可以先从简版的vue开始,逐步过渡到实际源码。
- Roolup 和源码相同配置,基本目录结构
- Vue 数据响应式原理、渐进处理
- watch和computed
- Vue 模板编译
- diff
项目基本配置
vue使用 roolup打包
npm install @babel/preset-env @babel/core rollup rollup-plugin-babel rollup-plugin-serve cross-env -D
配置文件 rollup.config.js
import babel from 'rollup-plugin-babel';import serve from 'rollup-plugin-serve';export default {input: './src/index.js',output: {format: 'umd', // 模块化类型file: 'dist/umd/vue.js',name: 'Vue', // 打包后的全局变量的名字sourcemap: true},plugins: [babel({exclude: 'node_modules/**'}),process.env.ENV === 'development'?serve({open: true,openPage: '/public/index.html',port: 3000,contentBase: ''}):null]}
babel配置文件 .babelrc
{"presets": ["@babel/preset-env"]}
项目启动命令
"scripts": {"build:dev": "rollup -c","serve": "cross-env ENV=development rollup -c -w"}
Vue基本封装思路
使用 class Vue 会让方法无法被分割,这里采用 function Vue(){} 原型方案,我们可以对 Vue.prototype.xx 进行文件分割。
初始化部分 设置为 initMixin() ,这样代码的风格:
import {initMixin} from './init';function Vue(options) {this._init(options);}initMixin(Vue); // 给原型上新增_init方法export default Vue;
其中 init 的具体代码:
import {initState} from './state';export function initMixin(Vue){Vue.prototype._init = function (options) {const vm = this;vm.$options = options// 初始化状态initState(vm)}}
后续 initState 时候再去进行 prop method data compouted watch 的初始化,这样代码读起来更清晰,专注。
数据响应式
https://www.yuque.com/xinbao37/vue-source/vue2-reactive
Watcher和Computed
https://www.yuque.com/xinbao37/vue-source/vue2-watch-computed
模板编译
https://www.yuque.com/xinbao37/vue-source/template-compiler
