前言

在开发过程中,我们时常会遇到这样一种情况:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的。

根据官方文档定义:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter

受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

对象

看一下示例:

在vue框架中,如果data中有一个变量:age,修改他,页面会自动更新。但如果data中的变量为数组或对象,我们直接去给某个对象或数组添加属性,页面是识别不到的

<template>
<p>{{userInfo.name}}</p>
<p v-if="userInfo.sex">{{userInfo.sex}}</p>
<button @click="updateName">修改userInfo</button>
<button @click="addSex">添加性别</button>
</template>
<script>
data(){
userInfo:{name:'小明'}
},
methods:{
updateName(){
this.userInfo.name='小红'
},
addSex(){
this.userInfo.sex = '男'
}
}
</script>

可以发现,在updateName函数中,我们尝试给userInfo对象修改name值,并成功修改,但添加的sex属性失败了

分析

  • 名字修改成功是因为vue初始化时为对象的属性建立 了getter/setter函数,可以监测数据变化并挂载到视图上
  • 而新增的sex属性由于错过了建立getter/setter阶段,即使在userInfo对象中添加成功,但由于没有setter函数,无法响应到视图上

解决方法

方法一:$forceUpdate()

迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

methods:{
updateName(){
this.userInfo.sex='男'
this.$forceUpdate();
}
}

方法二:Vue.set(object, key, value)

methods:{
updateName(){
this.$set(this.userInfo,'sex,'男');
}
}

数组

上面的例子反映的是给对象添加属性时的问题,数组同样有类似的问题,请看下面的例子

<body>
<div id="app">
<p>{{userInfo.name}}</p>
<p v-if="userInfo.sex">{{userInfo.sex}}</p>
<ul>
<li v-for="(item,index) in hobbies" :key='index'>{{item}}</li>
</ul>
<button @click="update">修改爱好</button>
</div>
<script>
let vm = new Vue({
el:'#app',
data: {
userInfo:{name:'小明'},
hobbies:['抽烟','喝酒','烫头']
},
methods:{
update(){
this.hobbies[2] = '读书'
}
}
})
</script>
</body>

点击修改爱好按钮后页面并没有修改,打开控制台发现值已修改

解决方法

一、使用vue提供的更新数组的方法

vue给我们提供了它封装后的可用于对数组进行增删改查操作的方法

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

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

上面的例子

update(){
//参数分别是:开始索引,是否删除(0:添加 1:删除),修改后的值
this.hobbies.splice(2,1,'读书')
},

使用封装后的方法则可以成功渲染到视图

二、Vue.set()

update(){
//参数分别是:对象,索引,修改后的值
Vue.set(this.hobbies,2,'读书')
},

三、this.$forceUpdate()

 update() {
this.hobbies[2] = '读书'
this.$forceUpdate()
},

forceUpdate() & set的更多相关文章

  1. vue之$forceUpdate

    由于一些嵌套特别深的数据,导致数据更新了.UI没有更新(连深度监听都没有监听到) this.$forceUpdate();

  2. React篇-报错信息:warning: Can't call setState (or forceUpdate) on an unmounted component.

    报错信息是: Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but ...

  3. Vue.extend构造器和$mount实例构造组件后可以用$destroy()进行卸载,$forceUpdate()进行更新,$nextTick()数据修改

    html <div id="app"> </div> <p><button onclick="destroy()"&g ...

  4. Can’t call setState (or forceUpdate) on an unmounted component 警告处理方法

    Can’t call setState (or forceUpdate) on an unmounted component Warning: Can't call setState (or forc ...

  5. 温故而知新 Vue 原来也有this.$forceUpdate();

    由于一些嵌套特别深的数据,导致数据更新了.UI没有更新(连深度监听都没有监听到),我捉摸着有没有和react一样的立即更新UI的API呢 this.forceUpdate()呢?结果还真有: this ...

  6. Vue – 基础学习(3):$forceUpdate()和$nextTick()的区别

    Vue – 基础学习(3):$forceUpdate()和$nextTick()的区别

  7. VUE项目中使用this.$forceUpdate()强制页面重新渲染

    在使用Vue框架开发时,在函数中改变了页面中的某个值,在函数中查看是修改成功了,但在页面中没有及时刷新改变后的值,我是在使用多层v-for嵌套时出现这种问题的, 解决方法:运用 this.$force ...

  8. VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题

    VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题:https://blog.csdn.net/jerrica/article/d ...

  9. vue $forceUpdate() 强制重新渲染

    vue $forceUpdate() 强制重新渲染:https://blog.csdn.net/z9061/article/details/94862047

  10. vue2.0 操作数组下标不跟新ui,使用set()或$forceUpdate 也不能跟新视图情况

    在vue 2.0 中操作数组不跟新ui图,即使使用set()或 $forceUpdate也不能跟新视图,我在前段时间也遇到了一个问题,当时我使用的时element 的tree 组件 由于需要对tree ...

随机推荐

  1. js 模板方法模式

    * 分离出共同点 function Beverage() {} Beverage.prototype.boilWater = function() { console.log("把水煮沸&q ...

  2. Windows系统中的SVN使用方法

    Windows 下搭建 SVN(3.9版本)服务器 2018年08月11日 12:22:55 Amarao 阅读数 11984   版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议, ...

  3. LR11可打开网页,但录制为空

    环境:WIN7+LR11+360安全浏览器9.0 LR11可打开网页,但录制为空解决方案:(3步) 1. tools-Recording Options -->Network-->Port ...

  4. P3211-[HNOI2011]XOR和路径【高斯消元】

    正题 题目链接:https://www.luogu.com.cn/problem/P3211 题目大意 一个\(n\)个点\(m\)条边的无向图,从\(1\)到\(n\)随机游走.求期望路径异或和. ...

  5. WPF进阶技巧和实战07--自定义元素02

    在01节中,研究了如何开发自定义控件,下节开始考虑更特殊的选择:派生自定义面板以及构建自定义绘图 创建自定义面板 创建自定义面板是一种比较常见的自定义控件开发子集,面板可以驻留一个或多个子元素,并且实 ...

  6. 淘宝商品html--网页结构

    淘宝商品html--网页结构 本篇爬虫紧接上一篇关于 泸州老窖 的爬虫随笔: import re import json def get_space_end(level): return ' ' * ...

  7. PAT (Basic Level) Practice (中文)1025 反转链表 (25分)

    1025 反转链表 (25分) 给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转.例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→ ...

  8. C#特性知识图谱-一、委托

    一. 委托 1.1 委托定义 委托可以看成是一个方法的容器,将某一具体的方法装入后就可以把它当成方法一样调用.一个委托类型的变量可以引用任何一个满足其要求的方法.委托类似于C语言中的函数指针,但并不完 ...

  9. SPI在JDBC中的运用

    前言 之前学习了JDK SPI的机制,本文专门讨论2个内容: 1.为什么在使用SPI后,不需要Class.forName()了? 2.SPI在JDBC中的运用. JDBC模板代码 private st ...

  10. 【UE4 C++】编程子系统 Subsystem

    概述 定义 Subsystems 是一套可以定义.自动实例化和释放的类的框架.可以将其理解为 GamePlay 级别的 Component 不支持网络赋值 4.22开始引入,4.24完善.(可以移植源 ...