vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue自定义封装指令

vue自定义封装指令以及实际使用

作者:cyc重名了

市面上大多数关于Vue.js自定义指令的文章都在讲语法,很少讲实际的应用场景和用例,下面这篇文章主要给大家介绍了关于vue自定义封装指令以及实际使用的相关资料,需要的朋友可以参考下

前言

vue默认内置了v-model、v-if、v-show、v-html、v-text等指令,但是这些往往不足以满足我们实际项目开发中的场景,比如权限控制按钮、路由菜单,复制文字等功能,就需要我们自己自定义一些满足我们项目需求的指令了,那怎么封装自定义指令,并使用呢?我们先从封装指令的基础说起。

封装指令基础

钩子函数

钩子函数参数

钩子函数参数包含了el、binding、vnode、oldVnode。

实际使用

复制指令(v-copy)

我们先看如何使用:

单击复制

<div v-copy>单击复制</div> // 默认复制div的文案
<div v-copy="copyStr">单击复制</div> // 复制指令里的内容(copyStr)

给el添加点击事件,判断binding的value值是否为空,若为空,默认获取绑定元素的文本内容

el.addEventListener("click", () => {
    let str = binding.value ? binding.value : el.innerText;

    handleClick(str);
});
el.style.cursor = "copy";

双击复制

<div v-copy:dblclick>双击复制</div> // 默认复制div的文案
<div v-copy:dblclick="copyStr">双击复制</div> // 复制指令里的内容(copyStr)

给el添加双击事件,判断binding的value值是否为空,若为空,默认获取绑定元素的文本内容

el.addEventListener("dblclick", () => {
    let str = binding.value ? binding.value : el.innerText;

    handleClick(str);
});
el.style.cursor = "copy";

点击icon复制

<div v-copy:icon>单击icon复制</div> // 默认复制div的文案
<div v-copy:icon="copyStr">单击icon复制</div> // 复制指令里的内容(copyStr)

判断el是否已经增加了icon,没有则增加i标签,放置icon,给icon增加点击事件,进行复制

if (el.hasIcon) return;

const iconElement = document.createElement("i");

iconElement.setAttribute("class", "el-icon-document-copy");
iconElement.setAttribute("style", "margin-left:5px");
el.appendChild(iconElement);
el.hasIcon = true;
iconElement.addEventListener("click", () => {
    let str = binding.value ? binding.value : el.innerText;

    handleClick(str);
});
iconElement.style.cursor = "copy";

handleClick 逻辑

判断是否有id为copyTarget的输入框,没有则创造一个id为copyTarget的输入框,然后进行选中,调用execCommand('copy')进行选中文字的复制。

function handleClick (text) {
    if (!document.getElementById("copyTarget")) {
        const copyTarget = document.createElement("input");

        copyTarget.setAttribute("id", "copyTarget");
        copyTarget.setAttribute("style", "position:fixed;top:0;left:0;opacity:0;z-index:-1000;");
        document.body.appendChild(copyTarget);
    }

    // 复制内容
    const input = document.getElementById("copyTarget");

    input.value = text;
    input.select(); // 选取文本域中的内容。
    // 调用execCommand()可以实现浏览器菜单的很多功能. 如保存文件,打开新文件,撤消、重做操作…
    document.execCommand("copy"); // 复制选中的文字到剪贴板;
    // Message.success("复制成功");
    Notification({
        title: "成功",
        message: `${text}已复制到剪切板`,
        type: "success"
    });
}

完整代码

import { Message, Notification } from "element-ui";

function handleClick (text) {
    if (!document.getElementById("copyTarget")) {
        const copyTarget = document.createElement("input");

        copyTarget.setAttribute("id", "copyTarget");
        copyTarget.setAttribute("style", "position:fixed;top:0;left:0;opacity:0;z-index:-1000;");
        document.body.appendChild(copyTarget);
    }

    // 复制内容
    const input = document.getElementById("copyTarget");

    input.value = text;
    input.select(); // 选取文本域中的内容。
    // 调用execCommand()可以实现浏览器菜单的很多功能. 如保存文件,打开新文件,撤消、重做操作…
    document.execCommand("copy"); // 复制选中的文字到剪贴板;
    // Message.success("复制成功");
    Notification({
        title: "成功",
        message: `${text}已复制到剪切板`,
        type: "success"
    });
}

const install = function (Vue) {
    Vue.directive("copy", {
        bind (el, binding) {
            if (binding.arg === "dblclick") { // 双击触发
                el.addEventListener("dblclick", () => {
                    let str = binding.value ? binding.value : el.innerText;

                    handleClick(str);
                });
                el.style.cursor = "copy";
            } else if (binding.arg === "icon") { // 点击icon触发
                if (el.hasIcon) return;

                const iconElement = document.createElement("i");

                iconElement.setAttribute("class", "el-icon-document-copy");
                iconElement.setAttribute("style", "margin-left:5px");
                el.appendChild(iconElement);
                el.hasIcon = true;
                iconElement.addEventListener("click", () => {
                    let str = binding.value ? binding.value : el.innerText;

                    handleClick(str);
                });
                iconElement.style.cursor = "copy";
            } else { // 单击触发
                el.addEventListener("click", () => {
                    let str = binding.value ? binding.value : el.innerText;

                    handleClick(str);
                });
                el.style.cursor = "copy";
            }
        }
    });
};

export default install;

权限操作指令(v-hasPermi)

import store from "@/store";

const allPermission = "*:*:*";
export function hasPermi(value){
    // return true;
    const permissions = store.getters && store.getters.permissions;
    if (value && value instanceof Array && value.length > 0) {
        const permissionFlag = value;
        const hasPermissions = permissions.some(permission => allPermission === permission || permissionFlag.includes(permission));
        if (!hasPermissions) {
            return false;
        }
        return true;
    }
    throw new Error("请设置操作权限标签值");
}


export default {
    inserted(el, binding) {
        const { value } = binding;
        if (!hasPermi(value)){
            el.parentNode && el.parentNode.removeChild(el);

        }
    }
};

总结

到此这篇关于vue自定义封装指令以及实际使用的文章就介绍到这了,更多相关vue自定义封装指令内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文