• vue.use 实现原理剖析 All In One


    vue.use 实现原理剖析 All In One

    插件通常用来为 Vue 添加全局功能。

    插件的功能范围没有严格的限制, 一般有下面几种:

    1. 添加全局方法或者 property。如:vue-custom-element

    2. 添加全局资源:指令/过滤器/过渡等。如 vue-touch

    3. 通过全局混入来添加一些组件选项。如 vue-router

    4. 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。

    5. 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router

    源码解读

    /**
     * Convert an Array-like object to a real Array.
     */
    export function toArray (list: any, start?: number): Array<any> {
      start = start || 0
      let i = list.length - start
      const ret: Array<any> = new Array(i)
      while (i--) {
        ret[i] = list[i + start]
      }
      return ret
    }
    

    util/index => shared/util.js

    https://github.com/vuejs/vue/blob/master/src/shared/util.js

    /* @flow */
    
    import { toArray } from '../util/index'
    
    export function initUse (Vue: GlobalAPI) {
      // 闭包
      Vue.use = function (plugin: Function | Object) {
        const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
        // plugin 已存在, 直接返回,防止重复添加
        if (installedPlugins.indexOf(plugin) > -1) {
          return this
        }
    
        // additional parameters
        // 把 arguments 转换成 apply 支持的参数数组形式
        const args = toArray(arguments, 1)
       // 从数组前面插入 this
        args.unshift(this)
        if (typeof plugin.install === 'function') {
          // plugin 是个对象,而且有 install 方法
          plugin.install.apply(plugin, args)
        } else if (typeof plugin === 'function') {
          // plugin 本身是个方法
          plugin.apply(null, args)
        }
        // 收集 plugin
        installedPlugins.push(plugin)
        return this
      }
    }
    
    

    https://github.com/vuejs/vue/blob/dev/src/core/global-api/use.js

    https://github.com/vuejs/vue/blob/master/src/core/global-api/use.js

    Vue 2.x

    全局方法 Vue.use() 使用插件, 必须放在调用 new Vue() 前。

    
    Vue.use(MyPlugin);
    // 调用插件的 install 方法 `MyPlugin.install(Vue)`;
    
    // Vue.use(MyPlugin, { someOption: true });
    
    new Vue({
      // ...
    });
    
    
    // 用 Browserify 或 webpack 提供的 CommonJS 模块环境时
    var Vue = require('vue');
    
    var VueRouter = require('vue-router');
    // 手动调用插件
    Vue.use(VueRouter);
    
    // 检查到全局变量 Vue 后才调用插件 ✅
    if(globalThis.Vue) {
        Vue.use(VueRouter);
    }
    
    
    if(globalThis.Vue) {
        console.log('globalThis.Vue =', typeof globalThis.Vue);
    }
    // globalThis.Vue = function
    
    

    自定义插件

    MyPlugin.install = function (Vue, options) {
      // 1. 添加全局方法或 property
      Vue.myGlobalMethod = function () {
        // ...
      };
      // 2. 添加全局资源 (指令/过滤器/过渡)
      Vue.directive('my-directive', {
        bind (el, binding, vnode, oldVnode) {
          // ...
        },
        //...
      });
      Vue.directive('my-filter', function (value) {
        if (!value || typoef value !== 'string') {
          return '';
        }
        return `${value[0].toUpperCase()}${value.slice(1)}`;
        // value = 
        // return value.charAt(0).toUpperCase() + value.slice(1);
      });
      // 3. 全局混入/全局注入一些组件选项
      Vue.mixin({
        created: function () {
          // ...
          console.log('created', mixin);
        },
        //...
        data () {
           isLoading: false,
           isDebugging: false,
        },
        methods: {
           log(value) {
              // 打印组建名称
              const componetName = `✅ ${this.name}` || '❌ Anonymous Component';
              console.log(`${componetName}'s value =`, value);
           },
        },
      });
      // 4. 添加实例方法
      Vue.prototype.$myMethod = function (methodOptions) {
        // ...
      };
      Vue.prototype.monitor = function (options = {}) {
        // 监控 SDK
        console.log('上报数据', options);
      };
    }
    
    

    https://cn.vuejs.org/v2/api/#Vue-use

    https://cn.vuejs.org/v2/guide/plugins.html

    Vue 3.x

    
    

    https://v3.cn.vuejs.org/guide/plugins.html

    demo

    refs



    ©xgqfrms 2012-2020

    www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

    原创文章,版权所有©️xgqfrms, 禁止转载 ️,侵权必究⚠️!


  • 相关阅读:
    例7-13
    例7-11
    例7-1
    例6-5
    例6-3
    例6-2
    例6-1
    例5-9
    例5-8
    例5-7
  • 原文地址:https://www.cnblogs.com/xgqfrms/p/15983128.html
Copyright © 2020-2023  润新知