Vue.use源码解析

作者: 88b61f4ab233 | 来源:发表于2018-12-15 20:15 被阅读4次

    什么是Vue插件

    关于什么是Vue插件大家可以去看官网的解释 ,总得来说就是提供一个全局注册/调用的能力。

    怎么用

    我们以Weex为例。

    首先有一个toast.js

    const Toast = {}
    Toast.install = (Vue, options) => {
      Vue.prototype.$toast = (msg, duration = 0.8) => {
        const modal = weex.requireModule('modal')
        modal.toast({
          message: msg,
          duration: 0.8
        })
      }
    }
    Vue.use(Toast)
    

    前端全栈学习交流圈:866109386,面向1-3经验年前端开发人员,帮助突破技术瓶颈,提升思维能力,群内有大量PDF可供自取,更有干货实战项目视频进群免费领取。

    很简单,就是定义了一个Toast对面,然后给Toast对象创建一个install方法,方法里给Vue的prototype创建了一个$toast方法,该方法就是调用modal去弹一个toast,最后使用Vue.use方法去注册这个Toast插件。

    然后我们还有一个index.vue:

    <template>
     <div>
     <div class="box" @click="onclick" @longpress="onlongpress" @appear="onappear" @disappear="ondisappear"></div>
      </div>
    </template>
     
    <script>
     const modal = weex.requireModule('modal')
     
     export default {
       methods: {
         onclick (event) {
           this.$toast("aaa", 0.8)
         },
         onlongpress (event) {
           console.log('onlongpress:', event)
           modal.toast({
             message: 'onlongpress',
             duration: 0.8
           })
         },
         onappear (event) {
           console.log('onappear:', event)
           modal.toast({
             message: 'onappear',
              duration: 0.8
            })
          },
          ondisappear (event) {
            console.log('ondisappear:', event)
            modal.toast({
              message: 'ondisappear',
              duration: 0.8
            })
          }
       }
     }
    </script>
     
    <style scoped>
    .box {
      border-width: 2px;
      border-style: solid;
      border-color: #BBB;
      width: 250px;
      height: 250px;
      margin-top: 250px;
      margin-left: 250px;
      background-color: #EEE;
    }
    </style>
    

    前端全栈学习交流圈:866109386,面向1-3经验年前端开发人员,帮助突破技术瓶颈,提升思维能力,群内有大量PDF可供自取,更有干货实战项目视频进群免费领取。

    在其中调用了this.$toast去使用插件的方法。

    由此我们可以知道,Vue的插件机制就是通过Vue.use方法去注册的。

    源码分析

    Vue.use = function (plugin) {
      if (plugin.installed) {
        return
      }
      var args = toArray(arguments, 1);
      args.unshift(this);
      if (typeof plugin.install === 'function') {
        plugin.install.apply(plugin, args);
      } else if (typeof plugin === 'function') {
        plugin.apply(null, args);
      }
      plugin.installed = true;
      return this
    };
     
    function toArray (list, start) {
     start = start || 0;
     var i = list.length - start;
     var ret = new Array(i);
     while (i--) {
      ret[i] = list[i + start];
     }
     return ret
    }
    

    use方法非常简单:

    0x01:判断该插件是否已经注册,如果已经注册就直接return,防止重复注册。

    0x02:然后通过toArray方法将Arguments这个类数组转换成真正的数据,并且去掉第一个元素。

    0x03:将this,也就是Vue实例添加到toArray生成的args数组中。

    0x04:判断use的入参plugin是install是否是一个方法,如果是则直接调用该方法。

    0x05:如果第四步是false,则判断plugun本身是不是一个方法,如果是方法,则用它本身代替install去执行。

    0x06:将plugin的installed标记位设置为true。

    就这么简单的6步,use方法就分析完了,其实就是为了去执行插件的install方法,而结合上面的例子我们知道,install中就把$toast赋值给了Vue的prototype,在其他地方就可以使用的。

    结合实际场景

    学习了Vue的插件机制,那么这个机制我们能用来做什么呢?我们结合Weex来看。

    首先我们知道,Weex是把bundle下发到客户端并渲染,所以一个页面的加载时间取决于两部分:bundle下载时间,bundle渲染时间。在不考虑本地缓存的情况下,bundle的大小直接决定了它的下载时间,以及用户所消耗的流量,所以我们需要有一种方式去尽可能的减小这个bundle的体积。这里Vue的插件机制就可以排上用场了。

    首先我们把一部分共用,不太会改动的基础的代码放在客户端,这样bundle里的内容就应该是纯业务相关的代码,在把bundle下载下来之后手动将客户端的基础js拼接到bundle上,这样就能有效地减小bundle的体积,而想要使用这种方式,就必须把基础js通过Vue的插件机制注册,业务js中全局调用,不然是无法拼接的(除非你的基础js不通过webpack打包),毕竟webpack打包之后所有的代码都是封闭的,无法互相调用。

    相关文章

      网友评论

        本文标题:Vue.use源码解析

        本文链接:https://www.haomeiwen.com/subject/ietzhqtx.html