在vue3中使用自定义指令

目录构建

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

模块化规范

我们在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);
}

以上!

猜你喜欢

转载自blog.csdn.net/weixin_54858833/article/details/123097665