Vue2 双向数据绑定(五)-- MyVue构造函数

发布日期:2019-06-12 阅读量:402

1. 实现

    // MyVue.js
    /**
     * MyVue 构造函数
     * @param { object } options 配置项
     */
    function MyVue(options) {
        this.vm = this; // 虚拟dom
        this.data = options.data; // 数据
        var self = this;
        Object.keys(this.data).forEach(function(key){ // 遍历数据项
            self.proxyKeys(key); // 下面我们会定义一个代理函数进行数据代理
        });
        observe(options.data); // 响应式数据
        new Compile(options.el, this.vm); // 将数据加载到试图
        return this;
    }
    
    /**
     * 数据代理
     */
     MyVue.prototype = {
         proxyKeys: function(key) { // 添加原型方法进行数据代理,使MyVue.data[key] 可以直接使用 MyVue[key]进行访问
             var self = this;
             Object.defineProperty(this, key, { //配置描述符
                 enumerable: true, //可枚举
                 configurable: true, // 能否通过 delete 删除属性、能否修改属性的特性,或者将属性修改为访问器属性
                 get: function proxyGetter() { // getter函数
                     return self.data[key];
                 },
                 set: function proxySetter(val) { // setter函数
                     self.data[key] = val;
                 }
             })
         }
     }

2. 测试

    // 同级目录新建index.html文件 引入 MyVue.js
<body>
    <div id="app">
        <h1>{{title}}</h1>
        <h2>{{name}}</h2>
        <h3>{{content}}</h3>
    </div>
</body>

<script src="Dep.js"></script>
<script src="observer.js"></script>

<script src="Watcher.js"></script>
<script src="Compile.js"></script>
<script src="SelfVue.js"></script>
<script>
    var ele = document.querySelector('#name');
    var myVue = new MyVue({
        el:'#app',
        data:{
            title:'title-a',
            name:'name-a',
            content:'content-a'
        }
    })
    window.setTimeout(function() {
        myVue.title = 'title-b';
        myVue.name = 'name-b';
        myVue.content = 'content-b'
    },2000);

</script>