目录
1、为什么使用自定义指令?
2、自定义指令
3、自定义指令使用
1、为什么使用自定义指令?
什么时候我们需要去自定义一个指令呢?
事件修饰符,很大的程度上我们是为了让我们的代码更加显得是数据驱动的以及可测试的,而将DOM操作的相关逻辑单独地委托出来,约定成一些特定的修饰符,为了保证methods方法只有纯粹的数据逻辑(和DOM解耦,易于单元测试),不去处理DOM相关的操作。
当我们的methods中存在操作DOM的逻辑的时候,就该思考是否可以抽象成一个自定义指令。
自定义指令作用:操作DOM
2、自定义指令
Vue.directive( ' 自定义指令名 ' , { } )
参数一是指令的名字,注意定义的时候指令前不需要加 v- 前缀,但调用的时候必须加上这个前缀
参数二是一个对象,在这对象身上有一些指令相关的函数,这些函数可以在特定阶段执行相关的操作,叫钩子函数
bind 和 unbind函数:这俩个钩子函数是在当前这个钩子函数与声明的元素绑定和解绑时被调用的,都只会被调用一次。
Inserted 钩子函数会在绑定元素插入父节点时调用,需要注意的是这个时候并不能保证当前的父节点已经插入到页面中去了。
inserted一般都会在bind之后被调用,区别如下:
bind 中 el.parentNode 为 null
inserted 中可以通过中 el.parentNode 访问当前节点的父节点
update和componentUpdate,这一对钩子函数会在Vnode更新的之前和之后被调用,这俩个钩子函数的传入的参数也比其他钩子函数多一个oldVnode, 平时我们开发的时候就可以根据 oldVnode 和 vnode 来比较数值变化来减少不必要的 Dom 模板更新, 从而一定程度提高组件性能。
钩子函数参数 | 参数说明 | |
el | 指令所绑定的元素,可以直接用来操作DOM | |
binding对象 | name | 指令名,不包括‘v-’前缀 |
value | 传递给指令的值,如v-directive="1+1",value为2 | |
oldValue | 指令绑定的前一个值,仅在钩子函数update 及 componentUpdated 中可用 | |
expression | 字符串形式的指令表达式,如v-directive="1+1",表达式为“1+1” | |
arg | 传递给指令的参数,可选,如v-directive:foo中参数为foo | |
modifiers | 包含修饰符的对象,如 v-directive.a.b 意味着修饰符对象为 {a : true , b:true} | |
vnode | vue编译器提供的虚拟节点对象 | |
oldVnode | 上一个虚拟节点,仅在钩子函数update 及 componentUpdated 中可用 |
注意 : 这些参数中, 除了 el 以外 , 其他参数都看做是只读参数,不要修改它们。
3、自定义指令使用
我们可以通过 Vue.directive 来在全局注册名为 demo 的指令,可以直接在单文件组件的模板中去使用这个指令, 也可以在JSX中去使用这个指令。
示例1:局部使用自定义指令
<template>
<div>
<!-- <div v-color>{{ msg }}</div> -->
<div v-color="'#00ff00'">{{ msg }}</div>
</div>
</template>
<script>
export default {
name: "app",
directives: {
color: {
bind(el, binding) {
// el.style.color = "red";
console.log(binding.name); //color
console.log(binding.value); //#00ff00
}
}
},
data() {
return {
msg: "Welcome to Your Vue.js App"
};
}
};
</script>
示例2:平台按钮权限控制
(1)main.js中全局定义has指令
// 权限指令
Vue.directive('has', {
inserted: function(el, binding) {
// debugger
const permision = store.getters.permisions.indexOf(binding.value) > -1
if (!permision) {
el.parentNode && el.parentNode.removeChild(el)
// el.style.display = 'none'
}
}
})
(2)store中向后台获取权限
import {getButtonsPermision} from '../../api/user';
const mutations = {
SET_PERMISIONS: (state, permisions) => {
state.permisions = permisions;
},
}
const actions = {
async getPermisions({commit}, appId) {
// debugger
const result = await getButtonsPermision({ appId }) //传递appId调用接口获取权限数据
const permisions = result.data.map(item => {
return item.code
})
commit('SET_PERMISIONS', permisions)
// sessionStorage.setItem('permisions', JSON.stringify(permisions))
return result
}
}
export default {
namespaced: true,
state,
mutations,
actions,
};
(3)页面使用
<el-button v-has="'myservice_edit'" type="text" @click="handleOperate(row, 'detail')">
编辑
</el-button>