• Vue_双向数据绑定失效踩坑-使用$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
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
    • 执行逻辑为

      • [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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    [1]发现 在没有使用$set时,仅有name属性与age属性有set与get方法,name2属性没有

    • 在这里插入图片描述

    [2]在使用了$set对name2进行赋值之后,name2也有get与set方法
    在这里插入图片描述

    知识点-$set
    [1]为什么使用$set

    在vue中,并不是任何时候数据都是双向绑定的,就比如上述修改多层嵌套数据时,数据的双向绑定就会失效;set为解决双向绑定失效而生!

    [2]语法
    • 修改/添加数组属性

      • Vue.$set(数组,索引值,元素值)
        
        • 1
    • 修改/添加对象属性

      • Vue.set(对象, 属性名,属性值)
        
        • 1
    [3]原理

    其实$set就是调用 Object.defineProperty 方法为当前属性添加get与set方法!

    知识点-$forceUpdate

    使用vue实例化对象的$forceUpdate方法也可以解决此问题;

    • 作用:具有强制刷新的功能,迫使Vue实例化对象重新渲染,仅仅影响本身和插槽内容的子组件,而不是影响所有子组件;
  • 相关阅读:
    Kafka
    (十五)VBA常用基础知识:正则表达式的使用
    20221121 今天的世界发生了什么
    前端三件套速成
    数学小抄: 概率角度推导Kalman Filter
    【图像插值】基于稀疏拉普拉斯滤波器处理红绿蓝三种像素实现插值效果附matlab代码
    SV-7041T IP网络有源音箱 教室广播多媒体音箱(带本地扩音功能)教学广播音箱 办公室背景音乐广播音箱 2.0声道壁挂式网络有源音箱
    UDP-GlcNAc,UDPAG,尿苷二磷酸-N-乙酰基葡萄糖胺,UDP-N-乙酰葡糖胺
    [附源码]Python计算机毕业设计SSM流浪猫狗救助站(程序+LW)
    【云原生 • Kubernetes】kubernetes 核心技术 - RC、Replica Set 和 Deployment
  • 原文地址:https://blog.csdn.net/qq_43260366/article/details/126852244