初始化 
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>

vue 源码分析的更多相关文章

  1. 前端Vue 源码分析-逻辑层

    Vue 源码分析-逻辑层 预期的效果: 监听input的输入,input在输入的时候,会触发 watch与computed函数,并且会更新原始的input的数值.所以直接跟input相关的处理就有3处 ...

  2. [Vue源码分析] v-model实现原理

    最近小组有个关于vue源码分析的分享会,提前准备一下… 前言:我们都知道使用v-model可以实现数据的双向绑定,及实现数据的变化驱动dom的更新,dom的更新影响数据的变化.那么v-model是怎么 ...

  3. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  4. Vue源码分析(一) : new Vue() 做了什么

    Vue源码分析(一) : new Vue() 做了什么 author: @TiffanysBear 在了解new Vue做了什么之前,我们先对Vue源码做一些基础的了解,如果你已经对基础的源码目录设计 ...

  5. vue 快速入门 系列 —— 侦测数据的变化 - [vue 源码分析]

    其他章节请看: vue 快速入门 系列 侦测数据的变化 - [vue 源码分析] 本文将 vue 中与数据侦测相关的源码摘了出来,配合上文(侦测数据的变化 - [基本实现]) 一起来分析一下 vue ...

  6. vue源码分析—Vue.js 源码目录设计

    Vue.js 的源码都在 src 目录下,其目录结构如下 src ├── compiler # 编译相关 ├── core # 核心代码 ├── platforms # 不同平台的支持 ├── ser ...

  7. vue源码分析—Vue.js 源码构建

    Vue.js 源码是基于 Rollup 构建的,它的构建相关配置都在 scripts 目录下.(Rollup 中文网和英文网) 构建脚本 通常一个基于 NPM 托管的项目都会有一个 package.j ...

  8. vue源码分析—认识 Flow

    认识 Flow Flow 是 facebook 出品的 JavaScript 静态类型检查⼯具.Vue.js 的源码利⽤了 Flow 做了静态类型检查, 所以了解 Flow 有助于我们阅读源码 Flo ...

  9. Vue 源码分析—— 目录结构

    一,Vue.js 的源码都是在src 目录下,其目录结构如下. 1.compiler 目录包含Vue.js 所有编译相关的代码.它包括把所有模板解析成ast 语法树, ast 语法树优化等功能. 2. ...

  10. vue源码分析之new Vue过程

    实例化构造函数 从这里可以看出new Vue实际上是使vue构造函数实例化,然后调用_init方法 _init方法,该方法在 src/core/instance/init.js 中定义 Vue.pro ...

随机推荐

  1. maven 配置私服 连接

    两种方法: 1.在单个项目的pom.xml中使用 私服的连接地址,这样只对该项目起作用. 2.在maven的setting.xml配置中添加私服的连接地址.这样对所有项目起作用. 本文章只演示第二种方 ...

  2. android sp文件一个键值保存多条信息

    之前碰到过这样的问题,sp文件只能够append,或者清空.其实一个键值,通过,分割,或者替代可以实现多条信息的存储.下面是一个举例: package com.ctbri.weather.utils; ...

  3. Mybaits查询返回值是List类型的

    查询返回值是list类型的 1 首先在接口中写方法 public interface EmployeeMapper { public List<Employee> getEmpsByLas ...

  4. maven依赖传递和排除依赖冲突

    1 依赖的传递 假如 A项目 依赖 a.jar 1.0.1,b.jar 1.0.1,没有直接依赖c.jar 1.0.1,但是b.jar 1.0.1依赖了c.jar 1.0.1,可以说A项目间接依赖了c ...

  5. 【C++进阶】 to_string,stringstream

    to_string函数主要进行以下一些参数转换为string stringstream,位于<sstream>库中 https://blog.csdn.net/jllongbell/art ...

  6. python语言优势

    与Java等语言比较起来,最大优点是语法很简洁,很多功能像octave和matlab,能够对数组或矩阵进行高效处理. 比如一个数组求和,这里只要一句话sum(a),Java等语言就需要循环.还有矩阵的 ...

  7. ArcCatalog连接远程ArcGIS Server服务器

    注意:本地机器登陆的用户名和密码必须与ArcGIS Server服务器上的用户名和密码完全一致,并加入到agsadmin和agsuser组中.重启电脑.   (其实就是在自己的电脑上建立一个用户名,这 ...

  8. Python Module_openpyxl_styles 样式处理

    目录 目录 前言 系统软件 Working with styles Styles can be applied to the following aspects Styles模块 Copying st ...

  9. H5如何测试?

    它跟安卓APP与IOS APP有什么样的区别呢?★ 我们以往的APP是使用原生系统内核的,相当于直接在系统上操作,是我们传统意义上的软件,更加稳定 ★ H5的APP先得调用系统的浏览器内核,相当于是在 ...

  10. shell基础命令

    什么是脚本? 脚本简单地说就是一条条的文字命令(一些指令的堆积),这些文字命令是可以看到的(如可以用记事本打开查看.编辑). 常见的脚本: JavaScript(JS,前端),VBScript, AS ...