vue的双向绑定原理_vue2双向绑定原理

vue的双向绑定原理_vue2双向绑定原理1、背景今天要讲的内容是Web前端框架vue.js中的一个细节,注意是细节哦,稍不留神就掉坑里了。由于这两天在公司开发前端vue页面,踩到了一个坑,这个坑不大不小的,但是对于我这种除非公司需要,否则不会主动学习前端技术的后端开发者来说,这个坑困扰了我半天时间。无论怎么修改代码,还是实现不了效果,归根结底还是没有找到问题的点所在。凡事都有好的一面,今天上午脑子就开了光,思路比昨天下午清晰多了,顺着思路,我终于发现了问题的点所在,然后百度一搜,果然是这样,嗨!于是我决定总结一番!大家都知道,vu

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

1、背景

今天要讲的内容是Web前端框架vue.js中的一个细节,注意是细节哦,稍不留神就掉坑里了。

由于这两天在公司开发前端vue页面,踩到了一个坑,这个坑不大不小的,但是对于我这种除非公司需要,否则不会主动学习前端技术的后端开发者来说,这个坑困扰了我半天时间。无论怎么修改代码,还是实现不了效果,归根结底还是没有找到问题的点所在。

凡事都有好的一面,今天上午脑子就开了光,思路比昨天下午清晰多了,顺着思路,我终于发现了问题的点所在,然后百度一搜,果然是这样,嗨!于是我决定总结一番!

大家都知道,vue的核心特性是数据动态双向绑定,但是数据绑定背后的原理是什么呢,这个有必要了解一番。

2、VUE核心原理

当你将一个普通的js对象作为vue的数据时,vue会遍历该对象的所有属性,并通过Object.defineProperty()方法将这些属性全部转化为getter/setter。defineProperty()是js标准内置对象Object的一个方法,用于直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。这句话有点抽象,先来看一下该方法的语法。

2.1、Object.defineProperty()

Object.defineProperty(obj, prop, descriptor)
  • obj:对象

  • prop:对象的某个属性

  • descriptor:属性描述符

属性描述符有以下可选方案:

  • configurable:当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除,默认为 false

  • enumerable:当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中,默认为 false

  • value:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等),默认为 undefined

  • writable:当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变,默认为 false

  • get:属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值,默认为 undefined

  • set:属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象,默认为 undefined

通过上面的介绍,我们了解到了Object.defineProperty()方法可以这么用。

Object.defineProperty(user, "name", {get() { return value; },  set(newValue) { value= newValue; },  configurable : true,  value: "小明"  });

关于Object.defineProperty()更深层次的介绍请戳这里 Object.defineProperty() – JavaScript | MDN

2.2、组件渲染

Object.defineProperty()说完了,接下来继续聊聊vue的响应式原理。前面说到Object.defineProperty()方法将这些属性全部转化为getter/setter,而这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。

每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。这种关系可以用下图表示。

vue的双向绑定原理_vue2双向绑定原理

3、脱坑关键

说完了上面的vue核心原理,下面聊聊标题:vue不能动态监测对象属性的问题!

由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。一听到这,是不是觉得没法玩了?不要慌,问题总是有解决办法滴!下面就聊聊解决办法!

3.1、对于对象

Vue 无法检测 property的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在对象上存在才能让 Vue 将它转换为响应式的。例如:

对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式 property。例如:

var vm = new Vue({
  data:{
    a:1
  }
});
//vm.a是响应式的

vm.b = 2
//vm.b是非响应式的

对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式 property。例如:

Vue.set(vm.someObject, 'b', 2)

您还可以使用 vm.$set 实例方法,这是全局 Vue.set 方法的别名:

this.$set(this.someObject,'b',2)

3.2、对于数组

Vue 不能检测以下数组的变动:

  • 当你利用索引直接设置一个数组项时,例如:vm.array[index] = newValue

  • 当你修改数组的长度时,例如:vm.array.length = newLength

举个栗子:

var vm = new Vue({

  data: {
    array: ['a', 'b', 'c']
  }
});

vm.array[1] = 'x' //不是响应性的
vm.array.length = 2 //不是响应性的

为了解决第一类问题,以下三种方式都可以实现和 vm.array[index] = newValue 相同的效果,同时也将在响应式系统内触发状态更新:

// Vue.set
Vue.set(vm.array, index, newValue)

// Array.prototype.splice
vm.array.splice(index, 1, newValue)

//vm.$set
vm.$set(vm.array, index, newValue)

为了解决第二类问题,你可以使用 splice:

vm.array.splice(newLength)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/180726.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mac idea2022.01永久激活【2021免费激活】

    (mac idea2022.01永久激活)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月30日
    1.3K
  • ubuntu18修改ssh端口(ssh 22端口拒绝)

    https://blog.csdn.net/md521/article/details/52597398

    2022年4月13日
    58
  • combox数据绑定_props父子传值

    combox数据绑定_props父子传值combox可以接受dataset对象作为其数据源。所以,combox.datasource=dataset1;是可以的。 但是在WPF中,combox不支持DataSource方法。可以通过下面的方法添加数据。foreach(datarowdrindataset1.tables[0].rows){combox1.items.add(dr.items[0

    2025年6月21日
    7
  • javascript图片展示墙特效

    查看效果:http://hovertree.com/code/javascript/pwl4bhoi.htm代码如下:1<!DOCTYPEhtml>2<html>

    2021年12月21日
    60
  • js清除浏览器缓存的几种方法(项目总结)「建议收藏」

    js清除浏览器缓存的几种方法(项目总结)「建议收藏」以前很少关注这方面的问题,直达我们的技术经理找我们说要换框架,为什么换框架呢,因为缓存的问题,原来的项目是用版本号作为刷新的依据的。因为微信公众号上有这样一个机制,使用版本好的话,有时做不到及时刷新,所以就用了vue.js,因为它有这样的功能就是如果某个文件里面的数据改变了,那么vue.js就会把这个文件的名字也相应的改掉,所以缓存里面的东西就用不了了,这样就做到了及时刷新,向后台请求数据。…

    2022年7月18日
    39
  • painless数字类型转换_笔记四十五: Ingest Pipeline 与 Painless Script

    需求:修复与增强写入的数据Tags字段中,逗号分割的文本应该是数组,而不是一个字符串需求:后期需要对Tags进行Aggregation统计IngestNodeElasticsearch5.0后,引入的一种新的节点类型。默认配置下,每个节点都是IngestNode具有预处理数据的能力,可拦截Index或者BulckAPI的请求对数据进行转换,并重新返回给Index和…

    2022年4月8日
    60

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号