vue响应式原理实现_响应式网页设计代码

Vue (6) 2024-07-29 14:23

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
vue响应式原理实现_响应式网页设计代码,希望能够帮助你!!!。

Vue响应式原理介绍

监听Vue实例中的data选项,我们以下用一个普通的js对象模拟data,用Object.defineProperty进行定义属性值的getter和setter方法。当data选择项中的key进行获取和修改时,Vue内部会调用相应的方法。
vue响应式原理实现_响应式网页设计代码_https://bianchenghao6.com/blog_Vue_第1张
主要考虑以下两点:

  1. data中数据修改时,Vue内部时如何监听到message数据的改变
    Object.defineProperty
  2. 当数据发送改变,Vue是如何知道需要那些模板中用到的key进行页面刷新
    发布者订阅者模式
    注:发布者为dep,订阅者为watcher
    每个data中的属性都会对应一个发布者(dep)对象
响应式原理实现代码: class Vue{ 
    constructor(options){ 
    //1.保存数据 this.$options = options; this.$data = options.data; this.$el = options.el; //2.将data添加到响应式系统中 new Observer(this.$data) //3.处理el new Complier(this.$el, this) //4.代理this.$data的数据 Object.keys(this.$data).forEach(key=>{ 
    this._proxy(key) }) } _proxy(key){ 
    Object.defineProperty(this, key, { 
    configurable: true, enumerable: true, set(newValue){ 
    this.$data[key] = newValue }, get(){ 
    return this.$data[key] } }) } } //将data中的属性加入到相应模式中 class Observer{ 
    constructor(data){ 
    this.data = data Object.keys(data).forEach(key=>{ 
    this.defineReactive(this.data, key, data[key]) }) } defineReactive(data, key, val){ 
    //一个属性(key)对应一个发布者对象 const dep = new Dep() Object.defineProperty(data, key, { 
    enumerable: true, configurable: true, //将订阅者加入到subs数组中 get(){ 
    if(Dep.target){ 
    dep.addSub(Dep.target) } return val }, //数据修改时,通知订阅者 set(newValue){ 
    if(newValue === val) return val = newValue dep.notify() } }) } } //定义发布者:添加、通知订阅者 class Dep{ 
    constructor(){ 
    this.subs = [] } // addSub(sub){ 
    this.subs.push(sub) } //订阅者更新时,调用watcher中的update()修改视图中的节点值 notify(){ 
    this.subs.forEach(sub=>{ 
    sub.update() }) } } //订阅者 class Watcher{ 
    constructor(node, name, vm){ 
    this.node = node; this.name = name; this.vm = vm; Dep.target = this; this.update() Dep.target = null } update(){ 
    this.node.nodeValue = this.vm[this.name] } } //template编译 const reg = /\{\{(.+)\}\}/ class Complier{ 
    constructor(el, vm){ 
    this.el = document.querySelector(el) this.vm = vm this.frag = this._createFragment() this.el.appendChild(this.frag) } _createFragment(){ 
    const frag = document.createDocumentFragment() let child; while(child = this.el.firstChild){ 
    this._compile(child) frag.appendChild(child) } return frag } _compile(node){ 
    if(node.nodeType === 1){ 
    const attrs = node.attributes if(attrs.hasOwnProperty('v-model')){ 
    const name = attrs['v-model'].nodeValue node.addEventListener('input',e=>{ 
    this.vm[name] = e.target.value }) } } //节点编译时,name为订阅者名字,创建对应的watcher实例 if(node.nodeType === 3){ 
    if(reg.test(node.nodeValue)){ 
    const name = RegExp.$1.trim() new Watcher(node, name, this.vm) } } } } 

如果感觉文章对你有帮助,别忘了点个赞哦!!!!!!!!!

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

发表回复