在vue中什么是set ?什么是 nexttick ?有什么相同,有什么不同?
我们都知道在vue中,主要分为视图和数据两大结构,那么在一些情况下,我们误认为自己已经更新了试图或者数据,但是在实际操作中并没有修改。这时候我们就需要用到 set 和 nexttick 。
我们首先说一下 nexttick ,一般情况下我们是把它放在,这里为了方便大家理解,我先通过点击事件触发的方式写一个简单的demo 。在实际的案例中我们也是把它放在一个事件内的。
项目应用:
当我们触发一个事件后,我要提取修改后的值,并且把它重新渲染到页面上,这个地方我写了三种方法,我们一一来看最后到底是那种方法提取到了修改后的值。
<template>
<div>
<div ref="mydiv">{{title}}</div>
<p v-if="title1">第一种修改方式 {{title1}}</p>
<p v-if="title2">第二种修改方式 {{title2}}</p>
<p v-if="title3">第三种修改方式 {{title3}}</p>
<el-button type="success" plain @click="changeFn" >点击改变</el-button>
</div>
</template>
<script>
export default {
name: "Index",
data() {
return {
title:"默认值",
title1:"",
title2:"",
title3:""
};
},
methods: {
changeFn(){
this.title="修改后"
this.title1 =this.$refs.mydiv.innerHTML
this.$nextTick(()=>{
this.title2 =this.$refs.mydiv.innerHTML
})
this.title3 = this.$refs.mydiv.innerHTML
},
},
};
</script>
<style scoped lang="scss">
</style>
效果图:
项目实际应用:
这里偷个懒啦,实际应用效果还是挺多的,这里就拿一下element ui里面的一个例子来吧。
那么究竟是为什么会产生这样的结果呢?小编在这里总结一下个人的经验和看法,Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,然后把在同一个事件循环 (event loop 这个事件机制在之前的文章当中有特别详细的讲解,大家可以去翻看一下),vue中是区分 dom 和 数据的,我的data中的数据发生了改变,但是dom中 因为是异步,所以修改data中的数据以后不会跟进刷新,(大佬自动忽略),而nexttick 是等待dom渲染完成后执行的一个函数,所以说这个时候我已经渲染完成了,这个时候再对值进行一个修改。这就是我理解的 nexttick
接下来我们再来说 set
Vue
文档有这么一句话:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新;
带着这句话,首先介绍一下它的用法
调用方法:Vue.set( target, key, value )
target:要更改的数据源(可以是对象或者数组)
key:要更改的具体数据
value :重新赋的值
<template>
<div class="app-container home">
<div v-for="(v, i) in data" :key="i">
{{ v.text }}
</div>
<el-button class="btn" @click="changeFn0()">按钮零</el-button><br />
<el-button class="btn" @click="changeFn1()">按钮一</el-button><br />
<el-button class="btn" @click="changeFn2()">按钮二</el-button><br />
</div>
</template>
<script>
export default {
name: "Index",
data() {
return {
data: [
{ text: "这是第一条数据 " },
{ text: "这是第二条数据 " },
{ text: "这是第三条数据 " },
],
};
},
methods: {
changeFn0(){
//正常情况下应该添加最后一条数据
var length = this.data.length;
this.data[length].text="add last one"
},
changeFn1() {
this.$set(this.data, 1, { text: "edit last" });
},
changeFn2() {
var length = this.data.length;
this.$set(this.data, length, { text: "add last two" });
},
},
};
</script>
<style scoped lang="scss"></style>
效果展示:
三个按钮依次点击后
我们都知道vue的数据双向绑定是通过原型链上面的get 和 set 属性更改的,但是我们这时候无论怎么点击button 无论怎么更改是不会更新的,因为在创建实例的时候 缺少了vue 监听的 set、get属性。(这个地方有兴趣的可以去看一下vue双向绑定的底层原理就会明白了)
那么接下来到了我们上面的问题解答环节了,nexttick 是指 在dom渲染完成后执行的一个函数,在某些特定情况下,我在这个方法中修改了值,然后要在页面上渲染这个值,这时候就需要用到nexttick,set是什么呢?set其实就是我在对一些数组嵌套对象 对象嵌套数组,想对内部的数据进行更改的时候,因为在创建实例期的时候 缺少了vue监听的 set get 属性,所以导致了内容不会更新,nexttick 在源码中编译成了如果在浏览器支持promise 我就添加了一个promise,然后按照时间循环机制event loop执行代码顺序,如果浏览区不支持promise ,源码中就会编译成一个set time out。 他们两个的共同点都在于,修改了数据以后,页面不会进行一个实时的页面刷新;不同点就在于,nexttick 更新的dom渲染完成后,而 set 是更新的是数据。