vue 源码分析

初始化 
Data,props,event监听
beforCreated,Created
挂载
执行编译,首次渲染、创建和追加过程
编译
编译模块分为三个阶段: parse optimize generate
数据响应式
渲染函数执行时会触发 getter 进行依赖收集,将来数据变化时会触发 setter 进行更新
虚拟 dom
Vue 工作机制
// dom
<div    style = "color:red" @click = "xx" ><a> click me </a>
</div>
// vdom
{
tag : 'div' ,
props :{ name : ' 开课吧 ' ,
        style:{color:red},
onClick : xx }
children : [
  {
    tag : 'a' ,
    text : 'click me'
}
 ]
}
更新视图
数据修改时监听器会执行更新,通过对比新旧 vdom ,得到最小修改,就是 patch
实现自己的 Vue
简化版架构图
// 创建 kvue.js// new KVue({// data: {
//
// }// })
class KVue {
  constructor ( options ) {
// 保存选项
this . $options = options ; // 传入 data 选项
this . $data = options . data ; // 响应化 this . observe ( this . $data );
}
  observe(value) {
if (!value || typeof value !== "object") {
return ;}
// 遍历,执行数据响应式 Object . keys ( value ). forEach ( key => {
      this.defineReactive(value, key, value[key]);
});
}
defineReactive ( obj , key , val ) { // 递归
this . observe ( val );
// obj 定义属性 Object . defineProperty ( obj , key , {
get() {
return val;
},
  set ( newVal ) {
        if ( newVal === val ) {
return ;}
val = newVal ;
console . log ( `${ key } 属性更新了 ` );}
});}
}
// 创建 index.html
< script src = "kvue.js" >< /script> < script >
      const app = new KVue({
data: {
          test: "I am test",
foo: {
bar : "bar" }
}});
      app.$data.test = "hello, kaikeba!";
      app . $data . foo . bar = "oh my bar" ;
< /script>
$data 做代理 , kvue.js
observe ( value ) {
  //...
Object . keys ( value ). forEach ( key => { this . defineReactive ( value , key , value [ key ]); // 代理 data 中的属性到 vue 根上 this . proxyData ( key );
});}
// vue 根上定义属性代理 data 中的数据 proxyData ( key ) {
  Object.defineProperty(this, key, {
get() {
      return this.$data[key];
},
    set(newVal) {
this.$data[key] = newVal;
}});
}
<script>
    app.test = "hello, kaikeba!";
    app . foo . bar = "oh my bar" ;
</script>
编译 compile
class KVue {
constructor(options) {
// ...
// 新建一个 Watcher 观察者对象,这时候 Dep.target 会指向这个 Watcher 对象 new Watcher ( this , 'test' );
// 访问 get 函数,为了触发依赖收集
this . test
       new Watcher(this,'foo.bar');
       this.foo.bar
}
}
<body>
<div
id="app">
    <p>{{name}}</p>
<p
k-text="name"></p>
<p>
{{age}}</p>
<p>
      {{doubleAge}}
</p>
<input type = "text" k-model = "name" ><button @click = "changeName" > 呵呵 </button><div k-html = "html" ></div>
  </div>
<script
src='./compile.js'></script>
<script
src='./kvue.js'></script>
<script>
const kaikeba = new KVue ({
      el : '#app' ,
      data : {
name : "I am test." ,
age : 12 , html : '<button> 这是一个按钮 </button>'
      },
created(){
console . log ( ' 开始啦 ' ) setTimeout (() => {
this . name = ' 我是测试 ' }, 1500 )
}, methods :{
changeName (){
this . name = ' 哈喽,开课吧 ' this . age = 1
}}
})
  </script>
</body>

猜你喜欢

转载自www.cnblogs.com/yayaxuping/p/11800880.html