vue数据更改视图不更新问题----深入响应式原理
当你把一个普通的JavaScript对象传给Vue实例的data选项,Vue将遍历此对象所有的属性,并使用Object.defineProperty把这些属性全部转为getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器。
这些getter/setter对用户来说是不可见的,但是在内部他们让vue追踪依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的watcher实例对象,它会在组建渲染的过程中把属性记录为依赖,之后当依赖项的setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新。
对象更改检测
在一个组件实例中,只有在data里初始化的数据才是响应的,Vue不能检测到对象属性的添加或删除,没有在data里声明的属性不是响应的。
Vue不允许在已经创建的实例上动态添加根级响应式属性,但是可以使用$set方法将相应属性添加到嵌套的对象上。
例子一:属性a是已经声明了的,是响应的;属性b没有提前声明,因此改变了属性b的值的时候,如果直接赋值 this.form.b = 'desc' , 虽然打印出来的值是改变了的,但是视图并没有更新。需要用Vue.set(object, key, value) 【或 this.$set(object,key,value)】 方法将响应属性添加到嵌套的对象上。注意:object 必须是在data中已经声明的对象。
......
<section>
<p>动态添加嵌套属性1:</p>
<p>a的值{{form.a}}</p>
<p>b的值{{form.b}}</p>
<el-button @click="changeA">改变A</el-button>
<el-button @click="changeB">改变B</el-button>
</section>
.......
export default {
name: "layout",
data(){
return {
form:{
a:''//初始化
}
}
},
methods:{
changeA(){
this.form.a = 1
},
changeB(){
//this.form.b = 'desc' //无效
this.$set(this.form,'b','desc')//动态添加
//或者 Vue.set(vm.form,'b','desc')
}
}
}
</script>
例子二:Vue.set(object,key,value)方法一次只能添加一个属性,如果需要向嵌套对象上添加多个属性,可以用Object.assign方法。object.assign方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,并返回目标对象。
vm.object = Object.assign( { } , vm.object , {a:' 1 ', b:' 2 ' }) 注:object必须是已经声明的对象
......
<section>
<p>object.assign方法</p>
<p>{{form3.f1}}</p>
<p>{{form3.f2}}</p>
<el-button @click="changeForm3">添加多个属性</el-button>
</section>
...... export default {
name: "layout",
data(){
return {
form3:{}
}
},
methods:{
changeForm3(){
this.form3 = Object.assign({},this.form3,{f1:'f1',f2:'f2'})
}
}
}
数组渲染问题
通过改动两种方式改动数组时,Vue检测不到变动:1.利用索引直接设置一个项;2.修改数组长度。
例子三:利用索引直接设置一个项,不能直接触发状态更新。
<p v-for="(item,index) in trees" @click="changeMe(index)">这个是{{item}}</p> export default {
name: "layout",
data(){
return {
trees:['a','b','c']
}
},
methods:{
changeMe(idx){
//this.trees[idx] = 'x'//无响应
this.$set(this.trees,idx,'x')//有响应
//this.trees.splice(idx,1,'x')//有响应 }
}
}
例子四:改变数组长度
<p v-for="(item,index) in trees">这个是{{item}}</p>
<el-button @click="changeLength">改变长度</el-button> export default {
name: "layout",
data(){
return {
trees:['a','b','c']
}
},
methods:{
changeLength(){
//this.trees.length = 2//无响应
this.trees.splice(2)//有响应
}
}
}
vue数据更改视图不更新问题----深入响应式原理的更多相关文章
- Vue.js 源码分析(四) 基础篇 响应式原理 data属性
官网对data属性的介绍如下: 意思就是:data保存着Vue实例里用到的数据,Vue会修改data里的每个属性的访问控制器属性,当访问每个属性时会访问对应的get方法,修改属性时会执行对应的set方 ...
- Vue.js 技术揭秘(学习) 深入响应式原理 nextTick外传
microTask mutationObserve. promise.then macroTask setImmediate. messageChannnel.setTimeout.postMess ...
- Vue的响应式原理
Vue的响应式原理 一.响应式的底层实现 1.Vue与MVVM Vue是一个 MVVM框架,其各层的对应关系如下 View层:在Vue中是绑定dom对象的HTML ViewModel层:在Vue中是实 ...
- Vue 数据响应式原理
Vue 数据响应式原理 Vue.js 的核心包括一套“响应式系统”.“响应式”,是指当数据改变后,Vue 会通知到使用该数据的代码.例如,视图渲染中使用了数据,数据改变后,视图也会自动更新. 举个简单 ...
- 一探 Vue 数据响应式原理
一探 Vue 数据响应式原理 本文写于 2020 年 8 月 5 日 相信在很多新人第一次使用 Vue 这种框架的时候,就会被其修改数据便自动更新视图的操作所震撼. Vue 的文档中也这么写道: Vu ...
- vue 数据劫持 响应式原理 Observer Dep Watcher
1.vue响应式原理流程图概览 2.具体流程 (1)vue示例初始化(源码位于instance/index.js) import { initMixin } from './init' import ...
- vue深入响应式原理
vue深入响应式原理 深入响应式原理 — Vue.jshttps://cn.vuejs.org/v2/guide/reactivity.html 注意:这里说的响应式不是bootsharp那种前端UI ...
- Vue.js学习 Item12 – 内部响应式原理探究
深入响应式原理 大部分的基础内容我们已经讲到了,现在讲点底层内容.Vue.js 最显著的一个功能是响应系统 —— 模型只是普通对象,修改它则更新视图.这让状态管理非常简单且直观,不过理解它的原理也很重 ...
- Vue.js响应式原理
写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出. 文章的原地址:answershuto/learnV ...
随机推荐
- oracle 关联更新
不多说了,我们来做实验吧. 创建如下表数据 select * from t1 ; select * from t2; 现需求:参照T2表,修改T1表,修改条件为两表的fname列内容一致. 方式1,u ...
- SpringBoot开发案例之mail中文附件名字乱码
最近在开发一个邮件发送多附件的微服务,使用的是org.springframework.mail.javamail.JavaMailSender;包下面的JavaMailSender 但是发送出来的附件 ...
- oracle学习笔记(九) SQL常用函数说明以及使用
SQL常用函数说明以及使用 以下补充以下常用的函数,更多的请看oracle函数API文档 to_char to_char(8.58,'9.99') to_char(8.50,'9.00') to_ch ...
- 基于C# WinForms窗体——飞机大战
原文:基于C# WinForms窗体——飞机大战 using System; using System.Collections.Generic; using System.ComponentModel ...
- EF中获取当前上下文的表名
EF在处理并发上并不是很好,很多时候我们需要手动写sql操作数据库.但是在基类中我们如何获取当前服务仓储操作的表呢? 使用正则是其中一种解决办法 Repository.Table是一条查询语句,通过t ...
- python基础(9):基本数据类型四(set集合)、基础数据类型补充、深浅拷贝
1. 基础数据类型补充 li = ["李嘉诚", "麻花藤", "⻩海峰", "刘嘉玲"] s = "_&qu ...
- Python 内置函数补充匿名函数
Python3 匿名函数 定义一个函数与变量的定义非常相似,对于有名函数,必须通过变量名访问 def func(x,y,z=1): return x+y+z print(func(1,2,3)) 匿名 ...
- hibernate关联关系(多对多)
数据库的多对多数据库中不能直接映射多对多 处理:创建一个桥接表(中间表),将一个多对多关系转换成两个一对多 注:数据库多表联接查询 永远就是二个表的联接查询 注2:交叉连接 注3:外连接:left(左 ...
- Java生鲜电商平台-电商会员体系系统的架构设计与源码解析
Java生鲜电商平台-电商会员体系系统的架构设计与源码解析 说明:Java生鲜电商平台中会员体系作为电商平台的基础设施,重要性不容忽视.我去年整理过生鲜电商中的会员系统,但是比较粗,现在做一个最好的整 ...
- awk 输出前 N 列的最简单方法
最近遇到一种场景,需要输出一个文本信息的前 N 列. 众所周知 cut 可以指定分隔符并指定列的范围,如 cut -d' ' -f-4 就是以空格为分隔符输出前 4 列.但是 cut 的分隔符只能是一 ...