Vue 进阶系列(二)之插件原理及实现

栏目: 编程语言 · 发布时间: 6年前

内容简介:Vue进阶系列汇总如下,欢迎阅读,欢迎加群讨论(文末)。

Vue进阶系列汇总如下,欢迎阅读,欢迎加群讨论(文末)。

Vue 进阶系列(一)之响应式原理及实现

Vue 进阶系列(二)之插件原理及实现

使用方法

插件的详细使用方法详情看Vue官网

Vue官网之插件Plugins

概括出来就是

  • 1、通过 Vue.use(MyPlugin) 使用,本质上是调用 MyPlugin.install(Vue)
  • 2、使用插件必须在 new Vue() 启动应用之前完成,实例化之前就要配置好。
  • 3、如果使用 Vue.use 多次注册相同插件,那只会注册成功一次。

源码解读

Vue.use 源码如下

Vue.use = function (plugin) {   
    // 忽略已注册插件
    if (plugin.installed) {
      return
    }
    
    // 集合转数组,并去除第一个参数
    var args = toArray(arguments, 1);
    
    // 把this(即Vue)添加到数组的第一个参数中
    args.unshift(this);
    
    // 调用install方法
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args);
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args);
    }
    
    // 注册成功
    plugin.installed = true;
    return this;
  };
复制代码

Vue.use 接受一个对象参数 plugin ,首先判断是否已注册,如果多次注册相同插件那么只会注册成功一次,在注册成功后设置 plugin.installed = true

然后执行 toArray(arguments, 1) 方法, arguments 是一个表示所有参数的类数组对象,需要转换成数组之后才能使用数组的方法。

function toArray (list, start) {
  start = start || 0;
  var i = list.length - start;
  var ret = new Array(i);
  // 循环去除 前start元素
  while (i--) {
    ret[i] = list[i + start];
  }
  return ret
}
复制代码

上面进行了一次转换,假设 list 是[1, 2, 3, 4], start 是1,首先创建一个包含3个元素的数组,依次执行 ret[2] = list[ 2 + 1]ret[1] = list[ 1 + 1]ret[0] = list[ 0 + 1] ,实际上就是去除 arguments 的第一个参数然后把剩余的类数组赋值给新的数组,其实就是去除 plugin 参数,因为调用 plugin.install 的时候不需要这个参数。

还可以通过如下几种方式实现类数组转换成数组,但是使用slice会阻止某些JavaScript引擎中的优化(参考自MDN)。

// ES5
var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);

// ES6
const args = Array.from(arguments);
const args = [...arguments];
复制代码

转换成数组之后调用 args.unshift(this) ,把 Vue 对象添加到args的第一个参数中,这样就可以在调用 plugin.install 方法的时候把 Vue 对象传递过去。

实例:实现一个插件

要求创建一个告诉Vue组件处理自定义 rules 规则选项的插件,这个 rules 需要一个对象,该对象指定组件中的数据的验证规则。

示例:

const vm = new Vue({
  data: { foo: 10 },
  rules: {
    foo: {
      validate: value => value > 1,
      message: 'foo must be greater than one'
    }
  }
})

vm.foo = 0 // 输出 foo must be greater than one
复制代码

第一步先不考虑插件,在已有的 Vue API中是没有 rules 这个公共方法的,如果要简单实现的话可以通过钩子函数来,即在 created 里面验证逻辑。

const vm = new Vue({
    data: { foo: 10 },
    rules: {
        foo: {
          validate: value => value > 1,
          message: 'foo must be greater than one'
        }
    },
    created: function () {
      
        // 验证逻辑
        const rules = this.$options.rules
        if (rules) {
          Object.keys(rules).forEach(key => {
          
            // 取得所有规则
            const { validate, message } = rules[key]
            
            // 监听,键是变量,值是函数
            this.$watch(key, newValue => {
            
              // 验证规则
              const valid = validate(newValue)
              if (!valid) {
                console.log(message)
              }
            })
          })
        }
      }
    
})

复制代码

可以通过 this.$options.rules 获取到自定义的 rules 对象,然后对所有规则遍历,使用自定义的 validate(newValue) 验证规则。

第二步实现这个 rules 插件,为了在 Vue 中直接使用,可以通过 Vue.mixin 注入到 Vue 组件中,这样所有的 Vue 实例都可以使用。

按照插件的开发流程,应该有一个公开方法 install ,在 install 里面使用全局的 mixin 方法添加一些组件选项, mixin 方法包含一个 created 钩子函数,在钩子函数中验证 this.$options.rules

实现代码如下:

import Vue from 'vue'

// 定义插件
const RulesPlugin = {

  // 插件应该有一个公开方法install
  // 第一个参数是Vue 构造器
  // 第二个参数是一个可选的选项对象
  install (Vue) {
  
    // 注入组件
    Vue.mixin({
    
      // 钩子函数
      created: function () {
      
        // 验证逻辑
        const rules = this.$options.rules
        if (rules) {
          Object.keys(rules).forEach(key => {
          
            // 取得所有规则
            const { validate, message } = rules[key]
            
            // 监听,键是变量,值是函数
            this.$watch(key, newValue => {
            
              // 验证规则
              const valid = validate(newValue)
              if (!valid) {
                console.log(message)
              }
            })
          })
        }
      }
    })
  }
}

// 调用插件,实际上就是调用插件的install方法
// 即RulesPlugin.install(Vue)
Vue.use(RulesPlugin)
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java学习笔记

Java学习笔记

林信良 / 清华大学出版社 / 2015-3-1 / CNY 68.00

●本书是作者多年来教学实践经验的总结,汇集了学员在学习课程或认证考试中遇到的概念、操作、应用等问题及解决方案 ●针对Java SE 8新功能全面改版,无论是章节架构或范例程序代码,都做了重新编写与全面翻新 ●详细介绍了JVM、JRE、Java SE API、JDK与IDE之间的对照关系 ●从Java SE API的源代码分析,了解各种语法在Java SE API中的具体应用 ......一起来看看 《Java学习笔记》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

SHA 加密
SHA 加密

SHA 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具