Vue 的数据绑定

不念不忘少年蓝@ 2021-09-03 04:10 526阅读 0赞

vue的数据双向绑定是通过数据劫持和发布-订阅者功能来实现的

实现步骤:

1.实现一个监听者Oberver来劫持并监听所有的属性,一旦有属性发生变化就通知订阅者

2.实现一个订阅者watcher来接受属性变化的通知并执行相应的方法,从而更新视图

3.实现一个解析器compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相对应的订阅者

2、vue是通过Object.defineProperty()来实现数据劫持的。

实现mvvm主要包含两个方面,数据变化更新视图,视图变化更新数据。

关键点在于 data 如何更新view

因为 view 更新 data 其实可以通过事件监听即可,比如 input 标签监听 ‘input’ 事件就可以实现了。

而数据更新视图的重点是如何知道数据变了,只要知道数据变了,那么接下去的事都好处理。如何知道数据变了,就是通过Object.defineProperty( )对属性设置一个set函数,当数据改变了就会来触发这个函数,所以我们只要将一些需要更新的方法放在这里面就可以实现data更新view了。

当 data 有变化的时候,通过ES5 中的 Object.defineProperty() 方法中的 set 方法劫持属性值的设置操作和 get 方法劫持属性值的获取操作,实现数据变化视图 view 跟着变化;

而视图 view 变化数据跟着变化则是通过底层的 input 事件来进行 data 的响应更改

Object.defineProperty(参数1,参数2,参数3) 返回值为该对象obj

参数1为该对象(obj),参数2为要定义或修改的对象的属性名,参数3为属性描述符,属性描述符是一个对象,主要有两种形式:数据描述符和存取描述符。这两种对象只能选择一种使用,不能混合使用。而get和set属于存取描述符对象的属性。

这个方法会直接在一个对象上定义一个新属性或者修改对象上的现有属性,并返回该对象

下面代码使用vue中的方法实现的数据劫持:

  1. <div>
  2. <input type="text" placeholder="请输入内容" />
  3. <h1></h1>
  4. </div>
  5. <script>
  6. var inputEle = document.querySelector('input')
  7. var h1Ele = document.querySelector('h1')
  8. // 设置默认值
  9. var obj = {
  10. msg: '默认值'
  11. }
  12. inputEle.value = obj.msg
  13. h1Ele.innerHTML = obj.msg
  14. // 实现视图变化数据跟着变化
  15. inputEle.oninput = function() {
  16. obj.msg = inputEle.value
  17. }
  18. // 直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
  19. // 实现数据变化视图跟着变化
  20. let temp = obj.msg
  21. Object.defineProperty(obj, 'msg', {
  22. get() {
  23. // get方法会劫持msg这个属性的获取操作
  24. return temp
  25. },
  26. set(value) {
  27. // set方法会劫持msg这个属性的设置操作
  28. temp = value
  29. h1Ele.innerHTML = temp
  30. inputEle.value = temp
  31. },
  32. enumerable: true,
  33. configurable: true
  34. })
  35. </script>

vue (defineProperty)实现拦截
进行数据劫持
++Object.defineProperty++ 拦截
1、首先会在一个函数内通过 typeof 去判断传进来的是不是一个对象,如果是的话先通过object.keys转一下然后去遍历,拿到 key

  1. <script>
  2. function observer (data) {
  3. // 判断如果没有传值,或者传的值不是一个对象,就直接return
  4. if(!data || typeof data !== 'object') {
  5. return;
  6. }
  7. Object.keys(data).forEach(item => {
  8. observerProperty (data, item, data[item])
  9. })
  10. }
  11. function observerProperty (target, key, value) {
  12. observer (value)
  13. Object.defineProperty(target, key, {
  14. get () {
  15. return value;
  16. }
  17. set (val) {
  18. value = val
  19. }
  20. }
  21. }
  22. // 这样就会对obj进行一个劫持,一旦改变obj内的属性,就返回相对应的数据,比如对obj的name进行了改变,observer()函数可能会返回一句obj的name已经改变为...
  23. // observer (obj)
  24. let obj = {
  25. id:1,
  26. name:zhngsan,
  27. age: 20
  28. }
  29. </script>

发表评论

表情:
评论列表 (有 0 条评论,526人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Vue数据

    > 单向绑定模式  v-bind:  之前说的指令语法只是说了一个 v-bind:及其简写模式 :,但是 v-bind:是一个单向绑定模式,只能将data中的数据解析到页面上

    相关 Vue 数据

    数据绑定就是将页面的数据和视图关联起来,当我们的数据变化的时候,视图可以自动更新。 插值 文本插值是数据绑定的最基本形式,使用双花括号“\{ \{ \}\}”,这种语法在

    相关 Vue 数据

    > vue的数据双向绑定是通过数据劫持和发布-订阅者功能来实现的 实现步骤: 1.实现一个监听者Oberver来劫持并监听所有的属性,一旦有属性发生变化就通知订阅者 2.