自定义指令
Vue允许注册自定义指令,它的作用是在某些场景下对于DOM元素进行操作
Vue注册全局指令通过Vue.directive( id, [definition] ) 的方式来完成,然后在入口文件中使用Vue.use() 来调用
指令定义函数提供了几个钩子函数:
- bind:只调用一次,第一次绑定到元素时调用
- inserted:被绑定元素在插入父节点的时候调用,父节点只要存在就可以调用,不必存在于document中
- update:被绑定的元素所在的模板更新的时候调用,不论绑定值是否改变
componentUpdated :被绑定元素所在模板完成一次更新周期时调用- unbind:只调用一次,指令与元素解绑时调用
如果自定义指令比较多,可以批量注册指令
新建directive/index.js 文件,代码如下:
import longpress from "./longpress.js";
import copy from "./copy.js";
const directives = {
longpress,
copy,
}
export default {
install(Vue) {
Object.keys(directives).forEach((key) => {
Vue.directive(key, directives[key]);
})
},
}
然后在入口文件main.js 中调用
import directives from '@/directive/index.js'
Vue.use(directives);
1.长按指令(v-longpress )
长按几秒触发执行相应操作
longpress.js 文件代码:
const longpress = {
bind: function (el, binding, vNode) {
if (typeof binding.value !== "function") {
throw "callback must be a function"
}
let pressTime = null;
let start = (e) => {
if (e.type === "click" && e.button !== 0) {
return
}
if (pressTime === null) {
pressTime = setTimeout(() => {
handler();
}, 1000);
}
}
let cancle = (e) => {
if (pressTime !== null) {
clearTimeout(pressTime);
pressTime = null;
}
}
const handler = (e) => {
binding.value(e);
}
el.addEventListener("mousedown", start);
el.addEventListener("touchstart", start);
el.addEventListener("click", cancle);
el.addEventListener("mouseout", cancle);
el.addEventListener("touchend", cancle);
el.addEventListener("touchcancel", cancle);
},
componentUpdated(el, { value }) {
el.$value = value
},
unbind(el) {
el.removeEventListener("click", el.handler)
},
}
export default longpress;
使用:给需要的操作的元素加上v-longpress 以及回调即可
<template>
<div>
<div style="width: 100px; height: 100px; background-color: red"
v-longpress="longpress">
长按触发指令
</div>
</div>
</template>
<script>
export default {
name: "longpress",
methods: {
longpress() {
alert("长按指令生效");
},
},
};
</script>
2.一键复制文本内容(v-copy)
copy.js 代码:
const copy = {
bind(el, { value }) {
el.$value = value;
el.handle = () => {
if (!el.$value) {
alert("暂无复制内容");
return
}
const textarea = document.createElement("textarea");
textarea.readOnly = "readonly";
textarea.style.position = "absolute";
textarea.style.left = "-9999px";
textarea.value = el.$value;
document.body.appendChild(textarea);
textarea.select();
const result = document.execCommand('Copy');
if (result) {
alert("复制成功");
}
document.body.removeChild(textarea);
}
el.addEventListener("click", el.handle);
},
componentUpdated(el, { value }) {
el.$value = value;
},
unbind(el) {
el.removeEventListener("click", el.handle);
},
}
export default copy
使用:给元素加上v-copy指令
<template>
<div>
<input class="text" type="text" v-model="copytext" />
<button style="margin-left: 20px" v-copy="copytext">复制</button>
<span>{{ copytext }}</span>
</div>
</template>
<script>
export default {
name: "copy",
data() {
return {
copytext: null,
};
},
};
</script>
防抖指令
debounce.js 代码:
const debounce = {
inserted(el, binding) {
let timer;
el.addEventListener("click", () => {
if (timer) {
clearTimeout(timer);
}
let callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, 1000);
if (callNow) {
binding.value();
}
});
}
}
export default debounce
使用:给需要操作的元素加上v-debounce指令
<template>
<div>
<button class="btn" v-debounce="clickHandle">点击事件防抖</button>
</div>
</template>
<script>
export default {
name: "debounce",
methods: {
clickHandle() {
console.log("触发了点击事件");
},
},
};
</script>
最后附上gitee地址:https://gitee.com/ywx_jd/custom-directive.
|