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