SOURCE

console 命令行工具 X clear

                    
>
console
// 如何实现简单版本的vue响应式原理
/*
    响应式原理:从改变一个数据到发生改变的过程
    
                       get部分收集依赖
                              ↓                      
    数据改变触发set  →  set部分触发notify   →   更改对应的虚拟dom   →   更新render
*/
 
/*
     1.构造函数(实现数据的双向绑定)
*/

/*
    vue函数
    vue是function,function的原型prototype是Function,
    Function的原型prototype是Object

    这里的Vue是构造函数

    要点:实现上面的4个步骤
*/
function Vue() {
    //  定义数据
    this.$data = { a : 1 }
    //  获取id="app"的dom元素(真实dom)
    this.el = document.getElementById("app")
    //  定义虚拟dom
    this.virtualDom = ""
    //  监听数据变化
    this.observer(this.$data);
    //  重新渲染
    this.render()

    // 构造函数,隐式创建,隐式子返回
    //  var this = {}
    //  return this 
    console.log(this)
}
/*
    要点:vue原型prototype设置observer函数,监听数据变化(连接virtualDom,render,el,$data)
            +注册getter,setter
        实现12步骤,数据改变触发set+set部分触发notify(get部分收集依赖)
*/
Vue.prototype.observer = function (obj) {
    var self = this;
    // 都是更改this.$data,所以代理后的数据改变后也是复制给this.$data,实现响应式更新
    this.$data = new Proxy(this.$data, {
        // 参数这里看现代js教程的proxy and reflect
        get: function (target,key) {
            return target[key]
        },
        // 第三个参数是新值newValue
        set:function (target,key,newValue) {
            target[key] = newValue
            self.render()
        }
    })

    console.log(this)   
}
/*
     要点:实现34步骤,更改对应的虚拟dom+重新render
*/
Vue.prototype.render  = function () {
    //  3.更改对应的虚拟dom
    this.virtualDom = 'i am ' + this.$data.a
    //  4.重新render (把新的虚拟dom赋值到真实dom)
    this.el.innerHTML = this.virtualDom

    console.log(this)  //   
}


/*
      2.创建实例,使用变时器setTImeout呈现效果(数据2秒后自动改变)
*/
var vm = new Vue()

setTimeout(function () {
    console.log("changes")
	console.log(vm.$data)	//	Object {a:1}
    //  1.  数据改变触发set
    vm.$data.a = 444
},2000)

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div id="app">
        <!-- 一定要改设置:no Wrap in <body> -->
    </div>
</body>    
</html>