为什么要开发插件?
插件是对Vue功能上的补充,比如可以设置页面全局共享属性,方法等。
目录
依据官方文档插件开发说明,插件开发有四种方式。
添加全局方法或者属性;
添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
通过全局 mixin 方法添加一些组件选项;
添加全局资源:指令/过滤器/过渡等;
一个库,提供自己的 API,同时提供上面提到的一个或多个功能,
export default{
install:function (Vue,options) {
Vue.$globalFunction=function (num) {
return 2*num;
};
Vue.$globalVariable="我是mrgao";
}
}
作用:
添加全局方法和属性,所有组件都可共享方法和属性,当某个组件更新了共享属性,那么其他组件也会同步更新。并非是组件实例之间的数据共享。
//1:编写组件
export default{
install:function (Vue,options) {
Vue.$globalFunction=function (num) {
return 2*num;
};
Vue.$globalVariable="我是mrgao";
}
}
//2:声明组件,注入组件
import install from "./plugins/demo.js";
Vue.use(install);
//3:组件样例
<Poptip trigger="focus">
<Input
v-model="gloablFunc"
prefix="logo-usd"
placeholder="Enter number"
style="width: 120px"
/>
<div slot="content">{{ formatNumber }}</div>
</Poptip>
import Vue from "vue";
export default {
data() {
return {
gloablFunc: ""
};
},
computed: {
formatNumber: function() {
//调用全局共享方法
return Vue.$globalFunction(this.gloablFunc);
}
}
};
方式:使用Vue.prototype的方式给Vue实例添加方法和属性
注意点:使用Vue.prototype的方式添加的属性是不会在各个实例之间数据共享的。
比如A实例修改了某属性,则B实例使用此属性时不会是A修改的值。
//1:组件编写 demo.js
export default {
install: function(Vue, options) {
Vue.prototype.$instanceFunction = function(num) {
return 3 * num;
};
Vue.prototype.$instanceVar="我是实例变量";
}
};
//2:组件声明 main.js
import install from "./plugins/demo.js";
Vue.use(install);
//3:组件使用 Plugins.vue
...省略部分
<span>添加实例方法/属性测试</span>
<div>{{ instanceVar }}</div>
mounted(){
console.log(this.$instanceVar);
this.instanceVar=this.$instanceVar;
//this.instanceVar=this.$instanceFunction(20);
}
混入mixin作用:
将混入对象的方法/数据对象合并到改组件本身的方法/数据上;若存在同名的方法,则首先调用混入对象,再调用组件本身方法,若存在同名数据对象,则使用组件的数据对象
混入分为局部混入和全局混入,一旦使用全局混入对象,将会影响到 所有 之后创建的 Vue 实例。请谨慎使用全局混入,尽可能使用局部混入。
此处借用官方的例子选项合并
当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合。比如,数据对象在内部会进行递归合并,在和组件的数据发生冲突时以组件数据优先。
若存在同名方法则优先调用混入对象的方法。
值为对象的选项,例如 methods, components 和 directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。
var mixin = {
data: function() {
return {
message: "hello",
foo: "abc"
};
},
created: function() {
console.log("混入对象的钩子被调用");
},
methods:{
demo1(){
console.log("混入demo1");
},
demo2(){
console.log("混入demo2");
}
}
};
export default {
mixins: [mixin],
data: function() {
return {
message: "goodbye",
bar: "def"
};
},
created: function() {
console.log('组件钩子被调用')
console.log(this.$data);
//混入对象的钩子被调用
//组件钩子被调用
// => { message: "goodbye", foo: "abc", bar: "def" }
},
methods:{
demo1(){
console.log("组件demo1");
}
}
};
为全局Vue实例混入一个created方法,在每一个实例调用本身的created之前都会首先调用混入的created。
通常我们可以使用全局混入对Vue实例注入统一处理统计。
// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
created: function () {
//console.log("相信我,这个Log会在每一个Vue实例created之前调用");
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
})
new Vue({
myOption: 'hello! mrgao'
})
// => "hello!"
除了核心功能默认内置的指令 (v-model 和 v-show等),Vue 也允许注册自定义指令。
参考官方文档:自定义指令
指令钩子函数会被传入以下参数:
//D.vue
<template>
<div v-demo:foo.a.b="message"></div>
</template>
<script>
export default {
data() {
return {
message: "我是demo"
};
}
};
//main.js
Vue.directive('demo', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '
' +
'value: ' + s(binding.value) + '
' +
'expression: ' + s(binding.expression) + '
' +
'argument: ' + s(binding.arg) + '
' +
'modifiers: ' + s(binding.modifiers) + '
' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
结果为:
name: "demo"
value: "我是demo"
expression: "message"
argument: "foo"
modifiers: {"a":true,"b":true}
vnode keys: tag, data, children, text, elm, ns, context, fnContext, fnOptions, fnScopeId, key, componentOptions, componentInstance, parent, raw, isStatic, isRootInsert, isComment, isCloned, isOnce, asyncFactory, asyncMeta, isAsyncPlaceholder
//1:编写过滤器 currency.js
const digitsRE = /(\d{3})(?=\d)/g
export function currency (value, currency, decimals) {
value = parseFloat(value)
if (!isFinite(value) || (!value && value !== 0)) return ''
currency = currency != null ? currency : '$'
decimals = decimals != null ? decimals : 2
var stringified = Math.abs(value).toFixed(decimals)
var _int = decimals
? stringified.slice(0, -1 - decimals)
: stringified
var i = _int.length % 3
var head = i > 0
? (_int.slice(0, i) + (_int.length > 3 ? ',' : ''))
: ''
var _float = decimals
? stringified.slice(-1 - decimals)
: ''
var sign = value < 0 ? '-' : ''
return sign + currency + head +
_int.slice(i).replace(digitsRE, '$1,') +
_float
}
//2:声明 main.js
import { currency } from "./currency";
Vue.filter("currency", currency);
//3:使用Productlist.vue
<Tag type="dot" closable color="success">单价:{{ product.price | currency }}</Tag>
上述已经简单讲解了Vue插件开发的四种方式,最后一种方式,也就是将上述四种组合在一个install方法中即可。
欢迎Star