需求
- 如上图所示,此功能为做一个重命名功能;
实现
-
<template> <div> <!-- c-table为基于elementUI的el-table进行封装的组件 --> <c-table :table-column="priceTableCol" :table-data="list"> <template v-slot:name2="row"> <el-input v-model="row.data.name2" /> </template> </c-table> </div> </template> <script> export default { data(){ return{ list:[] } }, created(){ this.priceTableCol = [ { prop: 'name', label: '姓名', align: 'center' }, { label: '别名', align: 'center', slot: 'name2' }, { prop: 'age', label: '年龄', align: 'center' }, ] this.getData() }, methods:{ getData(){ // 模拟在服务端拉取数据 this.list=[ {name:111, age:18}, {name:222, age:22} ] this.list.forEach(item=>{ item.name2= item.name }) } } } </script>
-
执行逻辑为
- [1]拉取服务端数据显示在表格中;
- [2]不能直接修改name属性,否则显示姓名列会随之改变 —> 因此将name属性值赋值给新添加的属性name2;
- [3]将name2属性作为重命名列属性值进行显示;
问题
当前使用vue版本2.6.12
重命名
- 通过上述视频可以发现,当我手动在页面删除姓名为111列的重命名时,页面内容并没有删除掉,但是打印的时候发现list里面的name2属性值已经变为了空字符串;
- 说明->data中的数据发生了变化,视图上的数据没有随之改变->数据没有实现双向绑定!
- 通过双向数据绑定原理我们可以看出在vue2.x中,有些数据并不能被完全监听到;
对象的新增属性不能被监听到
;数组通过数据下标进行赋值不能被监听到
;直接修改数组的length属性不能被监听到
;- 修改多层嵌套的值不容易被监听到;
解决
可以通过$set来解决!
<template>
<div>
<el-button @click="togetData">点击</el-button>
<c-table :table-column="priceTableCol" :table-data="list" :span-method="spanMethod" :is-show-pagination="false">
<template v-slot:name2="row">
<el-input v-model="row.data.name2" />
</template>
</c-table>
</div>
</template>
<script>
export default {
data(){
return{
list:[]
}
},
created(){
this.priceTableCol = [
{
prop: 'name',
label: '姓名',
align: 'center'
},
{
label: '重命名',
align: 'center',
slot: 'name2'
},
{
prop: 'age',
label: '年龄',
align: 'center'
},
]
this.getData()
},
methods:{
getData(){
this.list=[
{name:111, age:18},
{name:222, age:22}
]
this.list.forEach(item=>{
this.$set(item, 'name2', item.name)
})
},
togetData(){
console.log('this.list', this.list)
}
}
}
</script>
[1]发现 在没有使用$set时,仅有name属性与age属性有set与get方法,name2属性没有
[2]在使用了$set对name2进行赋值之后,name2也有get与set方法
知识点-$set
[1]为什么使用$set
在vue中,并不是任何时候数据都是双向绑定的,就比如上述修改多层嵌套数据时,数据的双向绑定就会失效;set为解决双向绑定失效而生!
[2]语法
-
修改/添加数组属性
-
Vue.$set(数组,索引值,元素值)
-
-
修改/添加对象属性
-
Vue.set(对象, 属性名,属性值)
-
[3]原理
其实$set就是调用 Object.defineProperty 方法为当前属性添加get与set方法!
知识点-$forceUpdate
使用vue实例化对象的$forceUpdate方法也可以解决此问题;
- 作用:具有强制刷新的功能,迫使Vue实例化对象重新渲染,仅仅影响本身和插槽内容的子组件,而不是影响所有子组件;