Vue中直接操作数组索引不奏效的问题解读

目录
  • Vue操作数组索引不奏效
    • 1.案例
    • 2.解释
    • 3.如何操作数组
    • 4.深层原因
  • 更新数组或对象不生效
    • 新增对象属性不生效
    • 更新数组元素不生效

Vue操作数组索引不奏效

1.案例

我们首先创造一个数组hobby并展示

data:{
hobby:["抽烟" , "喝酒" , "烫头"]
}
<ul>
	<li v-for="(item , index) in hobby">{{item}}</li>
</ul>

此时,我们在控制台操作修改该数组

vm.hobby[0] = "运动"

会发现此时数组确实已经修改,但页面内容并没有改变

2.解释

我们知道,Vue会对每一个data中的对象创建getter和setter方法,来实现响应式

我们查看此数组,发现并没有对每个数组元素的getter和setter方法的设置

此处为了方便理解,我们将该数组改为对象,对比一下

data: {
          hobby: {
            i1:"抽烟",
            i2:"喝酒",
            i3:"烫头"
            }
    }

很明显多了对于每一项的setter和getter方法的设置,这是响应式的关键

3.如何操作数组

一.push、pop、shift、unshift、reverse、sort、splice等可以直接修改数组本身的方法,可以做到响应式

vm.hobby.push('运动') //页面实时更新了

二.使用Vue.set()方法

以上两种方法都可以做到响应式

4.深层原因

这里沿用上例。

此处调用的操作数组的方法push,其实已经不是数组原型对象中的push了

Vue中存在的push,第一步先调用了Array原型对象的push,第二步重新解析模板,生成虚拟DOM

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

以上为官方文档。

多看看文档总是会有收获的

更新数组或对象不生效

新增对象属性不生效

<body>
    <div id="root">
        <button @click="updateInfo">更新学生信息</button>
        <div>姓名:{{student.name}}</div>
        <div>年龄:{{student.age}}</div>
        <div>性别:{{student.gender}}</div>
    </div>
    <script>
    Vue.config.productionTip = false;
    const vm = new Vue({
        el:"#root",
        data:{
            student:{
                name:"张三",
                age:18
            }
        },
        methods:{
            updateInfo(){
                this.student.gender = "男";
            }
        }
    })
    </script>
</body>

【问题描述】如上图所示,this.student.gender = “男”,新增对象属性不生效。

【解决方法】使用Vue.set(target,key,value)或者vm.$set(target,key,value),如下图所示。

以下四个写法均可。

Vue.set(vm.student,“gender”,“男”)
Vue.set(vm._data.student,“gender”,“男”)
vm.$set(vm.student,“gender”,“男”)
vm.$set(vm._data.student,“gender”,“男”)

所以,updateInfo函数可以改成这样:

<body>
    <div id="root">
        <button @click="updateInfo">更新学生信息</button>
        <div>姓名:{{student.name}}</div>
        <div>年龄:{{student.age}}</div>
        <div v-if="student.gender">性别:{{student.gender}}</div>
    </div>
    <script>
    Vue.config.productionTip = false;
    const vm = new Vue({
        el:"#root",
        data:{
            student:{
                name:"张三",
                age:18,
            }
        },
        methods:{
            updateInfo(){
                // Vue.set(this.student,"gender","男");
                this.$set(this.student,"gender","男");
            }
        }
    })
    </script>
</body>

更新数组元素不生效

<body>
    <div id="root">
        <button @click="updateInfo">更新马某梅的信息</button>
        <ul>
            <li v-for="(p,index) of persons" :key="p.id">
                {{p.name}}-{{p.age}}-{{p.gender}}
            </li>
        </ul>
    </div>
    <script>
    Vue.config.productionTip = false;
    new Vue({
        el:"#root",
        data:{
            persons:[
                {id:"001",name:"周冬雨",age:18,gender:"女"},
                {id:"002",name:"马冬梅",age:19,gender:"女"},
                {id:"003",name:"张桂梅",age:59,gender:"女"},
                {id:"004",name:"周杰伦",age:30,gender:"男"}
            ]
        },
        methods:{
                updateInfo(){
                    //更新 奏效
                    // this.persons[1].name = "马铁梅";
                    // this.persons[1].age = 25;
                    // this.persons[1].gender = "男";
                    //更新 不奏效
                    this.persons[1] = {
                   		id:"002",
                        name:"马铁梅",
                        age:25,
                        gender:"男"
                    }
                }
            }
    })
    </script>
</body>

【问题描述】this.persons[1]={name:xxx,age:xxx,gender},更新数组元素不生效。

【解决方法】有两种解决方法:

使用方法splice更新数组,如下所示。

this.persons.splice(1,1,{
    id:"002",
    name:"马铁梅",
    age:25,
    gender:"男"
})

使用Vue.set(target,key,value)或者vm.$set(target,key,value)

this.$set(this.persons,1,{
    id:"002",
    name:"马铁梅",
    age:25,
    gender:"男"
})
//或者
Vue.set(this.persons,1,{
    id:"002",
    name:"马铁梅",
    age:25,
    gender:"男"
})

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Vue2中无法检测到数组变动的原因及解决

    目录 解决方法 由于JavaScript 的限制,Vue 不能检测以下数组的变动: 当利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue 当修改数组的长度时,例如:vm.items.length = newLength var vm = new Vue({ data: { items: ['a', 'b', 'c'] } }) vm.items[1] = 'x' // 不是响应性的 vm.items.length = 2 // 不是响应性的 解决

  • vue.set向对象里增加多层数组属性不生效问题及解决

    目录 属性多层数组数据的添加修改 为什么需要使用Vue.set? 最近项目中使用到了树形表格 向对象数组中添加新属性 属性多层数组数据的添加修改 为什么需要使用Vue.set? vue中不能检测到数组的一些变化 比如一下两种: 1.数组长度的变化 vm.arr.length = 100 2.数组通过索引值修改内容 vm.arr[1] = ‘aa’ 那么为什么vue要做成这样,不去监听数组的变化,数组在日常中使用频率还是比较高的,这个问题其实尤大说过,是为了性能,假设我们新建了一个数组,长度是10

  • vue中更改数组中属性,在页面中不生效的解决方法

    问题描述: 使用vue的方法获取了数组数据,获取数据后为每个数据增加edit属性,初始值均为false,其目的是为了当点击列表中的编辑按钮时,控制保存与不保存的按钮的出现与消失,结果当更改数组中的edit属性后,页面并没有如预期的那样当edit为true时页面显示更改状态,当edit为false时为不更改状态 解决方案: edit是在通过post方法获取数据后增加到vue的data数据中的属性,一开始我的做法先将接收到的数据赋值到vue的data中,再对vue的data中的数据增加edit属性,

  • 详解vue的数据劫持以及操作数组的坑

    TL;DR 给data添加新属性的时候vm.$set(vm.info,'newKey','newValue') data上面属性值是数组的时候,需要用数组的方法操作数组,而不能通过index或者length属性去操作数组,因为监听不到属性操作的动作. 安装和初使用vue vue是构建用户界面的渐进式框架.所谓的渐进式:vue + components + vue-router + vuex + vue-cli可以根据需要选择相应的功能. 来串命令mkdir vue-apply;cd vue-ap

  • Vue中直接操作数组索引不奏效的问题解读

    目录 Vue操作数组索引不奏效 1.案例 2.解释 3.如何操作数组 4.深层原因 更新数组或对象不生效 新增对象属性不生效 更新数组元素不生效 Vue操作数组索引不奏效 1.案例 我们首先创造一个数组hobby并展示 data:{ hobby:["抽烟" , "喝酒" , "烫头"] } <ul> <li v-for="(item , index) in hobby">{{item}}</li&

  • vue中按钮操作完刷新页面的实现

    目录 vue按钮操作完刷新页面 1.父组件中实现 2.子组件绑定 点击按钮后自动刷新页面 vue按钮操作完刷新页面 首先从子组件和父组件角度去写这个东西,简言之就是在父组件中实现这个刷新功能方法,然后在子组件中进行绑定并进行监听就好了啊 1.父组件中实现 ① 图示部分: 个人建议这个作为父组件,肯定一般是放在列表中的,即把列表页面作为父组件的归属地 ② 代码部分: method方法中部分 refresh () { this.reload() } 将reload进行注入 inject: ['rel

  • vue中实现监听数组内部元素

    目录 vue监听数组内部元素 我们有两种办法解决此问题 vue如何监听数组的变化 vue监听数组内部元素 在VUE中,对数组的监听是浅监听,也就是它只能监听到数组的长度或者有无的变化,当我们修改数组中的某一个值时,也就是数组的长度状态并没有改变时,在正常情况下它是无法监听到的,在watch中我们知道可以使用deep属性进行深监听,那么在其他情况下呢? 我们有两种办法解决此问题 1.通过原生的js对数组先进行切割,然后在添加新的内容(也就是我们要修改的内容) array.splice(i, 1,

  • vue中设置滚动条方式

    目录 vue设置滚动条 vue如何在div中设置滚动条呢? vue控制滚动条 vue设置滚动条 vue如何在div中设置滚动条呢? 首先需要写一下css样式 <div     :style="{'max-height': this.timeLineHeight + 'px' }"     style="overflow-y:scroll;"  >              </div> 在这个div中,放的是你写的前端代码.它是可以滚动的.

  • 在vue中对数组值变化的监听与重新响应渲染操作

    在我们项目开发过程中,实例中的数据类型可以是对象.数组等.在对象中,某个属性值发生更改时,我们可以通过对象的深度监听,以达到重新渲染页面的需求.或者查阅这篇文章 例如: <script> export default { data(){ return { objVal: { name: 'obj', type: 'obj' } } }, watch:{ objVal:{ handler(val,oldval){ }, deep: true, } }, methods:{ changeObj()

  • vue中v-for循环选中点击的元素并对该元素添加样式操作

    相信大家都会遇到这种情况:v-for循环时,我只需要点击到的元素做出相应反应,其他的元素不变:但是往往所有v-for循环出的元素都会变化.如下面的代码:我需要点击到的元素添加一个类样式,其他元素不变,但是这样会导致所有的元素都会变化 html: <div v-for = "(item,index) in items" :class = 'addclass:isactive' @click='onclick()'> <span>{{item.name}}</

  • JS数组操作(数组增加、删除、翻转、转字符串、取索引、截取(切片)slice、剪接splice、数组合并)

    POP 删除最后一项 删除最后一项,并返回删除元素的值:如果数组为空则返回undefine var a = [1,2,3,4,5]; a.pop();//a:[1, 2, 3, 4] a.pop();//a:[1, 2, 3] a.pop();//a:[1, 2] shift 删除第一项 删除原数组第一项,并返回删除元素的值:如果数组为空则返回undefine var a = [1,2,3,4,5]; a.shift(); //a:[2,3,4,5] a.shift(); //a:[3, 4,

  • php数组索引与键值操作技巧实例分析

    本文实例讲述了php数组索引与键值操作技巧.分享给大家供大家参考.具体如下: <?php $array = array("a", "b","c"); //定义数组 $array[] = "Simon"; //增加一个新的数组元素 print_r($array); //输出数组 ?> <?php $array = array("a", "b","c")

  • 使用vue中的v-for遍历二维数组的方法

    如下所示: <table cellpadding="0" cellspacing="0" class="clearfix bigTable" id='downloaddata'> <tr v-for='(item, index) in data'> <template v-for='items in item'> <template v-for='(itemss, indexs) in items' v-

  • vue.js中$set与数组更新方法

    由于 JavaScript 的限制,Vue 不能检测以下变动的数组: 当利用索引直接设置数组的某一项时,例如:vm.items[indexOfItem] = newValue 当你修改数组的长度时,例如:vm.items.length = newLength,不会更新数组. 当然vue中给了解决方法,就是使用 Vue.set, vm.$set(Vue.set的变种写法)或者 splice,caoncat等修改数组,同时也将触发状态更新: ex: 所以如果在实例创建后添加新的属性到实例上,则不会触

随机推荐