最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【Vue2.x源码学习】第二篇 - Vue 的初始化流程

    正文概述 掘金(BraveWang)   2021-06-06   365

    这是我参与更文挑战的第2天,活动详情查看: 更文挑战

    一,前言

    上篇,使用 rollup 完成了 Vue2 源码环境的搭建

    本篇,介绍 Vue 的初始化流程


    二,Vue 简介

    以两个概念性问题做简单介绍

    1,问题:Vue 是 MVVM 框架吗?

    在 Vue 官网上是这样说的:

    Vue 是一套用于构建用户界面的渐进式框架,
    
    Vue 并没有完全支持 MVVM 模型,但 Vue 的设计受到了它的启发,
    
    变量名 vm 是 vue model 的缩写,表示 vue 实例
    

    所以,严格说 Vue 并不是一个 MVVM 框架

    MVVM 模式是仅能够通过视图更改数据,通过数据来更改视图的,

    但 Vue 是可以通过 ref 获取 dom 进行操作的

    2,问题:Vue 的双向绑定和单向数据流矛盾吗?

    当然不矛盾,这是一个理解问题
    
    双向绑定是指数据变了视图会更新;视图变了会影响数据;
    
    单向数据说的是响应式数据,即数据变化后会更新视图;
    

    三,使用 Vue

    1,Vue Demo

    以一个简单的 Vue Demo 为例:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
      
    <body>
      <!-- 模板 -->
      <div id=app>{{message}}</div>
      <!-- 引入 vue -->
      <script src="./vue.js"></script>
      <script>
        <!-- 初始化 Vue,传入 options 对象 -->
        let vm = new Vue({
          el: '#app',
          // 1,data 是对象
          data: {
            message: 'Hello Vue'
          }
          // 2,data 是函数,返回一个对象
          // data() {
          //   return { message: 'Hello Vue' }
          // }
        });
      </script>
    </body>
    </html>
    

    Vue 初始化时,传入 el 挂载点,data 数据;

    初始化完成后,message 成为响应式数据,数据变化更新视图,视图变化影响数据;

    2,问题:响应式数据原理

    Object.defineProperty 数据劫持(这里也正是 vue2 的性能瓶颈)

    3,问题:Vue 中的数据可以是对象吗?

    根组件不会被共享,可以是对象也可以是函数

    非根组件必须为函数,否则 data 状态会多组件共享


    四,Vue 的初始化操作

    1,原型方法 _init

    在 Vue 原型上扩展一个 _init 方法(原型方法),用于 Vue 的初始化操作

    /**
     * vue中所有功能都是通过原型扩展方式添加的
     * @param {*} options 		new Vue时传入的 options 配置对象
     */
    function Vue(options){
        this._init(options);	// 调用Vue原型上_init方法
    }
    
    // 在Vue原型上扩展一个原型方法_init,进行vue初始化
    Vue.prototype._init = function(options) {
      
    }
    
    export default Vue;
    

    2,重构:原型方法 _init 模块化处理

    将用于初始化操作的原型方法 _init 单独抽离形成一个独立模块 initMixin

    // src/init.js
    export function initMixin(Vue) {
      Vue.prototype._init = function (options) {
        console.log(options)
      }
    }
    
    //------------------------------------------------//
    // src/index.js
    import { initMixin } from "./init";// 引入initMixin模块
    
    function Vue(options){
        this._init(options);	// 这里调用的是Vue的原型方法
    }
    
    // 调用 initMixin 进行 Vue 初始化操作
    initMixin(Vue)
    
    export default Vue;
    

    3,重构后测试

    【Vue2.x源码学习】第二篇 - Vue 的初始化流程


    4,原型方法 _init 的 this 指向

    export function initMixin(Vue) {
      Vue.prototype._init = function (options) {
        const vm = this;
        console.log(vm)	// this == vm 实例
      }
    }
    

    打印原型方法 _init 的 this,this 指向 vm 实例

    【Vue2.x源码学习】第二篇 - Vue 的初始化流程


    5,vm.$options

    为了后续让 vue 中的其他方法也能够轻松获取到外部 new Vue 实例化时传入的 options 对象

    干脆将 options 选项挂到 vm 实例上,即 vm.$options

    export function initMixin(Vue) {
      Vue.prototype._init = function (options) {
        const vm = this;  // this 指向当前 vue 实例
        vm.$options = options; // 将 Vue 实例化时用户传入的 options 暴露到 vm 实例上
      }
    }
    

    6,initState 方法:状态的初始化

    在实际使用中,数据不仅来源于传入的 data,还可能来自 props、watch、computed...

    所以,最好能够统一在一个地方,集中进行数据的初始化处理:initState 方法

    // src/state.js
    export function initState(vm){
        // 获取options:_init 中已将 options 挂载到 vm.$options
        const opts = vm.$options;
    
        if(opts.data){
            initData(vm);	// data数据的初始化
        }
      	// props 数据的初始化
        // watch 数据的初始化
        // computed 数据的初始化
    }
    
    function initData(vm){
        console.log("进入 state.js - initData,数据初始化操作")
    }
    

    引入并使用 initState

    import { initState } from "./state";
    
    export function initMixin(Vue) {
      Vue.prototype._init = function (options) {
        const vm = this;
        vm.$options = options;
    
        // new Vue 时,传入 options 选项,包含 el 和 data
        initState(vm);  // 状态的初始化
    
        if (vm.$options.el) {
          console.log("有el,需要挂载")
        }
      }
    }
    

    【Vue2.x源码学习】第二篇 - Vue 的初始化流程


    五,结尾

    本篇主要介绍了 Vue 数据的初始化流程,核心的几个点:

    • initMixin
    • vm.$options
    • initState

    下一篇,数据劫持:Object.defineProperty

    维护日志

    • 20210605:调整文章的目录结构

    起源地下载网 » 【Vue2.x源码学习】第二篇 - Vue 的初始化流程

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元