-
为什么用?
vue本身已经有很多内置指令,如v-model、v-html、v-if、v-else、v-for等,这些指令使用起来非常方便,但是有些时候内置指令不能完全要求,需要自定指令,通常用于局部修改DOM,例如:页面加载时,某个输入框获得焦点(autofocus工作的情况下)。
// 注册一个全局自定义指令 `v-focus` Vue.directive('focus', { // 当被绑定的元素插入到 DOM 中时…… inserted: function (el) { // 聚焦元素 el.focus() } }) //局部注册,组件中添加以下代码 directives: { focus: { // 指令的定义 inserted: function (el) { el.focus() } } } //使用 <input v-focus>
-
怎么用?
-
全局定义
Vue.directive('directiveName', { //仅调用一次,指令第一次绑定到元素时调用,在这里添加一次性的初始化设置 bind:function(el,binding,vnode,oldVnode){ //el 指令所绑定的元素,可以用来操作DOM,例如el.focus() //el.focus() }, //被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中) inserted:function(el,binding,vnode,oldVnode){ //binding 一个对象包含以下属性 //name 指令名 //value 指令绑定的值 //oldValue 指令绑定的前一个值 //expression 字符串形式的指令表达式 //arg 传给指令的参数 //modifiers 一个包含修饰符的对象 }, //所有组件的VNode更新时调用,但是可能发生在其子VNode更新之前,指令的值可能发生了改变,也可能没有,可通过比较更新前后值(value、oldValue )忽略不必要的模板更新 update:function(el,binding,vnode,oldVnode){ //vnode Vue编译生成的虚拟节点 //oldVnode 上一个虚拟节点 }, //指令所在组件的VNode及其子VNode全部更新后调用 componentUpdated:function(el,binding,vnode,oldVnode){ }, //只调用一次,指令与元素解绑时调用 unbind:function(el,binding,vnode,oldVnode){} })
tips:除了el之外,其他参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset来进行。
-
局部定义
directives: { directiveName: { bind: function (el,binding,vnode,oldVnode) {}, inserted: function (el,binding,vnode,oldVnode) {}, update: function (el,binding,vnode,oldVnode) {}, componentUpdated: function (el,binding,vnode,oldVnode) {}, unbind: function (el,binding,vnode,oldVnode) {} } }
-
动态指令参数
//指定动态指令参数 <p v-test:[argument]="value"></p> //获取动态指令参数 Vue.directive('test', { bind: function (el, binding, vnode) { console.log(binding.arg); } })
-
对象字面量形式传多个值到指令
//传入多个值到指令 <div v-test="{ color: 'white', text: 'hello!' }"></div> //获取传入的多个值 Vue.directive('test', function (el, binding) { console.log(binding.value.color) // => "white" console.log(binding.value.text) // => "hello!" })
-
示例:
自定义全局权限指令
//定义
Vue.directive('permission',() => {
insert: (el,binding) => {
//添加禁用控制
const DISABLED = (binding.arg === 'disabled')
const status = binding.modifiers
if (DISABLED) {
if (binding.value) {
//可见状态
if (status.visible) return el.remove(el)
//可操作状态
if (status.editable) el.style.pointerEvents = 'none'
}
}
let result = -1
//遍历权限列表permissioinList
result = permissioinList.findIndex(item => item === binding.value)
if (result == -1) {
el.remove()
}
}
})
//使用
<h1 v-permissioin="xxx">测试<h1>