先通过一个案例具体讲解
<template>
<div>
<div id="app">
<ul ref="ul1">
<li v-for="(item,index) in list" :key="index">
{{item}}
</li>
</ul>
<button @click="addItem">添加一项</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list:['a','b','c']
}
},
methods: {
addItem(){
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
//获取DOM元素
const ulElem = this.$refs.ul1
//eslint-disable-next-line
console.log(ulElem.childNodes.length)
}
},
}
</script>
打印出来是什么样的呢?
不觉得很奇怪吗,我们ul里面明明有9个li标签,但是显示它的子节点长度只有6个
因为当data里面的数据改变的时候,dom不会立刻去改变,此时获取不到最新的,vue是异步渲染的,所以当第一次添加的时候,显示的子节点长度其实是之前的a,b,c的长度,
那我们想当点击完之后立即拿到结果怎么办?很简单,我们把它用nexttick包裹起来
this.$nextTick(()=>{
//获取DOM元素
const ulElem = this.$refs.ul1
//eslint-disable-next-line
console.log(ulElem.childNodes.length)
})
总结一下:
vue是异步渲染
data改变之后,DOM不会立刻渲染
$nexttick会在DOM渲染之后被触发,以获取最新DOM节点
页面渲染时会将data的修改做整合,多次data修改只会渲染一次
下面再介绍一下异步组件,何为异步组件,就是按需加载,异步加载大组件
还是用一个例子说明一下
<template>
<div>
<bigDeom v-if="isShow"></bigDeom>
<button @click="isShow = true"></button>
</div>
</template>
<script>
export default {
// import()函数
components:{
// bigDeom:()=>import('') 会向这样引入,而不是在外面直接import引入
// 这样写当我们第一次进入页面的时候,这个组件不会被加载,当我们点击按钮时候它才会加载出来,
// 这样可以极大优化性能
},
data() {
return {
isShow:false
}
},
}
</script>