这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战
Vue2
中的响应式原理是开发者们津津乐道的一个话题,也是面试的一道高频题目,在开始之前需要先了解一下Vue
初始化的一个大致流程
Vue初始化
首先看一下我们在使用Vue
时一个最基本的使用
new Vue({
el: '#app',
data() {
return {
name: 'nordon',
age: 12
}
},
computed() {},
methods: {
},
})
当我们如上使用Vue
时,其便会进行一个初始化的过程,接下来便一起看看Vue
是如何处理的
在上篇文章中已经介绍了使用Rolleup
搭建开发环境,创建了src/index.js
文件作为入口文件,那么当使用new Vue
时会传递非常多的选项,如果都放在index.js
中处理明显是不合适的,因为它作为入口文件主要的作用就是整合,将不同的功能抽取到对应的文件中,因此需要单独创建一个init.js
处理初始化的功能
此时index.js
内容
import { initMixin } from "./init";
/**
* Vue 的一个声明
*/
function Vue(options) {
this._init(options);
}
initMixin(Vue)
export default Vue;
后续会存在生命周期、渲染、全局API等很多初始化过程,都会通过拆分代码到不同的文件中进行维护
init.js
内容
/**
* 初始化混合操作
* 主要是在Vue的原型上增加一个init函数
*/
export function initMixin(Vue) {
/**
* Vue 初始化操作
*/
Vue.prototype._init = function (options) {
};
}
数据初始化
vue的数据来源非常多,可以通过data、props、methods、computed、watch等,需要根据不同的选项类型进行对应的初始化处理,这个逻辑也是非常多,需要将其拆分到state.js
中
此时init.js
Vue.prototype._init = function (options) {
// this.$options 指代的就是开发者传递的选项
const vm = this;
vm.$options = options;
// 初始化状态
initState(vm);
};
需要注意:Vue
中会将用户传递的选项全部挂在到实例vm
的$options
上,后续各个模块之间的流转中只需要传递vm
即可,因为vm.$options
可以获取到全部的传递选项信息
创建state.js
并编写代码
export function initState(vm) {
const ops = vm.$options; // 获取用户全部选项
if (ops.props) {
// 传递了属性
initProps(vm);
}
if (ops.methods) {
// 传递了方法
initMethod(vm);
}
if (ops.data) {
//传递了数据
initData(vm);
}
if (ops.computed) {
// 传递了计算属性
initComputed(vm);
}
if (ops.watch) {
//传递了监听
initWatch(vm);
}
}
function initProps(vm) {}
function initMethod(vm) {}
function initData(vm) {}
function initComputed(vm) {}
function initWatch(vm) {}
上述代码将不同的选项逻辑拆分到不同的函数中,每个函数保持职责单一原则
接下来便是处理数据初始化
在初始化传入data
可以是对象,也可以是一个函数,首选需要对data
进行处理,保证最终得到的都是一个对象
let data = vm.$options.data;
// 对data进行处理
data = vm._data = typeof data === "function" ? data.call(vm) : data;
将data
赋值给vm._data
方便开发者可以直接访问到传递的data
数据