Vue2踩坑_双向数据绑定失效踩坑-使用$set

需求

在这里插入图片描述

  • 如上图所示,此功能为做一个重命名功能;
实现
  • <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实例化对象重新渲染,仅仅影响本身和插槽内容的子组件,而不是影响所有子组件;
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值