vue原理之observer

17 篇文章 0 订阅
16 篇文章 0 订阅

上节课我们讲了vue五种类型中的vue 实现data响应
这节课我们讲第二中类型observer

Observer

功能
负责把 data 选项中的属性转换成响应式数据
data 中的某个属性也是对象,把该属性转换成响应式数据
数据变化发送通知

在这里插入图片描述

具体代码实现如下

class Observer {
        constructor(data) {
            this.walk(data)
        }
        // 1. 判断数据是否是对象,如果不是对象返回 
        // 2. 如果是对象,遍历对象的所有属性,设置为 getter/setter
        walk(data) {
            if (!data || typeof data != 'object') {
                return
            }
            Object.keys(data).forEach(key => {
                this.defineReactive(data, key, data[key])
            })
        }
        //  定义响应式成员  即对data总的数据实现setter和getter
        defineReactive(data, key, val) {
            const that = this
            // 如果 val 是对象,继续设置它下面的成员为响应式数据 
            this.walk(val)
            Object.defineProperty(data, key, {
                enumerable: true,
                configurable: true,
                get() {
                    return val;
                },
                set(newValue) {
                    if (val === newValue) {
                        return
                    }
                    // 如果 newValue 是对象,设置 newValue 的成员为响应式 
                    that.walk(newValue)//这里不用this  因为在set方法中 在function的内部 会开启新的作用域 此时的this执行data对象   
                    val = newValue;
                }
            })
        }
    }

整体代码如下:

// 具体实现步骤
// 1: 通过属性  保存选项的数据
// 2: 把data中的成员 转换为getter和setter  注入到vue实例中 方便使用
// 3:调用observer对象 监听数据变化
// 4:调用compiler 解析指令和插值表达式
class Vue {
    constructor(options) {
        // 通过属性  保存选项的数据
        this.$options = options || {};//如果我们在调用vue构造函数的时候 没有传入参数 我们初始化一个空对象
        this.$data = options.data || {};
        this.$el = typeof options.el === 'string' ? document.querySelector(options.el) : options.el;//如果我们是传入的选择器 则将选择器转换为dom对象
        // 把data中的成员 转换为getter和setter  注入到vue实例中 方便使用
        this._proxyData(this.$data)
        // 调用observer对象 监听数据变化
        new Observer(this.$data)
        // 调用compiler 解析指令和插值表达式 
    }
    _proxyData(data) {//vue传过来的参数 转换为getter和setter
        // 遍历data的所有属性
        Object.keys(data).forEach(key => {
            Object.defineProperty(this, key, {
                // 可遍历 可枚举
                enumerable: true,
                configurable: true,
                get() {
                    return data[key]
                },
                set(newValue) {
                    if (newValue === data[key]) {
                        return
                    } else {
                        data[key] = newValue;
                    }
                }
            })
        })
        // 把data中的属性 注入到vue实例中

    }
}
class Observer {
    constructor(data) {
        this.walk(data)
    }
    // 1. 判断数据是否是对象,如果不是对象返回 
    // 2. 如果是对象,遍历对象的所有属性,设置为 getter/setter
    walk(data) {
        if (!data || typeof data != 'object') {
            return
        }
        Object.keys(data).forEach(key => {
            this.defineReactive(data, key, data[key])
        })
    }
    //  定义响应式成员  即对data总的数据实现setter和getter
    defineReactive(data, key, val) {
        const that = this
        // 如果 val 是对象,继续设置它下面的成员为响应式数据 
        this.walk(val)
        Object.defineProperty(data, key, {
            enumerable: true,
            configurable: true,
            get() {
                return val;
            },
            set(newValue) {
                if (val === newValue) {
                    return
                }
                // 如果 newValue 是对象,设置 newValue 的成员为响应式 
                that.walk(newValue)//这里不用this  因为在set方法中 在function的内部 会开启新的作用域 此时的this执行data对象   
                val = newValue;
            }
        })
    }
}

let vm = new Vue({
    el: '#app',
    data: {
        msg: 'hello',
        count: 123,
        person: {
            name: 'zs'
        }
    }
})
 vm.msg={'sex':'ada'}

上一篇:vue原理代码的基本实现
下一篇:详解vue原理中的编译compiler

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值