Vue.js 中的自定义指令

Posted

技术标签:

【中文标题】Vue.js 中的自定义指令【英文标题】:Custom-directive in Vue.js 【发布时间】:2019-01-05 19:02:27 【问题描述】:

我有一个自定义指令 :myMethod="loadProfile(currentUser)" 在加载组件时加载 JSON。我使用来自VuexmapGetters,但令人惊讶的是,这种方法也非常有效。与其他方法(如在mountedcreated 挂钩中调用方法)相比,这是否也是正确的或性能方面的,我有两难选择(我也试过)?调用钩子或自定义指令哪个更好?

这是我的示例代码:

  <template v-if="currentUser.username === 'admin'">
       ... //
  <template v-else>
      <div :myMethod="loadProfile(currentUser)"></div>
  </template>

Vuex Getter

  computed: 
     ...mapGetters([
         'currentUser',
     ])
  

方法

  loadProfile(payload)
        this.user.last_name = payload.last_name,
        this.user.first_name =  payload.first_name,
        this.user.image = ( payload.image === 'no_avatar.png' ? '/image/no_avatar.png' : '/storage/images/'+ payload.image)
    

【问题讨论】:

【参考方案1】:

除非确实需要,否则不要使用方法。在这种情况下,似乎没有理由在没有 currentUser 的情况下调用 loadProfile,所以让我们将其移至计算属性:

computed: 
  ...mapGetters([
    'currentUser'
  ]),
  actualUser () 
    // Make a shallow copy
    const user =  ...this.user ;

    if (this.currentUser) 
      user.lastName = this.currentUser.lastName;
      user.firstName = this.currentUser.firstName;
      user.image = (this.currentUser.image === 'no_avatar.png' ? '/image/no_avatar.png' : `/storage/images/$this.currentUser.image`);
    

    return user;
  

为什么要使用计算属性?每当它们的依赖关系更新时,计算和更新计算属性。当依赖关系保持不变时,计算的属性只会从缓存中加载。这样可以提高性能,让您不必担心何时自己更新数据。


至于使用指令。在大多数情况下,您不需要使用指令。您不会在此处发送对指令的函数引用,而是发送该方法的评估结果,因此执行&lt;div :myMethod="actualUser"&gt;&lt;/div&gt; 也可以。您可能希望确保您正在做的事情不能用实际组件来完成。组件可重用,比自定义指令中的代码更易于阅读。

【讨论】:

感谢您的回复和回答。现在我明白了。【参考方案2】:

Vue.js 指令仅用于执行一些常规组件无法执行的低级 DOM 操作。所以简而言之,你不应该做你现在正在做的事情。

现在继续回答:

在您的代码中,您正在执行以下操作:&lt;div :myMethod="loadProfile(currentUser)"&gt;&lt;/div&gt;。如果:myMethod 是一个指令,那么它应该是v-myMethod="" 而不是:myMethod=""。后一种语法,即冒号语法是指props,而不是指令。因此,这意味着您的代码并没有真正执行指令。只是将myMethod 视为一些道具。

其次,执行:myMethod="loadProfile(currentUser)" 并不意味着您在实际指令代码中执行任何操作。它仍在组件模板中被调用。

第三,如果我们查看您的loadProfile() 方法实现,那么它不是返回值的函数。它只是一个使用this 修改组件实例的函数。如果您只需要这样做,那么您不需要指令或道具。

第四,:myMethod="loadProfile(currentUser)" 会起作用,但它看起来很尴尬,绝对不可读。相反,您应该依赖观察者或计算属性。这是 Vue.js 中惯用的做事方式。示例观察者实现如下所示:

watch: 
    currentUser(newVal) 
        this.user.last_name = newVal.last_name,
        this.user.first_name =  newVal.first_name,
        this.user.image = ( newVal.image === 'no_avatar.png' ? '/image/no_avatar.png' : '/storage/images/'+ newVal.image)
    

就性能而言,您不必担心。如果有的话,性能损失可以忽略不计。

【讨论】:

谢谢兄弟,感谢您的澄清。

以上是关于Vue.js 中的自定义指令的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Vue.js 2 中的自定义指令中获取文字表达式?

如何在 Vue.js 2 的自定义指令中进行双向绑定?

最简单的方式理解Vue的自定义指令

在 Vue.js 中反应性地重新填充指令数组

Vue.js 自定义指令

Vue.js---自定义指令