文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

前言

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自定义封装指令内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯