1、创建对应文件及其文件夹

2、创建 emphasize.ts 自定义指令文件

// 匹配常用字符集 列表
// 根据业务需求 配置字符集
const characterList: any = {
  "<": "&lt;",
  ">": "&gt;",
  "&": "&amp;",
  "¥": "&yen;",
};
// 处理函数
const nodeChild = (node: any, val: any) => {
  const children = Array.from(node.children);
  let nodeSplicing: any = "";
  //   判断是否为末级节点
  if (children.length !== 0) {
    // 子节点数据遍历
    children.forEach((item: any) => {
      // 递归 子节点
      nodeChild(item, val);
      // nodeSplicing 为当前节点的子级拼接后的字符串
      nodeSplicing = nodeSplicing + item.outerHTML;
    });
    // 进行数据替换 防止标签内部 有需要标记的重复数据 导致标红后 标签外露
    // innerHTML 返回标签开始和结束标签之间的HTML
    node.innerHTML = node.innerHTML
      .replaceAll(nodeSplicing, `*^(_)`)
      .toString();
    node.innerHTML = node.innerHTML.replaceAll(
      val,
      `<span style="color:red">${val}</span>`
    );
    node.innerHTML = node.innerHTML.replaceAll("*^(_)", nodeSplicing);
  } else {
    // 末级节点 不需要内部标签数据替换
    node.innerHTML = node.innerHTML.replaceAll(
      val,
      `<span style="color:red">${val}</span>`
    );
  }
};
export default {
  mounted(el: any, binding?: any) {
    // 进行字符集匹配
    const value: string = binding.value;
    const valueArr: Array<string> = value.split("");
    valueArr.forEach((item: string, index: number) => {
      valueArr[index] = characterList[item] || item;
    });
    // 进行数据匹配 如当前绑定节点 整体并无需要标记内容 不进行DOM 操作
    const idx: number = el.innerHTML.indexOf(valueArr.join(""));
    if (idx != -1) {
      nodeChild(el, valueArr.join(""));
    }
  },
  //   binding 数据改变 调用 初始不会调用
  //   不建议 因为原始DOM已经被标记
  //   可根据业务需要进行 原始数据传参 对原始数据进行操作 然后进行DOM替换即可
  //   beforeUpdate(el: any, binding?: any) {
  //     nodeChild(el, binding);
  //   },
};

3、 index.ts 引入

import emphasize from "./modules/emphasize";
// 统一入口
export default function directive(app: any) {
  app.directive("emphasize", emphasize);
}

 4、main.ts 中引入 指令入口文件

import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
import router from "./router";
import store from "./store";
// 引入指令入口文件
import directive from "@/directive/index";
// 挂载
directive(app);
app.use(store);
app.use(router);
app.mount("#app");

5、使用 

<template>
  <div v-html="nodeStr" v-emphasize="emphasizeStr" class="nodestr"></div>
</template>

<script lang="ts" setup>
import { ref, onMounted } from "vue";
import { RouteLocationRaw, useRouter } from "vue-router";
const router = useRouter(); //路由初始化
const nodeStr = ref<string>(
  '<div><div>9846531564路人甲,4564864<br><a herf="18866664444">18866664444,路人乙<br><a herf="18866664444">18866664444,路人丙<br></a></a></div></div>'
);
let emphasizeStr = ref<string>("18866664444");
</script>

 6、效果

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐