一、写在前面
插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:
添加全局方法或者属性。如:vue-custom-element
添加全局资源:指令/过滤器/过渡等。如 vue-touch
通过全局混入来添加一些组件选项。如 vue-router
添加 Vue 实例方法,通过把它们添加到
Vue.prototype上实现。一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router
Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象。
二、 Vue.prototype 实现
通过Vue.prototype来把方法添加到实例上面。
非插件开发:
//myplugin.js
import Vue from "vue"
Vue.prototype.$myplugin = function(){}
函数或属性
Vue.prototype.$myplugin = {}有几个问题:
1. import Vue from "vue" 中的 vue 是自定义的,用户自己配置的,可能和你的这个 vue 不是一个
2. $myplugin可能被用户自己占用
开发插件:
// myplugin.js
var myplugin = {};
myplugin.install = function (Vue, options) {
Vue.prototype.$myplugin = function(){};
}
exports default myplugin;// main.js
import Vue from 'vue';
import myplugin from './myplugin.js';
Vue.use(myplugin);Vue.use(myplugin) 安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。
该方法需要在调用 new Vue() 之前被调用。
当 install 方法被同一个插件多次调用,插件将只会被安装一次。
之后我们就可以通过 this.$myplugin 来使用插件了
插件开发好处在于,由用户自己调用use,这样用户的Vue版本和插件没有关系
三、添加全局方法或者属性
// myplugin.js
var myplugin = {};
myplugin.install = function (Vue, options) {
Vue.$myplugin = function(){};
}
exports default myplugin;和添加实例方法类似
四、directive 添加全局指令
指令钩子函数
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性初始化设置inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。update:所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前。指令值可能发生了变化,也可能没有发生变华。componentUpdated:指令所在组件的VNode及子VNode全部更新后调用unbind:只调用一次,指令与元素解绑时调用
钩子函数参数
指令钩子函数会被传入以下参数:
el:指令所绑定的元素,可以用来直接操作DOMbinding:一个对象,包含以下属性name:指令名,不包含v-前缀value:指令的绑定值,例如:v-my-direactive= "1+1"中表达式值为2oldValue:指令绑定的前一个值,仅在update和componentUpdated钩子中可用。无论值是否改变都可用。expression:字符串形式的指令表达式。例如v-my-directive="1 + 1"中,表达式为"1 + 1"。
arg:传给指令的参数,可选。例如v-my-directive:foo中,参数为foo。modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar中,修饰符对象为{ foo: true, bar: true }
指令开发
// myplugin.js
var myplugin = {};
Toast.install = function (Vue, options) {
Vue.directive("time", {
bind(el, binding) {
el.innerHTML = el.innerHTML ? el.innerHTML : el.textContent;
el.innerHTML = Time.getFormatTime(binding.value);
}
exports default myplugin;import myplugin from 'myplugin'
Vue.use(time);五、全局混入开发
// 定义一个混入对象
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}
// 定义一个使用混入对象的组件
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"Vue.mixin({
created: function () {
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
})
new Vue({
myOption: 'hello!'
})
// => "hello!"vm.$options用于当前 Vue 实例的初始化选项。需要在选项中包含自定义 property 时会有用处
六、插件开发,动态生成组件
import Toast from "./toast";
//toastplugin.js
export default {
install(Vue, options) {
Vue.prototype.$toast = function(message) {
let Constructor = Vue.extend(Toast);
let toast = new Constructor();
toast.$slots.default = [message];
toast.$mount();
document.body.appendChild(toast.$el);
};
}
};//app.js
methods:{
toast(){
this.$toast("toast!!!")
}
}//index.js
import Vue from "vue";
import toastplugin from "./toast/toastplugin";
Vue.use(toastplugin);样式在toast.vue 中写
为什么我要动态生成?,因为我的toast组件不会写在app.vue里面,需要点击才出现