vue控制代码执行顺序之$nextTick()(三)
当动态渲染页面时,如何判断页面的DOM节点已经渲染完成?vue 有一个重要的概念:异步更新队列。Vue在观察到数据时并不是直接更新DOM,而是开启一个队列,并缓冲在同一个事件循环中发生的所有数据变化。在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。如下:通过websocket方式接受了后端的数据,并在页面渲染了几个图标。如果要获取第一个图标,并将其颜色变蓝,如果不使用nextTick..
当动态渲染页面时,如何判断页面的DOM节点已经渲染完成?
vue 有一个重要的概念:异步更新队列。Vue在观察到数据时并不是直接更新DOM,而是开启一个队列,并缓冲在同一个事件循环中发生的所有数据变化。在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。
官网教程地址:https://cn.vuejs.org/v2/guide/reactivity.html
如下:通过websocket方式接受了后端的数据,并在页面渲染了几个图标。如果要获取第一个图标,并将其颜色变蓝,如果不使用
n
e
x
t
T
i
c
k
(
)
方
法
,
会
报
错
:
c
a
n
n
o
t
r
e
a
d
p
r
o
p
e
r
t
y
s
t
y
l
e
o
f
n
u
l
l
。
因
为
此
时
节
点
还
没
有
渲
染
完
成
,
通
过
I
D
去
获
取
D
O
M
节
点
获
取
到
的
是
N
u
l
l
。
当
使
用
了
nextTick()方法,会报错:cannot read property style of null 。因为此时节点还没有渲染完成,通过ID去获取DOM节点获取到的是Null。当使用了
nextTick()方法,会报错:cannotreadpropertystyleofnull。因为此时节点还没有渲染完成,通过ID去获取DOM节点获取到的是Null。当使用了nextTick()方法后,会等页面的DOM节点渲染完成后才执行其中的代码。使用$nextTick就是确保我们操作的是更新后的DOM。
<template>
<div class="home">
<div v-if="ifShow" class="openning">开启消灭小怪兽之旅吧</div>
<div v-else>
<div class="center title">
<p v-text="title" @click="flowWebsocket()"></p>
<!--<label v-text="title"></label>-->
</div>
<div class="center flow">
<!--<div class="icon iconfont icon-gaojing"></div>-->
<div v-for="item in imgs" :id="item.id">
<!--<img :src="item.imgSrc"/>-->
<span :class="item.imgSrc">
</span>
<h3>{{item.subTitle}}</h3>
</div>
</div>
<div class="center content" ref="done">
<iframe :src="contentSrc" frameborder="0" v-if="isUrl"></iframe>
<div v-else>
<span class="icon iconfont icon-wanchenggouxuan multiColor"></span>
</div>
</div>
</div>
</div>
</template>
<script>
import SockJS from "sockjs-client";
import Stomp from "stompjs";
import con1 from "../assets/logo.png";
import con2 from "../assets/check-circle.png"
export default {
name: "home",
data() {
return {
title: '',
//items罗列所有的图标和相应的标题
items: {
imgSrc: "icon iconfont icon-web-icon-",
subTitle: '默认'
},
imgs: [],
contentSrc: '',
isUrl: true,
stompClient: null,
url: 'http://10.88.44.46:8080/imc',
ifShow: true
}
},
methods: {
init() {
var socket = new SockJS(this.GLOBAL.httpUrl + "/ws");
this.stompClient = Stomp.over(socket);
},
initWebsocket() {
var monster = null;
var steps = [];
var id = '';
var firstId = '';
var imgSrc = '';
var subTitle = '';
var url = '';
var socket = new SockJS("http://10.88.44.142:8080/ws");
var stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
stompClient.subscribe('/topic/global', function(message) {
// this.listData = JSON.parse(message.body);
// console.log('date', this.getCurrentDate(2));
//message为一个数组,传递流程各环节的名称
// console.log('message1', message);
// console.log('message', message.body);
this.ifShow = false;
monster = JSON.parse(message.body);
// console.log('steps', monster.stepIds);
steps = monster.stepIds;
// this.title = monster.name;
this.title = "数据库表空间自动化扩充流程";
this.imgs = [];
//渲染整体流程
steps.forEach(step => {
if(step.showType == 0) {
id = step.id;
imgSrc = (step.icon == null) ? this.items.imgSrc : step.icon;
subTitle = (step.name == null) ? this.items.subTitle : step.name;
this.imgs.push({
'id': id,
'imgSrc': imgSrc,
'subTitle': subTitle
});
//取得第一个需要展示的url展示在页面下方
if(url == '') {
firstId = step.id;
url = (step.url == null) ? this.url : step.url;
// url = "http://10.88.44.67:8080/imc/loginCmd.jsf?name=admin&simplePwd=admin&navigation=/fault/browser/faultInfo.jsf?beanName=faultQueryBean&faultId=0";
console.log("url-" + url);
this.contentSrc = url;
}
}
});
//this.nextTick() 中的代码会等待页面中的DOM节点都渲染完成后才会触发
this.$nextTick(() => {
//渲染下方展示图片
console.log('需要渲染的divID为', firstId);
console.log('element-', document.getElementById(firstId));
document.getElementById(firstId).style.color = "#4EC0FF";
document.getElementById(firstId).style.borderBottom = "2px solid #4EC0FF";
});
}.bind(this));
}.bind(this));
},
flowWebsocket() {
var socket = new SockJS("http://10.88.44.142:8080/ws");
var stompClient = Stomp.over(socket);
var titles = [];
var id = '';
var step = null;
stompClient.connect({}, function(frame) {
stompClient.subscribe('/topic/step', function(message) {
console.log('message-', message);
console.log('date', this.getCurrentDate(2));
this.imgs.forEach(step => {
// debugger;
document.getElementById(step.id).style.color = "#808891";
document.getElementById(step.id).style.borderBottom = "2px solid white";
});
//id = message.id;
step = JSON.parse(message.body);
id = step.id;
console.log('id-', id);
document.getElementById(id).style.color = "#4EC0FF";
document.getElementById(id).style.borderBottom = "2px solid #4EC0FF";
console.log("目前的流程节点-", document.getElementById(id));
this.contentSrc = (step.url == null) ? this.url : step.url;
if(id == "5") {
this.isUrl = false;
this.$refs.done.style.height = "0vh";
this.$refs.done.style.backgroundColor = "#F7F8FA";
this.$refs.done.style.color = "#2EA40D";
}
}.bind(this));
}.bind(this));
},
test() {
var titles = ['ITSM工单系统', '自动化执行', '完成'];
console.log('titles', titles)
var num = 1;
var id = '';
titles.forEach(title => {
id = title + num;
this.items.forEach(item => {
if(title == item.subTitle) {
this.imgs.push({
'id': id,
'imgSrc': item.imgSrc,
'subTitle': item.subTitle
})
}
})
})
},
getCurrentDate(format) {
var now = new Date();
var year = now.getFullYear(); //得到年份
var month = now.getMonth(); //得到月份
var date = now.getDate(); //得到日期
var day = now.getDay(); //得到周几
var hour = now.getHours(); //得到小时
var minu = now.getMinutes(); //得到分钟
var sec = now.getSeconds(); //得到秒
month = month + 1;
if(month < 10) month = "0" + month;
if(date < 10) date = "0" + date;
if(hour < 10) hour = "0" + hour;
if(minu < 10) minu = "0" + minu;
if(sec < 10) sec = "0" + sec;
var time = "";
//精确到天
if(format == 1) {
time = year + "-" + month + "-" + date;
}
//精确到分
else if(format == 2) {
time = year + "-" + month + "-" + date + " " + hour + ":" + minu + ":" + sec;
}
return time;
}
},
mounted() {
this.initWebsocket();
// this.test();
this.flowWebsocket();
}
}
</script>
<style lang="css" scoped>
@import url("../assets/icon/iconfont.css");
.center {
/*border: 1px solid red;*/
margin: auto;
width: 90vw;
text-align: center;
}
.title {
/*height: 10vh;*/
padding: 0vh 0vh 0vh 0vh;
font-size: 3vw;
margin-top: 3vh;
margin-bottom: 2vh;
}
.flow {
/*border: 1px solid blue;*/
height: 15vh;
}
.flow span {
font-size: 4vw;
}
.multiColor {
background: -webkit-linear-gradient(left bottom, #2CA10A, #5BEE4C);
font-size: 15vw;
}
.icon-wanchenggouxuan {
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.flow p {
font-size: 6vw;
}
.flow div {
/*color: #4EC0FF;*/
color: #808891;
/*border-bottom: 2px solid #808891;*/
padding-right: 5vw;
padding-left: 5vw;
margin-left: 1vw;
display: inline-block;
}
iframe {
width: 90vw;
height: 70vh;
}
.content {
margin-top: 1vh;
/*border: 1px solid green;*/
height: 70vh;
}
.content div {
font-size: 10vw;
background-color: #F7F8FA;
padding: 15vh;
}
.openning {
padding: 40vh 0vh;
font-size: 60px;
font-weight: bold;
background: -webkit-linear-gradient(left,red,orange,yellow,green,blue,indigo,violet);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
</style>
更多推荐
所有评论(0)