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 ...
随机推荐
- hyper-v Centos7 网卡配置无效
环境: Win 10 Hyper-v 安装虚拟机:Centos 7 遇到问题: 网络配置无效,使用命令“ip addr” 网卡没有出现在列表中,显示了一个奇怪的网卡名字如“enp0s010f”,配置文 ...
- vue-商品管理案例改进
案例改进 vue-resource全局配置: Vue.http.options.root = 'http://vue.studyit.io/'; 全局启用 emulateJSON 选项 Vue.htt ...
- Wireshark使用技巧:提取VOIP通话中的音频流
"Wireshark的RTP流分析功能实战." 在VOIP协议的分析过程中,常常会遇到一些标准协议承载的语音传输,如以SIP.H.323为控制协商协议,RTP为语音数据协议的VOI ...
- 干货,Wireshark使用技巧-过滤规则
- 过滤规则使用 在抓取报文时使用的规则,称为过滤规则,Wireshark底层是基于Winpcap,因此过滤规则是Winpcap定义的规则,设置过滤规则后,抓到的报文仅包含符合规则的报文,其它报文则被 ...
- 一文解读PV/UV/VV/IP (转)
什么是PV? PV即Page View,网站浏览量,指页面浏览的次数,用以衡量网站用户访问的网页数量.用户每次打开一个页面便记录1次PV,多次打开同一页面则浏览量累计.一般来说,PV与来访者的数量成正 ...
- ubuntu 查看软件包中的内容 (已经安装)
在 使用 apt 进行安装软件的时候,我们要经常判断,软件安装了什么和安装到什么地方.这时候 我们要使用 dpkg -L 命令来进行查看: 同样 在 fedora 上可以使用 rpm -ql iper ...
- Python—网络抓包与解包(pcap、dpkt)
pcap安装 [root@localhost ~]# pip install pypcap 抓包与解包 # -*- coding:utf-8 -*- import pcap, dpkt import ...
- [PHP] vscode配置SFTP扩展同步文件
在我们的项目开发过程中,经常有一种模式,有一台linux的开发机作为我们的测试机器,上面安装了ftp服务.我们在windows系统的本地机器使用IDE编写代码,自动或者保存时同步上传到测试机下,这样就 ...
- CodeForces - 1228D (暴力+思维+乱搞)
题意 https://vjudge.net/problem/CodeForces-1228D 有一个n个顶点m条边的无向图,在一对顶点中最多有一条边. 设v1,v2是两个不相交的非空子集,当满足以下条 ...
- 源码编译Kubeadm二进制文件
kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,伴随Kubernetes每个版本的发布都会同步更新,kubeadm会对集群配置方面的一些实践做调整,通过实验k ...