Vuejs - 通过指令删除组件并且正在执行安装/创建事件时出现问题

use*_*487 2 javascript vue.js vue-directives

我希望我的指令作为 v-if 工作,因为在我的指令中我必须检查访问权限并销毁该元素(如果它没有访问权限)。

这是我的代码

Vue.directive('access',  {
    inserted: function(el, binding, vnode){

        //check access

        if(hasAccess){
           vnode.elm.parentElement.removeChild(vnode.elm);
        }
    },

});
Run Code Online (Sandbox Code Playgroud)

vue 文件

<my-component v-access='{param: 'param'}'>
Run Code Online (Sandbox Code Playgroud)

问题是我将此指令应用于组件,它删除该组件,但不删除创建/安装的挂钩调用的函数的执行。

在组件(my-component)中,mounted/created 钩子中有函数。这些函数执行完毕,我不想再执行这些函数了。有没有办法停止执行已安装/创建的事件?

Dec*_*oon 5

不可能复制v-if自定义指令中的行为。指令无法控制 vnode 的渲染方式,它们仅对其附加的 DOM 元素产生影响。(v-if很特别,它实际上不是指令,而是在编译模板时生成条件渲染代码。)

尽管如果可能的话,我会避免执行以下任何建议,但无论如何我都会提供它们,因为它接近您想要做的事情。

1.扩展Vue原型添加全局方法

您肯定需要使用v-if来进行条件渲染。因此,我们所要做的就是提出一个计算访问权限的全局辅助方法。

Vue.prototype.$access = function (param) {
  // Calculate access however you need to
  // ("this" is the component instance you are calling the function on)
  return ...
}
Run Code Online (Sandbox Code Playgroud)

现在在您的模板中您可以执行以下操作:

<my-component v-if="$access({ param: 'param' })">
Run Code Online (Sandbox Code Playgroud)

2.在根组件中定义全局方法

这与 #1 基本相同,只是您只在根实例上定义方法,而不是用垃圾污染 Vue 原型:

new Vue({
  el: '#app',
  render: h => h(App),
  methods: {
    access(param) {
      return ...
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

现在在您的模板中您可以执行以下操作:

<my-component v-if="$root.access({ param: 'param' })">
Run Code Online (Sandbox Code Playgroud)

现在该方法的定义位置就更清楚了。

3.使用全局mixin

这可能并不理想,但就其价值而言,您可以研究全局 mixin的可行性。

4.使用自定义组件

您可以创建一个自定义组件(理想情况下功能正常,但不一定如此),它可以计算模板中特定区域的访问权限:

Vue.component('access', {
  functional: true,
  props: ['param'],
  render(h, ctx) {
    // Calculate access using props as input
    const access = calculateAccess(ctx.props.param)

    // Pass the access to the default scoped slot
    return ctx.scopedSlots.default(access)
  }
})
Run Code Online (Sandbox Code Playgroud)

在您的模板中,您可以执行以下操作:

<access :param="param" v-slot="access">
  <!-- You can use `access` anywhere in this section -->
  <div>
    <my-component v-if="access"></my-component>
  </div>
</access>
Run Code Online (Sandbox Code Playgroud)

由于<access>是一个功能组件,它实际上不会渲染它自己的组件实例。将其视为一个函数而不是一个组件。

对于你的情况来说有点矫枉过正,但如果你遇到更复杂的场景,那么仍然很有趣。