值得注意的是:尽管需要对纯 DOM 元素进行底层操作,但还是要尽量减少直接对DOM的操作,尽量用数据去驱动。
局部自定义指令
// input框自动获取焦点,自定义指令,与methods同级, input添加指令v-focus
directives: {
'focus': { // 指令的定义
inserted(el) {//被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
if (el.tagName.toLocaleLowerCase() === 'input') {
el.focus()
} else {
if (el.getElementsByTagName('input')) {
el.getElementsByTagName('input')[0].focus()
}
}
}
}
}
全局自定义指令
<div id="app">
<div v-red="{a:1}">1111</div>
<input type="text" v-focus />
</div>
1、声明directive.js文件
//简写形式
import Vue from 'vue'
Vue.directive('red', function (el, binding, vnode, oldVnode) {
console.log(el);
console.log(binding.value);
console.log(vnode);
el.style.backgroundColor = binding.name
})
然后在main.js中import导入即可
2、在main.js中直接写
钩子函数形式
Vue.directive('focus', {
//只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
blind: function(el, binding, vnode){},
// 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
inserted: function (el, binding, vnode) {
// 聚焦元素
el.focus()
},
//被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
update: function(el, binding, vnode){},
//被绑定元素所在模板完成一次更新周期时调用。
componentUpdated: function(el, binding, vnode){},
})
//简写形式
Vue.directive('red', function (el, binding, vnode) {
console.log(el);//<div style="background-color: red;">1111</div>
console.log(binding.value);//{a:1}
console.log(vnode);
el.style.backgroundColor = binding.name
})
项目中常用自定义指令(补充中。。。)
根据权限控制是否显示
Vue.directive('permission', {
//由于el.parentNode获取不到,所以要使用inserted
inserted: function (el, binding) {
const { value } = binding
const roles = store.getters && store.getters.roles
if (value && value instanceof Array) {
if (value.length > 0) {
const permissionRoles = value
const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
})
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
}
} else {
throw new Error(`need roles! Like v-permission="['admin','editor']"`)
}
}
})
拖拽功能
Vue.directive('drag', {
inserted: function (target) {
console.log(target);
target.onmousedown = function (ev) {
target.style.position="absolute"
var disX = ev.clientX - target.offsetLeft;
var disY = ev.clientY - target.offsetTop;
target.onmousemove = function (eve) {
target.style.left = eve.clientX - disX + 'px';
target.style.top = eve.clientY - disY + 'px';
}
target.onmouseup = function () {
target.onmousemove = null;
target.onmouseup = null;
}
return false;
}
}
})