mounted阶段获取不到dom的原因及解决方法原创
# 问题描述
需要在dom渲染后,获取dom来进行页面自动滚动到需要的位置。 在mounted阶段用document.querySelector()以及this.$refs获取元素均获取不到。用两种方式获取元素,打印出来的结果都是undefined。 有解答说用this.nextTick(function(){…}),试了一下结果还是undefined
# 分析原因
1、Vue 推荐使用 template 来创建 HTML。但是模板毕竟是模板,不是真实的dom节点。vue会先利用对象中的render 函数**,**生成虚拟节点并挂载,挂载的真实DOM是进行异步渲染的,并且在修改完状态后也是异步的方式进行渲染。代码中将document.querySelector操作定义为同步任务,此时事件队列应该是:
- 同步队列:获取dom元素,
- 异步队列:从虚拟节点转真实节点并进行渲染
根据先同步后异步的执行流程,是获取不到dom元素的;
2、在mounted阶段,若需要获取的元素或组件有v-if,v-for属性。v-if的初始化结果为false。v-for遍历 (opens new window)的数组初始化阶段无值。(即mounted阶段后,根据获得的后台数据来动态操作dom)这两种情况都会导致mounted阶段获取元素的语句获取不到dom。
# 解决方法
1、把获取元素的语句放在异步获取到数据,赋值给data中的key之后进行。同时需要给获取元素的语句加上setTimeout。因为setTimeout是宏任务,会在vue的render函数执行之后再执行。
mounted() {
setTimeout(() => {
if (this.$route.path !== "/") {
let rightbar = document.querySelector(".right-menu-wrapper");
let arrow = document.querySelector(".page-nav-centre-next");
if (rightbar) {
arrow.style.right = "16rem";
} else {
arrow.style.right = "2rem";
}
}
}, 200);
},
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2、把获取元素的语句放到updated周期中执行。这种情况下每次视图更新之后都会执行一次获取元素的语句,如果不需要每次视图更新之后都执行,可以在mounted周期中,使用可以在mounted周期中,使用this.$once让获取元素的语句只在updated阶段执行一次。
mounted() {
this.$once(“hook: updated”, function() {…})
}
2
3
- 01
- element-plus多文件手动上传 原创11-03
- 02
- TrueLicense 创建及安装证书 原创10-25
- 03
- 手动修改迅捷配置 原创09-03
- 04
- 安装 acme.sh 原创08-29
- 05
- zabbix部署 原创08-20