前言

在开发过程中,我们时常会遇到这样一种情况:当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. php环境 安装

    php 相关 wget https://www.php.net/distributions/php-7.2.16.tar.gz //你可以官网获取最新的包        tar解压    //一般目录 ...

  2. PHP 一个树为另一棵树的子结构 [TO BE CONTINUED]

    输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) <?php class TreeNode { private $val; private $left; ...

  3. phpstorm 配置Psr4 风格代码

    http://www.cnblogs.com/xp796/p/6441700.html

  4. 基于Processing图像序列处理保存导出的流程梳理

    做一个基于processing的图像序列处理保存导出的流程梳理.本案例没有什么实质性的目的,仅为流程梳理做演示. 准备 把需要处理的影像渲染成序列图片,可以在PR中剪辑并导出PNG序列[格式倒是没什么 ...

  5. kubelet源码分析——关闭Pod

    上一篇说到kublet如何启动一个pod,本篇讲述如何关闭一个Pod,引用一段来自官方文档介绍pod的生命周期的话 你使用 kubectl 工具手动删除某个特定的 Pod,而该 Pod 的体面终止限期 ...

  6. MacOS Typora集成SM.SM图床 实现自动上传图片

    MacOS Typora集成SM.SM图床 实现自动上传图片 此为PicGo-Core (Command line) (OpenSource)配置方法 参照官网 https://support.typ ...

  7. SpringBoot 简易实现热搜邮件推送,妈妈再也不用担心我不了解国家大事了

    1.前言 上班的时候,无聊的时候,偶尔跑去百度看下热搜,所以就萌生出这种想法,通过邮件推送的方式实现效果,首先找到百度热搜的页面 热搜,话不多说,直接开干. 2.环境准备 因为是个SpringBoot ...

  8. 设计 4 个线程,其中两个线程每次对 j 增加 1 ,另外两个线程对 j 每次减少 1 。写出程序。

    题目:设计 4 个线程,其中两个线程每次对 j 增加 1 ,另外两个线程对 j 每次减少 1 .写出程序. 代码实现 public class ThreadTest{ private int j; c ...

  9. 暑期 2021 | Serverless Devs 最全项目申请攻略来啦!

    Serverless 是近年来云计算领域热门话题,凭借极致弹性.按量付费.降本提效等众多优势受到很多人的追捧,各云厂商也在不断地布局 Serverless 领域.但是随着时间的发展,Serverles ...

  10. .NET Core 基于Quartz的UI可视化操作组件 GZY.Quartz.MUI 简介

    前言 最近在用Quartz做定时任务.虽然很方便,但是Quartz自己貌似是没有UI界面的..感觉操作起来 就很难受.. 查了一下,貌似有个UI组件 不过看了一下文档..直接给我劝退了..太麻烦了 我 ...