vue 自定义指令大全
应用场景
- 代码复用和抽象的主要形式是组件
- 当需要对普通 DOM 元素进行底层操作,此时就会用到自定义指令
- 但是,对于大幅度的 DOM 变动,还是应该使用组件
钩子函数
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind
:只调用一次,指令与元素解绑时调用。
v-copy 复制内容
const copy = {
bind(el, { value, arg }, vnode) {
if (vnode.data.attrs) {
el.$copyContent = vnode.data.attrs.copyContent
console.log('init', el.$copyContent )
}
el.$value = value
el.handler = () => {
// 值为空
if (!el.$value) return
// 判断 value 是否为回调函数
let isCallback = false
if (typeof el.$value === 'function') {
isCallback = true
}
// 创建 textarea 标签
const textarea = document.createElement('textarea')
textarea.readOnly = 'readonly'
textarea.style.position = 'absolute'
textarea.style.left = '-9999px'
textarea.value = isCallback ? el.$copyContent : el.$value
document.body.appendChild(textarea)
// 选中并调用 api 复制
textarea.select()
const result = document.execCommand('Copy')
if (result) {
console.log('复制成功')
if (isCallback) {
el.$value()
}
}
// 移除标签
document.body.removeChild(textarea)
}
el.addEventListener(arg || 'dblclick', el.handler)
},
// 值更新
componentUpdated (el, { value }, vnode) {
if (vnode.data.attrs) {
el.$copyContent = vnode.data.attrs.copyContent
console.log('update', el.$copyContent )
}
el.$value = value
},
// 指令解绑
unbind (el, { arg }) {
el.removeEventListener(arg || 'dblclick', el.handler)
}
}
export default copy
- 使用方法
绑定指令 v-copy 默认绑定双击事件; 绑定回调函数时 copyContent 必须放置 “复制内容”; 字符串则是直接 “复制内容”
<template>
<div class="directives">
<h1>自定义指令</h1>
<hr />
<br>
<h2>copy</h2>
<p>
<span class="cur" v-copy="'默认双击复制'">默认双击复制</span>
<span class="cur" v-copy:click="'单击复制'">单击复制</span>
<span class="cur" v-copy="callback" copyContent="【成功回调】默认双击复制">【成功回调】默认双击复制</span>
<span class="cur" v-copy:click="callback" copyContent="【成功回调】单击复制">【成功回调】单击复制</span>
</p>
</div>
</template>
<script>
export default {
methods: {
callback() {
alert('复制成功')
}
}
}
</script>
<style scope>
.cur {
cursor: pointer;
margin: 0 10px;
}
</style>
更新中…