vue2自定义指令和指令的生命周期
指令的周期
5个 (bind、inserted、update、componentUpdated、unbind)。
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
注册自定义指令
注册全局指令Vue.directive()
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})复制代码
注册局部指令directives属性
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
},
// ...
}
}复制代码
案列一
注册一个局部的自定义指令v-append-text:不替换原来的内容,直接插入其后。
<template>
<div>
<button @click="show = !show">{{show ? "销毁" : "插入"}}</button>
<button v-if="show" v-append-text="`hello ${number}`" @click="number++">按钮</button>
</div>
</template>
<script>
export default {
directives: {
// 这里定义一个名为appendText的指令,使用时要像这样去用:v-append-text
appendText: {
/**
* 指令的生命周期 (bind、inserted、update、componentUpdated和unbind)
**/
bind(){
console.log("bind");
},
inserted(el, binding){
el.appendChild(document.createTextNode(binding.value));
console.log("inserted", el, binding);
},
update() {
console.log("update");
},
componentUpdated(el, binding){
el.removeChild(el.childNodes[el.childNodes.length - 1]);
el.appendChild(document.createTextNode(binding.value));
console.log("componentUpdated");
},
unbind(){
console.log("unbind");
}
}
},
data() {
return {
number: 1,
show: true
};
}
}
</script>复制代码
在vue2项目中使用指令
首先我们可以再src目录下,创建一个directives的文件夹;
然后在directives文件夹里新建一个globalDirectives.js的文件;
源码
// globalDirectives.js
const globalDirectives = {
/*
* 文字超出省略
* width:宽度,非必传,默认100%
* line:超出多少行显示省略号,非必传,默认1行
* 示例:v-ellipisis="{width:100,line:2}"
*/
ellipsis: (el, binding) => {
let { width, line } = binding.value
el.style.width = width ? width + 'px' : '100%'
el.style.display = '-webkit-box'
el.style.overflow = 'hidden'
el.style.textOverflow = 'ellipsis'
el.style['-webkit-line-clamp'] = line || 1
el.style['-webkit-box-orient'] = 'vertical'
},
/*
* 元素吸顶
* stickyNum:距离顶部多少px吸顶,非必传,默认0
* 示例:v-sticky="50"
*/
sticky: {
bind: (el, { value }) => {
const stickyNum = value || 0
window.addEventListener(
'scroll',
globalDirectives.sticky.handleScroll(el, stickyNum)
)
},
unbind: () => {
window.removeEventListener(
'scroll',
globalDirectives.sticky.handleScroll()
)
},
handleScroll: (el, stickyNum) => {
return () => {
const scrollTop =
window.scrollY ||
document.documentElement.scrollTop ||
document.body.scrollTop
if (scrollTop >= el.offSetTop - stickyNum) {
el.style.position = 'sticky'
el.style.top = stickyNum + 'px'
el.style.zIndex = 10
} else {
el.style.position = 'stick'
}
}
}
},
/*
* 点击事件防抖
* 参数:事件名称
* 示例:v-debounce = "eventName"
*/
debounce: {
inserted: (el, { value }) => {
el.addEventListener(
'click',
globalDirectives.debounce.debounceEvent(value)
)
},
unbind: (el, { value }) => {
el.removeEventListener(
'click',
globalDirectives.debounce.debounceEvent(value)
)
},
debounceEvent: (value) => {
let timeout
return () => {
if (timeout) clearTimeout
timeout = setTimeout(() => {
value()
}, 500)
}
}
}
}
export default globalDirectives复制代码
- 在directives文件夹里新建一个index.js的文件,完成批量定义
- 注册全局指令
// index.js
import globalDirectives from './globalDirectives'
const directives = {
install: function (app) {
Object.keys(globalDirectives).forEach((key) => {
app.directives(key, globalDirectives[key])
})
}
}
export default directives复制代码
- 在main.js引入自定义指令
// main.js
import directives from '@/directives'
Vue.use(directives)复制代码
本文为作者原创文章,转载无需和我联系,但请注明转载链接。 【前端黑猫】