mvvm视图不刷新问题
vue2.x
针对数组
1 直接数组[下标]=值 操作 数据修改视图不刷新
const app = new Vue({
data: {
obj: {}
},
methods: {
add() {
// this.obj.a = '这是a属性';
this.$set(this.obj, 'a', '这是a属性的值')
},
change() {
this.obj.a = '被点击值修改了';
}
},
})
解决方法:this.$set(对象,属性,值)
const vm = new Vue({
data:{
arr:['a','b','c','d']
},
methods:{
changeli(index){
// this.arr[index]='被点击了'
this.$set(this.arr,index,"被点击了,值改变了")
}
}
});
vm.$mount('#app')
2 直接修改数组的length属性 视图也不刷新
const vm = new Vue({
data:{
arr:['a','b','c','d']
},
methods:{
// changeli(index){
// // this.arr[index]='被点击了'
// this.$set(this.arr,index,"被点击了,值改变了")
// },
changelength(){
// this.arr.length=0
// this.arr=[]
this.arr.splice(0,this.arr.length)
}
}
});
原因:
Object.defineProperty setter 劫持不到 数组 上面两个操作
怎么解决?
实例上有一个方法
s
e
t
使用
set 使用
set使用set 修改数据后视图刷新
this.
s
e
t
(
对象
,
属性
,
值
)
t
h
i
s
.
set(对象,属性,值) this.
set(对象,属性,值)this.set(数组,下标,值)
length 不建议直接修改length 改为使用 splice
以上问题 3.x 原因 Proxy 代理可以劫持到 数组 以上操作
3.动态添加属性视图不刷新
<button @click=“setA”>添加属性a
{{obj.a}}
<div id="app">
<!-- 点击添加obj属性a -->
<button @click="setA">添加属性a</button>
{{obj.a}}
</div>
<script>
const {createApp}=Vue
const app =createApp({
data(){
return{
obj:{
}
}
},
methods:{
setA(){
this.obj.a='111'
// this.$set(this.obj,'a','添加了obj的属性a')
console.log(this.obj);
}
}
});
// 渲染到dom树
app.mount('#app')
</script>
视图不刷新原因:
对象obj初始值没有a属性,vue2mvvm原理开始遍历不到该属性,无法监听,a没有setter,无法通知观察者触发render生成虚拟dom,一般会警告该属性未定义,$set可以动态添加对象的属性和属性值
针对 动态属性
一个数据是 对象 初始化 是空 对象, 后续动态给对象添加了 某个属性,这个属性 变化视图不刷新,
初始化 Vue遍历 时 ,对象没有这个属性,这个属性就没有setter
解决方案:
使用 s e t 动态添加 s e t t e r 将该属性变成动态属性( set动态添加setter将该属性 变成动态属性( set动态添加setter将该属性变成动态属性(set给他添加 setter)$set相当于解决vue2.x不完美之处的补丁
一些数据 初始化时 未在data中定义初始值, 没有setter 后续视图不刷新
要求:
所有的数据,一定要在data中定义 合理的初始值
注意!!!建立空对象是不好的代码习惯。定义 data 对象时建议初始化所有可能被用到的属性,即使初值是 undefined 或 null。这样做的好处是使得 Vue 能够正确地检测到对象的属性并将其设置成响应式的,而不会在请求数据过来之前会报未定义。
不好代码习惯后果举例
在此之前视图不刷新问题全是vue2中出现的问题,但在下述代码vue3下的代码,初始化时,数据未在data里面定义,后续动态通过this赋值视图也不会刷新,这个没有特别好的解决方案,是因为坏的代码习惯导致的,在小程序开发中问题最常见
<div id="app">
<!-- 点击添加msg -->
<button @click="createmsg">添加msg</button>
{{msg}}
<button @click="changemsg" v-if="isshow">修改msg</button>
{{msg}}
</div>
<script src="./vue.global.js"></script> //vue3js文件
<script>
const {createApp}=Vue
const app =createApp({
data(){
return{
isshow:false
}
},
methods:{
createmsg(){
this.msg='这是动态添加的msg'
this.isshow=true
},
changemsg(){
this.msg='值改变了'
console.log(this.msg);
}
}
});
// 渲染到dom树
app.mount('#app')
</script>
代码最好遵循如下要求:
1.所有的数据一定要在data中定义初始值,如果是对象,对象属性一定要定义
2.设置合理数据类型初始值