mini-vue实现之Vue类实现

195 阅读1分钟

mini-vue代码已放到github上。 我们现在开始实现一个简版的vue,首先实现的是Vue类。

vue类的功能

  • 负责接收初始化的参数
  • 负责把data中的属性注入到Vue实例, 转换成getter和setter
  • 负责调用observer监听data中所有属性的变化
  • 负责调用compiler解析指令/差值表达式

这一节我们主要来实现前两个功能。

class Vue {
    constructor(options) {
        this.$options = options || {};
        this.$data = options.data || {};
        this.$el = typeof options.el === 'string' ? document.querySelector(options.el) : options.el;
        
        this._proxyData(this.$data)
    }
    
    _proxyData(data) {
        Object.keys(data).forEach(key => {
            Object.defineProperty(this, key, {
                enumerable: true,
                configurable: true,
                get() {
                    return data[key]
                },
                set(newValue) {
                    if(data[key] === newValue) {
                        return
                    }
                    data[key] = newValue
                }
            })
        })
    }
}

上述代码的作用就是将初始化Vue实例的时候,将options传入并挂载到vue实例上,同时为data中的恶属性添加getter和setter方法

我们来新建一个html文件测试下

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <div id="app"></div>
        <script src="./js/vue.js"></script>
        <script>
            let vm = new Vue({
                el: '#app',
                data: {
                    msg: 'hello',
                    count: 1,
                },
            });
            console.log(vm);
        </script>
    </body>
</html>

我们来看下控制台打印

WechatIMG379.png

可以看到现在在初始化vue实例的时候我们将options、data、el等属性挂载到了vue实例上。并且为data中的属性添加上了getter和setter方法。至此我们第一步已经完成。