本章主要介绍 Vue 中direction 的一些实际应用场景
指令与自定义指令是什么
-
Vue 中指令是 是一种特殊的用在 模板语法中的 属性 (attribute)
-
Vue 中有官方自己定义的 指令(
v-ifv-on等),后面跟随js表达式 -
Vue 也提供给用户 自己定义自己的 指令,那就可大有作为了
自定义指令内部api解析
el, binding, vnode 这几个元素拿到,就可以搞很多黑科技,骚操作
可以自行打印里面都包含哪些有用的信息
-
el 中信息
el可以获取当前dom节点,并且进行编译,也可以操作事件 el.style.border="1px solid red"; //操作style所有样式 console.log(el.value); //获取v-model的值 console.log(el.dataset.name) //data-name绑定的值,需要el.dataset来获取 -
vnode中信息
console.log(vnode.context.$route); //获取当前路由信息,根据路由信息,可以控制改DOM是否显示 route.meta 角色信息 当然,想的更远些 vnode.context 还可以拿到 很多 Vue的信息 -
生命周期 一般用update多
// 注册
Vue.directive('my-directive', {
// 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
bind: function (el, binding, vnode) {
// 重点:拿到下面几个元素,基本就
// el : 当前挂载指令的DOM元素
// binding: 一个对象,包含该指令的很多信息
// vnode:当前挂载指令的 虚拟DOM结构
},
// 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
inserted: function () {},
// 一般都在此处 做很多逻辑处理,因为会 调用很多次
// 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改 变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数 见下)。
update: function () {},
// 指令所在组件的 VNode 及其子 VNode 全部更新后调用
componentUpdated: function () {},
//只调用一次,指令与元素解绑时调用
unbind: function () {}
})
// 注册 (指令函数)
Vue.directive('my-directive', function () {
// 这里将会被 `bind` 和 `update` 调用
})
实战中的场景
-
v-loading 全局加载
Vue.directive('loading', { update(el, binding, vnode) { if (binding.value) { const div = document.createElement('div') div.innerText = '加载中...' div.setAttribute('id', 'loading') div.style.position = 'absolute' div.style.left = 0 div.style.top = 0 div.style.width = '100%' div.style.height = '100%' div.style.display = 'flex' div.style.justifyContent = 'center' div.style.alignItems = 'center' div.style.color = 'white' div.style.background = 'rgba(0, 0, 0, .7)' document.body.append(div) } else { document.body.removeChild(document.getElementById('loading')) } } }) -
根据路由角色控制DOM(一般是按钮多)是否显示
bind: function (el, binding, vnode) { // 获取按钮权限 路由中 meta 中的角色 let btnPermissions = vnode.context.$route.meta.btnPermissions.split(","); if (btnPermissions.indexOf('admin')<0) { // 不是admin 就不显示 // 当然此处也可以 将 el 样式隐藏也行 el.parentNode.removeChild(el); } } -
根据后台下发 权限 字段,控制当前DOM是否展示
// 很多时候,服务器下发了 showBtn 字段就代表 显示某个 按钮,前端一般把控制权限的数据都放在内存中 // 这样写 在 bind update 都会执行 Vue.directive('check-permission', function (el, binding) { var success = checkPermission(binding.value); // 拿到绑定的值 if(!success){ el.style.display = 'none'; } }) function checkPermission(permissionKey) { var values = localStorage.getItem("userPermissions"); if (!values) { console.log('can not find permissions config from localstorage, function access will be denied.'); return false; } var ret = values.split(',').find(item => item === permissionKey) != null; console.log('===========check permission, key:' + permissionKey + ", result:" + ret + "=========="); return ret; } // 使用 v-check-permission="'showBtn'"