• vue-简单例子初始化


    1. vue

    (function (global, factory) {
        //根据当前环境中用的ADM或COMMONJS格式的模块规范或者未用模块管理规范,将Vue(函数)对象返回给对应变量属性(或全局变量),
        typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
        (global.Vue = factory());
    }(this, (function () { 'use strict';
    .....
    return Vue$3;
    
    })
    ));

    1.立即执行函数

      (function(global,factory){

       }(this,(...)) )

      将this和vue的构建函数传入匿名函数,根据当前环境进行vue初始化,如果是ADM模块管理下则传入define函数,Commonjs模块管理输出vue函数给module.exports,否则直接挂在全局变量上。

    2.factory()

      初始化Vue框架。

      2.1 cached(fn)

      cached(fn):缓存函数,提供fn缓存处理函数,然后存在内部变量cache中。

      2.2 资源类型 

    //资源类型
    var ASSET_TYPES = [
    'component',//组件
    'directive',//指令
    'filter'//过滤器
    ];
    //生命周期内的函数钩子
    var LIFECYCLE_HOOKS = [
    'beforeCreate',
    'created',
    'beforeMount',
    'mounted',
    'beforeUpdate',
    'updated',
    'beforeDestroy',
    'destroyed',
    'activated',
    'deactivated',
    'errorCaptured'
    ];
    View Code

      2.3 合并strats

        mergeHook合并LIFECYCLE_HOOKS钩子策略,将父级和子级的钩子函数和props属性合并为数组。

        mergeAssets当存在一个虚拟节点(实例创建),我们需要将构造函数选项和实例选项和父级选项三方式合并。 AssetsType:组件、指令、过滤器

        strats.watch:一个观察者哈希值不应该覆盖另一个观察者的哈希值,所以我们将它们合并为数组。

        其他策略哈希:strats.props ,strats.methods ,strats.inject,strats.computed

      2.4 全局消息通达

        微任务、宏任务触发函数初始化。构建任务

        宏任务macroTimerFunc:异步调用flushCallbacks回调函数列表中的函数setImmediate或MessageChannel或setTimeout。

         微任务microTimerFunc:如果有Promise.then则使用这个构建微任务,否则微任务实际执行宏任务。

      2.5初始化渲染代理initProxy

      

     1 //has代理处理对象
     2   var hasHandler = {
     3     has: function has (target, key) {
     4       var has = key in target;
     5       var isAllowed = allowedGlobals(key) || key.charAt(0) === '_';
     6       if (!has && !isAllowed) {
     7         warnNonPresent(target, key);
     8       }
     9       //key不能是全局变量(或属性)也不能是_打头的‘私有’属性
    10       return has || !isAllowed
    11     }
    12   };
    13 //get代理处理对象
    14   var getHandler = {
    15     get: function get (target, key) {
    16       if (typeof key === 'string' && !(key in target)) {
    17         warnNonPresent(target, key);
    18       }
    19       return target[key]
    20     }
    21   };
    22   //
    23   initProxy = function initProxy (vm) {
    24     if (hasProxy) {//如果()环境内置proxy代理
    25       // determine which proxy handler to use
    26       var options = vm.$options;  //_withStripped 被卸载?待完善
    27       //渲染代理定义,如果vm对象定义中有render等则用get代理处理函数否则使用has代理处理函数
    28       var handlers = options.render && options.render._withStripped
    29         ? getHandler
    30         : hasHandler;
    31       vm._renderProxy = new Proxy(vm, handlers);
    32     } else {
    33       vm._renderProxy = vm;
    34     }
    35   };
    36 
    37 
    38 ........
    39 
    40 Vue.prototype._render = function () {
    41 
    42     .....
    43      vnode = render.call(vm._renderProxy, vm.$createElement);
    44     ....
    45 }    
    View Code

    this就是vm._renderProxy渲染代理,生成html代码时需要读取数据,代理会过滤非枚举的属性对象。返回 target[key]时,又会触发Object.definePropery拦截。

      2.6 设置渲染帮助函数

        installRenderHelpers

       2.8初始化混合

        initMixin(Vue$3);

        设置 Vue.prototype._init  全局初始化函数

      2.9状态混合

      stateMixin(Vue$3);

      设置$data、$props 只读属性,分别来自_data 、_props。定义全局方法$set、$delete、$watch(用户使用的侦听方法)。

      2.10 事件混合

        eventsMixin(Vue$3);

        在Vue原型上定义$on、$off、$once、$emit事件处理函数。

        $on时将event设置到_events上维护,vm._events[event]。

      2.11 生命周期混合
      lifecycleMixin(Vue$3);

      原型上定义_update、$forceUpdate、$destroy、

      2.12渲染混合
      renderMixin(Vue$3);

      首先installRenderHelpers调用渲染辅助函数,定义$nextTick、_render、

      2.13初始化全局api

      initGlobalAPI:config、 Vue.util 、Vue.set、Vue.delete、Vue.nextTick 、Vue.options、Vue.options.components

      2.13.1 初始化用户插件使用函数

      initUse(Vue);

       Vue.use 初始化插件,plugin.install,加载到Vue上。

      2.13.2 初始化混合
        initMixin$1(Vue);

        Vue.mixin用户混合选项options

      2.13.3 初始化扩展
      initExtend(Vue);  子组件继承

      2.13.4 初始化资源注册
      initAssetRegisters(Vue);

      3.

    以上是vue自身初始化,下面用户使用vue

    new Vue

    生命周期函数:

    mergeOptions:合并实例的components、directives、filters等属性。

    initProxy: vm._renderProxy = new Proxy(vm, handlers);如果vm  vue实例是带render的组件实例则添加gethandler处理函数,否则添加hashandler

    beforecreate之前:初始化vue实例代理、初始化化声明周期,初始化事件,初始化渲染

    created之前:初始化注入、初始化state状态(data/props)、初始化provide

    function Vue$3 (options) {
      if ("development" !== 'production' &&
        !(this instanceof Vue$3)
      ) {
        warn('Vue is a constructor and should be called with the `new` keyword');
      }
      this._init(options);
    }

    1.vm._uid  

      Vue节点的uid唯一编号设置,并给特殊的Vue节点设置_isVue标记,避免被监听。

      1.1初始化内部组件或者合并参数选项

      initInternalComponent(vm, options); :  如果options参数中表明是一个组件则初始化内部组件。优化内部组件实例化,因为动态选项合并很慢,并且内部组件选项都不需要特殊处理。

    vm.constructor.options主要由之前VUE自执行时初始化的内容:components组件、directives指令、filters过滤。

    1. components:{KeepAlive: {…}, Transition: {…}, TransitionGroup: {…}}
    2. directives:{model: {…}, show: {…}}
    3. filters:{}

     resolveConstructorOptions :如果没有super父级继承属性,则直接返回上面三个属性(另_base)

    mergeOptions (parent,child,vm) 然后将父级选项和子级选项合并,

    首先检查child.components(如果child下还有组件的话)中的组件名称是否有效,无效则会给出提示信息或根据配置提示函数做处理。

       1.1.1 规范化属性

        normalizeProps(child, vm); 驼峰化属性名称

      normalizeInject(child, vm); 规范化注入属性对象options.inject
      normalizeDirectives(child);规范化指令,如果指令对象的某个属性值是函数则将该属性绑定到一个对象{ bind: def, update: def },其中def就是原指令函数。

      child.extends 将子组件中的选项内容合并到父组件上去。

      child.mixins Mixin 钩子与组件自身钩子同名时,Mixin 钩子按照传入顺序依次调用,并在调用组件自身的钩子之前被调用。

      mergeField ()根据默认初始的components、directives、filters、_base(Vue$3)四个选项属性的各自策略将parent和child响应的属性合并

      然后再将子组件中含有的属性和父组件中没有的属性合并到父组件(第一次newVue的时候的父级是之前加载vue就执行产生的默认四个选项的属性对象)中。

    1.2 initProxy

      vm._renderProxy = new Proxy(vm, handlers);如果vm  vue实例是带render的组件实例则添加gethandler处理函数,否则添加hashandler。比如new Vue直接传el而不是手动添加render函数则对vue实例加_renderProxy 代理。

    1.3    initLifecycle(vm);

      找到vm父节点并将该vue实例存入父节点的children中。

      vm节点挂父节点、根节点 vm.$parent = parent;

      初始化children节点

      $refs相关参数、_watcher、_inactive、相关标记:_directInactive、_isMounted标记、_isDestroyed、_isBeingDestroyed

      

    1.4 initEvents(vm)

      根据 listeners = vm.$options._parentListeners;添加组件更新监听器,

       Vue.prototype.$on  : 将事件处理函数挂在vm._events的事件对象上  (vm._events[event] || (vm._events[event] = [])).push(fn);

    1.5 initRender(vm);

      初始与渲染相关的属性_vnode、 _staticTrees、解析$slots插槽、$scopedSlots

      vm._c :封装了createElement 创建元素关键函数,主要是内部使用

      vm.$createElement:也封装了vm.$createElement函数,可供外部调用

      defineReactive:添加对$attrs 和$listeners 属性对象 建立双向绑定

    回调beforecreate钩子

     callHook(vm, 'beforeCreate');

    2. create部分

    2.1initInjections(vm);

      初始化注入:

    2.2  initState(vm);

      初始组件的  vm._watchers  监听器,props、methods、data、computed、watch

       initData (vm):

        mergedInstanceDataFn 合并数据对象函数,对data添加代理 proxy(vm, "_data", key);,key的来源是vm.$options.data;的data的关键字, proxy在vm对象上对获取_data上的key属性进行属性代理劫持,将key直接挂在vue实例的第一层,如果调用vm.key时,从target的_data的对应key上获取。

        observe(data, true /* asRootData */);为options中的data,尝试给一个value值创建观察者实例,如果成功观察,返回新的观察者,如果值已经有一个观察者,则返回现有的观察者。

      initProvide(vm); 

    以上  callHook(vm, 'created'); 回调created事件。

    3. 装载el节点

       vm.$mount(vm.$options.el);

      Vue$3.prototype.$mount

      将 template/el 转换成 render function,如果是el,则使用  template = getOuterHTML(el);获取html模板,

       createCompileToFunctionFn 解析模板

        var compiled = compile(template, options);将模板解析为一个对象,

        res.render = createFunction(compiled.render, fnGenErrors);

    v-show :调用toggleDisplay

  • 相关阅读:
    SQL Server SQLHelper帮助类
    Winform 常用的方法
    SQL Server 插入含有中文字符串出现乱码现象的解决办法
    ComboBox 中 DisplayMember 和 ValueMember 都是具体干什么的?
    HTML常用标签属性使用
    虚拟机安装windows server 2012 R2
    VS2017生成带图标的QT项目方法
    QSS 记录
    QT qss资源文件与代码分离
    pgsql 服务遇见的问题记录
  • 原文地址:https://www.cnblogs.com/xiaozhuyuan/p/8981073.html
Copyright © 2020-2023  润新知