更新:谢谢你们的支持,最近折腾了一个博客官网出来,方便你们系统阅读,后续会有更多内容和更多优化,猛戳这里查看html
------ 如下是正文 ------前端
Vue进阶系列汇总以下,欢迎阅读。vue
Vue 进阶系列(二)之插件原理及实现github
插件的详细使用方法详情看Vue官网数组
Vue官网之插件Plugins前端工程师
归纳出来就是app
Vue.use(MyPlugin)
使用,本质上是调用MyPlugin.install(Vue)
new Vue()
启动应用以前完成,实例化以前就要配置好。Vue.use
屡次注册相同插件,那只会注册成功一次。Vue.use
源码以下ide
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)
复制代码
本人Github连接以下,欢迎各位Star
我是木易杨,网易高级前端工程师,跟着我每周重点攻克一个前端面试重难点。接下来让我带你走进高级前端的世界,在进阶的路上,共勉!