背景
页面触发事件修改对象类型
的数据值,对象数据已成功修改,但是页面不更新
、不渲染
新数据值。
代码
<template>
<div>
<ul>
<li v-for="(item, index) in persons" :key="index">
{{ item.key }} - {{ item.name }}
</li>
</ul>
<button @click="add">修改属性值</button>
</div>
</template>
<script>
export default {
name: 'XuanRan',
data() {
return {
persons: [
{key: 'orgData1', name: '123'}
]
}
},
methods: {
add() {
this.persons[1] = {key: 'newkey', name: '888'}
console.log(this.persons)
}
}
}
</script>
现象
可以看到页面中并没有自动更新新增的信息,但是,在控制台可以打印出来
解决方法
1. ...
展开语法
方法:
- 对象数据obj,使用
obj = {...obj}
- 对于数组arr,使用
arr = [...arr]
针对上例,修改add方法。
add() {
this.persons[1] = {key: 'newkey', name: '888'}
this.persons = [...this.persons]
console.log(this.persons)
}
2. 使用Vue.set( target , key , value)
方法:
- target: 要更改的数据源(可以是一个对象或者数组)
- key 要更改的具体数据。如果是数组元素更改,key表示索引;如果是对象,key表示键值
- value 重新赋的值
针对上例,修改add方法。
add() {
this.$set(this.persons, 1, {key: 'newkey', name: '888'})
console.log(this.persons)
}
3. 使用Object.assign()
MDN:Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
方法:
- 克隆对象,
Object.assign({}, target)
- 克隆数组,
Object.assign([], target)
针对上例,修改add方法。
add() {
this.persons[1] = {key: 'newkey', name: '888'}
this.persons = Object.assign([], this.persons)
console.log(this.persons)
}
4. 使用lodash
的clone
方法
方法:
- npm i --save lodash
- import _ from 'lodash'
- _.clone(target)
针对上例,修改add方法。
<script>
import _ from 'lodash'
export default {
name: 'XuanRan',
data() {
return {
persons: [
{key: 'orgData1', name: '123'}
]
}
},
methods: {
add() {
this.persons[1] = {key: 'newkey', name: '888'}
this.persons = _.clone(this.persons)
console.log(this.persons)
}
}
}
</script>
5. 使用$fourceUpdate
- 迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
针对上例,修改add方法。
add() {
this.persons[1] = {key: 'newkey', name: '888'}
this.$forceUpdate()
console.log(this.persons)
}