在vue3中使用自定义指令

3 篇文章 2 订阅

目录构建

直接看图
在这里插入图片描述

模块化规范

我们在directives文件夹下书写指令,例如 copy.ts
并暴露注册这个指令的方法

// copy.ts
const copyDirective = {
		mounted(){},
		updated(){},
		...
}

// 暴露注册指令的方法
export function setCopyDrective(app) {
  app.directive("copy", copyDirective);
}

在入口文件index.ts中:
引入每个指令的注册方法,并暴露一个注册所有指令的方法

// index.ts
import type { App } from "vue";
import { setCopyDrective } from "./copy";

export function setDirectives(app: App) {
  // 加载需要的指令
  setCopyDrective(app);
}

我们要在项目初始化的时候就自动注册所有自定义指令,所以在main.js中引入注册所有指令的方法并使用:

// main.js
import { createApp } from "vue";
import App from "./App.vue";
import { setDirectives } from "./directives";

const app = createApp(App);

// 注册所有自定义指令
setDirectives(app);

app.mount("#app");

v-copy的实现 – 复制到剪贴板

例子来自:

作者:橙某人
链接:https://juejin.cn/post/6968996649515515917
来源:稀土掘金

  • 首先,使用场景可能是我们点击某一个按钮,就复制了某个内容(目标内容)到剪贴板中了,通过 ctrl+v 能粘贴出来。
  • 把内容塞进剪贴板,我们会用到上面提到的document.execCommand(‘Copy’)API来实现,但是这里要注意,该API的作用是将当前 选中 的内容拷贝进剪贴板,所以我们必须让我们的目标内容被选中,才能调用该API来完成功能。
  • 让内容被选中我们能通过 HTML事件 中的 onselect() 方法来实现,而 标签、 标签都能支持该事件。
  • 所以我们需要动态创建一个 标签,当然该标签只是个辅助工具,所以要把它移出可视区域外。
  • 再将我们的目标内容赋值给它的value属性,将它插入到页面DOM结构中。
  • 调用 标签的 select() 选中值,再通过 document.execCommand(‘Copy’) API把内容复制进剪贴板。
  • 最后移除 标签就可以。

笔者实现的是复制input框中的文本,和原文略有不同:

<template>
  <h3>定义指令操作DOM元素</h3>
  <div class="box">
    <input type="text" v-model="msg" />
    {{ msg }}
    <button v-copy="msg">复制内容</button>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
  name: "",
  components: {},
  setup(props) {
    const msg = ref("");
    return {
      msg,
    };
  },
});
</script>

<style lang="less" scoped></style>

copy.ts

// import type { App, Directive, DirectiveBinding } from "vue";

const copyDirective = {
  mounted(el, binding) {
    el.target = binding.value;
    el.addEventListener("click", () => {
      // 创建 textarea 元素
      const textarea = document.createElement("textarea");
      // 移出视野
      textarea.style.position = "fixed";
      textarea.style.top = "-99999px";
      // 插入 DOM
      document.body.appendChild(textarea);
      // 定义值
      textarea.value = el.target;
      // 自动选中文本  用于复制的 API 只能复制选中的值
      textarea.select();
      // 浏览器复制 API 显示废弃的原因是没有纳入标准 但仍被各大主流浏览器支持
      const res = document.execCommand("Copy");

      res && console.log(`success: ${el.target}`);
      // 移除 textarea
      document.body.removeChild(textarea);
    });
  },
  updated(el, binding) {
    // 实时更新内容
    el.target = binding.value;
  },
};

export function setCopyDrective(app) {
  app.directive("copy", copyDirective);
}

以上!

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值