Vue3中获取Dom踩坑以及使用浏览器原生webAPI操作dom(替换jquery,因为这种需求不常见,引入jq太重,而且有可能与其他框架冲突)

Chobits / 2023-08-25 / 原文

前言:

Vue的设计是数据驱动视图变化,所以直接操作Dom官方并不推荐,但有时候确实有这种需求,下面记录一次实现这种需求过程中碰到的问题

 

需求:

根据 excle 文件里的表格样式,生成一个类似的表,每个单元格进行配置

 

解决方案思路:

1.将excel解析为 html代码存在数据库

2.从数据库取出,v-html 回显

3.获取table dom,操作dom,模仿excel添加最上部的列序号 A B C D....,列号1,2,3,4....

以及添加相应的事件方法

遇到的问题:

1.用ref无法直接获取v-html里的table,要先获取v-html 所在的外层div,然后取子节点;

同时,因为是异步获取数据,取子节点方法需要在nextTick里,代码如下:

 1 initEditor = async () => {
 2     const { matterId } = this.route.params;
 3     if (matterId) {
 4       const entity: SalaryMatterEntity = await getEntity(matterId);
 5       if (entity) {
 6         this.data.template_html = entity.templateCode;
 7         // 操作 模板表格的 dom
 8         console.log('=====dom====', this.matterTableDiv);
 9         const tableDiv = this.matterTableDiv;
10         console.log('=====value====', tableDiv.value);
11         nextTick(() => {
12           const matterTable = tableDiv.value.firstChild;
13           console.log('=====matterTable====', matterTable);
14           this.addTitleRow(matterTable);
15           this.addNumCol(matterTable, this);
16         });
17       }
18     }
19   };

2.Vue3 获取dom的方法与Vue2 不同,这个很多文章都有些,下面只说vue3写法,声明一个与模板ref="xxx"一样的响应式refApi变量即可,代码如下:

1 <template>
2 <div ref="matterTableDiv" class="matter-table-div" v-html="data.template_html">
3 </div>
4 </template>
5 
6 <script lang="ts" setup name="SalaryMatterTemplateEditor">
7   const matterTableDiv= ref(null);
8 </script>

3.***最重要的,使用浏览器原生API操作DOM,可能比jQuery麻烦一点,但还是能用,下面有一个网站提供对应的方法替换代码:

You Might Not Need jQuery