Vue.js 中的自定义指令
Posted
技术标签:
【中文标题】Vue.js 中的自定义指令【英文标题】:Custom-directive in Vue.js 【发布时间】:2019-01-05 19:02:27 【问题描述】:我有一个自定义指令 :myMethod="loadProfile(currentUser)" 在加载组件时加载 JSON。我使用来自Vuex
的mapGetters
,但令人惊讶的是,这种方法也非常有效。与其他方法(如在mounted
或created
挂钩中调用方法)相比,这是否也是正确的或性能方面的,我有两难选择(我也试过)?调用钩子或自定义指令哪个更好?
这是我的示例代码:
<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;
为什么要使用计算属性?每当它们的依赖关系更新时,计算和更新计算属性。当依赖关系保持不变时,计算的属性只会从缓存中加载。这样可以提高性能,让您不必担心何时自己更新数据。
至于使用指令。在大多数情况下,您不需要使用指令。您不会在此处发送对指令的函数引用,而是发送该方法的评估结果,因此执行<div :myMethod="actualUser"></div>
也可以。您可能希望确保您正在做的事情不能用实际组件来完成。组件可重用,比自定义指令中的代码更易于阅读。
【讨论】:
感谢您的回复和回答。现在我明白了。【参考方案2】:Vue.js 指令仅用于执行一些常规组件无法执行的低级 DOM 操作。所以简而言之,你不应该做你现在正在做的事情。
现在继续回答:
在您的代码中,您正在执行以下操作:<div :myMethod="loadProfile(currentUser)"></div>
。如果: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 中的自定义指令的主要内容,如果未能解决你的问题,请参考以下文章