Vue中可能会用到的自定义指令

自定义指令

Vue允许注册自定义指令,它的作用是在某些场景下对于DOM元素进行操作

Vue注册全局指令通过Vue.directive( id, [definition] )的方式来完成,然后在入口文件中使用Vue.use()来调用

指令定义函数提供了几个钩子函数:

  1. bind:只调用一次,第一次绑定到元素时调用
  2. inserted:被绑定元素在插入父节点的时候调用,父节点只要存在就可以调用,不必存在于document中
  3. update:被绑定的元素所在的模板更新的时候调用,不论绑定值是否改变
  4. componentUpdated:被绑定元素所在模板完成一次更新周期时调用
  5. 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
			}
			//动态创建textarea标签
			const textarea = document.createElement("textarea");
			//将此textarea设为readonly,防止ios下自动唤起键盘,同时将textarea移出可视区域
			textarea.readOnly = "readonly";
			textarea.style.position = "absolute";
			textarea.style.left = "-9999px";
			//将值复制给textarea的value属性
			textarea.value = el.$value;
			//插入到页面中
			document.body.appendChild(textarea);
			//选中值并复制
			textarea.select();
			const result = document.execCommand('Copy');
			if (result) {
				alert("复制成功");
			}
			//移除textarea
			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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值