如果要成长为一名高级乃至资深前端工程师,不但要熟练使用,还要明白背后的原理,达到举一反三的程度。在整个成长过程中,阅读源码是不可或缺的重要一环。
本篇文章以vue 2.6.10源码为例,为大家分享vue2.x组件实例化流程。
首先创建一个index.html文件,并且引入vue2.6.10.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Hello Vue</title>
</head>
<body>
<div id="app">
<div>{
{
a}}</div>
</div>
<script type="text/javascript" src="vue_2.6.10.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
a: 1
}
});
console.log(vm.$options);
</script>
</body>
</html>
控制台输出选项参数为
可以看到除了我们初始化时传递进去的el和data参数,还多了好多其他的参数,例如components,directives等。特别需要注意的是,传进去的data是一个对象,但是却变成了一个函数。
这是什么原因呢?
下面从Vue实例初始化流程来为大家具体分析,内容有点多,还希望大家能够耐心看完哦。
在vue2.6.10.js中首先检测宿主环境是否支持匹配条件
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.Vue = factory());
}(this, function () { 'use strict';
然后定义Vue工厂函数factory(),并且赋值给global.Vue,首先检测是不是通过new Vue()来初始化根实例,如果直接在index.html中把Vue()当作一个普通函数来调用,则会发出警告;options就是在index.html中new Vue()时传递的选项参数。
function Vue (options) {
if (!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword');
}
this._init(options);
}
调用this._init(options)对选项参数做处理,通过函数initMixin(Vue)来完成。
function initMixin (Vue) {
// 定义Vue的原型属性_init
Vue.prototype._init = function (options) {
var vm = this;