Vue 原理学习总结

Vue 如何实现响应式原理

Vue 将MVVM做为数据绑定的入口。
几个Vue源码关键核心概念:

  • Observer 数据的观察者,监听自己的model数据变化
  • Complie 解析编译模板指令
  • Watcher 数据订阅者,是Observer 与 Complie 之间通信的桥梁(用来订阅变化时执行相应操作的)。

进一步分析
双向绑定流程:

Observer --data update–> Dep --notify通知–> Watcher --update–> View
-------------------------------Dep----<–subscribe订阅—Watcher--------------------
在这里插入图片描述

Dep 是Observer 和 Watcher 之间的桥梁, Observer 观察到数据变化则告知 Dep, Dep会向收集到的Watcher 订阅者们(Dep 内会有一个数组用来收集依赖的订阅者),发送数据改变的通知,收到通知后进行View更新。*

一个简单的实现Demo实例:

class Vue{
   constructor (options) {
       this.$options = options
       this._data = options.data
       observer(options.data, this._update.bind(this))
       this._update()
   }
   _update() {
       this.$options.render()
    }
}
function observer(obj, cb) {
   Object.keys(obj).forEach(key => {
       defineReactive(obj, key, obj[key], cb)
   })
}
function defineReactive(obj, key, val, cb) {
   Object.defineProperty(obj, key, {
       enumerable: true,
       configurable: true,
       get: ()=> {
           console.log(`访问了: ${key}`)
           return val
       },
       set: newVal => {
           if(newValue === val) 
              return
           console.log(`设置了: ${key}`)
           val = newVal
           cb()
       }
   })
}

var vm = new Vue({
   el: '#app',
   data: {
       text: "vm data attr"
   },
   render(){
      console.log('runder function run.....')
   }
})

vue 如何通过Dep 避免渲染无关值更新导致的渲染问题:

vue 会在Render 函数中,收集本次渲染相关的值,并处理相关值为响应式。 所以,与渲染无关的值,并不会触发get, 也就不会在依赖收集器中添加到监听。 所以渲染无关的值,即使调用set赋值, notify中的subs也是空的。 因此不会触发渲染。
注: 这里“依赖收集器” 并非官网定义的名词。 只是个人理解起名。

总结:

  • vuedata 初始化为一个Observer 并将对象中的每个值,重写其get, set, data中的每个key, 都有一个独立的依赖收集器;
  • get中,向依赖收集器添加了监听;
  • 在mount 时, 实例了一个Watcher, 将收集器的目标指向了当前Watcher
  • data值发生变更时,触发set, 触发了依赖收集器中的所有监听的更新, 从而触发Watcher.update
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值