数据改变但是视图不变的原因以及解决方法

本文详细介绍了Vue.js中数据驱动视图的原理,特别讨论了Vue无法检测到数组和对象某些变动的情况。针对这个问题,提出了Vue.set()、Object.assign()和数组的变异方法如push()、splice()等解决方案,确保视图能正确响应数据变化。通过实例代码展示了如何在实际操作中应用这些方法,以实现数据和视图的同步更新。
摘要由CSDN通过智能技术生成
我们都知道,vue的特点之一就是数据驱动视图,也就是当我们的数据发生改变的时候,视图也就随之改变了,不需要我们再进行更新视图的操作,但是有一些情况,我们虽然改变了数据,但是视图并没有变化,官网是这样解释的:由于 JavaScript 的限制,Vue 不能检测数组和对象的变化,其实我认为应该说vue不能检测未挂载的即后来添加的新属性,所以需要我们进行一些操作达到我们想让vue检测的目的

对于对象

  • Vue.set()

通过代码展示:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        {{show}}
        <button @click="add">添加b</button>
    </div>
    <script src="./vue.js"></script>
    <script>
        const vm = new Vue({
            el: "#app",
           data(){
                return{
                    show:{
                        a:"我是a"
                    }
                }
           },
            methods: {
                add() {
                   this.show.b = "我是b"
                   console.log(this.show)
                }
            }

        })
    </script>
</body>

</html>

效果:

在这里插入图片描述

当我们点击按钮的时候,我们可以发现show里边确实添加了b属性,但是视图并没有展示。如果我们想要展示就需要用到vue提供的一个方法Vue.set(),如果我们改变添加方式:
  methods: {
                add() {
                   Vue.set(this.show,"b",2)
                   console.log(this.show)
                }
            }

效果:
11

此时,我们点击按钮,视图发生了改变,当然,data内的show对象也添加了b属性
  • Object.assign() 或 _.extend()
官网上是这样说的:有时你可能需要为已有对象赋值多个新 property,比如使用 Object.assign() 或 _.extend()。但是,这样添加到对象上的新 property 不会触发更新。在这种情况下,你应该用原对象与要混合进去的对象的 property 一起创建一个新的对象。

我们还是通过代码理解:

 methods: {
                add() {
               this.show = Object.assign({},this.show,{b:1,c:"我是c"})
                console.log(this.show)
                }
            }

分析:Object.assign()是合并对象的意思,Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。代码的意思是我们把原来的对象和新增属性组成的对象,合并到一个空对象里边{},这时候相当于给我们data里边的show重新赋值;(_.extend()也是合并的一种方式)

效果:
11

对于数组

Vue 不能检测以下数组的变动:
  • 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
  • 当你修改数组的长度时,例如:vm.items.length = newLength
那我们怎么改变数组已经定义好的元素呢?
  • 方法一:变更方法(这种都是修改原数组)
就拿我们通过索引来修改原数组

代码举例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        {{arr}}
        <button @click="btn">点击</button>
    </div>
    <script src="./vue.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                arr: [1, 2]
            },
            methods: {
                btn() {
                    this.arr[2] = 3
                    console.log(this.arr)
                }
            }
        })
    </script>
</body>

</html>

效果:

11

跟改变对象属性很类似,那个是用到了Vue.set方法,在数组里边我们就要用可以引起视图发生改变的方法。
  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
还是那个例子,我们就可以用数组的splice或者push进行添加操作
methods: {
                btn() {
                    this.arr.splice(2,1,3)
                    //或者push
                    // this.arr.push(3)
                    console.log(this.arr)
                }
            }

效果:

11

替换数组

官方解释:变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,例如 filter()、concat() 和 slice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:
解释:比如filter()方法,我们进行筛选过后,并不会改变原数组,而是返回一个新数组,我们再把新数组赋值给一个已经定义好的数组来保存就可以(有点类似,对象使用的方法Object.assign()方法,空对象,把需要的总的数据放到空对象里边,再把这个新对象赋值给定义好的对象)

代码举例:

 const app = new Vue({
            el: "#app",
            data: {
                arr: [1, 2, 5, 6, 8],
            },
            methods: {
                btn() {
                    this.arr = this.arr.filter(item => {
                        return item > 3
                    })
                      console.log(this.arr)
                }
            }
        })

11

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值