自定义指令存在的意义
说说我自己的理解,自定义指令是用来操作DOM的。尽管Vue推崇数据驱动视图的理念,但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的DOM操作,并且是可复用的。
实战
因为项目中表格比较多,表格状态有三种状态----初始化状态,无数据状态,查询出错状态,每个状态对应一个背景图片,因为每一个表格都一样所以开始的时候我们就直接写了一个自定义指令
bgType.js
自定义指令demo
const createNode = (classes, text)=> {
let template = `
<div class="bg"></div>
<div><p>${text}</p></div>
`
let temWrapper = document.createElement('div')
temWrapper.innerHTML = template
temWrapper.className = classes
return temWrapper
}
const elemHandler = (el,binding)=> {
let className = ''
let text = ''
let status = binding.value
switch (status) {
case 'init':
className = 'init_bg'
text = '请查询数据'
break
case 'noData':
className = 'noData_bg'
text = '暂无数据'
break
case 'error':
className = 'error_bg'
text = '查询出错'
break
default:
className = ''
break
}
let curElem = el.querySelector('.init_bg')
if (curElem) {el.removeChild(curElem)}
curElem = el.querySelector('.noData_bg')
if (curElem) {el.removeChild(curElem)}
curElem = el.querySelector('.error_bg')
if (curElem) {el.removeChild(curElem)}
if (className!=='') {
el.appendChild(createNode(className, text))
}
}
// 自定义指令
const bgType = {
/*
*el是自定义挂载的节点,
*binding是自定义指令的挂载到节点上的信息包括当前指令的名称,当前指令的生命周期,当前指令挂载的值
*Vnode vue编译生成的虚拟dom节点
*oldVnode 上一个生成的虚拟节点仅在update和componentUpdated可用
*/
bind(el, binding) {
elemHandler(el,binding)
},
update(el, binding) {
elemHandler(el,binding)
},
}
export default bgType
使用自定义指令
<template>
<!--指令测试-->
<div >
<div @click="changeStatus">换状态</div>
<div style="width: 500px;height: 500px" v-bgType="status"></div>
</div>
</template>
<script>
import bgType from '../../directs/bgType.js'
export default {
name: "directs",
data() {
return {
status: 'init'
}
},
// 自定义指令注册
directives: {
bgType
},
methods: {
changeStatus(){
this.status = 'noData'
}
},
}
</script>
自定义指令的勾子函数
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。