26.Vue插件

简介

插件是为应用添加全局功能的一种强大而且简单的方式。以下是一些知名插件案例:

  1. 添加全局方法或者 property。如:vue-custom-element。
  2. 添加全局资源:指令/过滤器/过渡等。如 vue-touch。
  3. 通过全局混入来添加一些组件选项。如 vue-router。
  4. 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
  5. 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router。

制作

插件有一个公开方法install,所有的插件都需要使用install这个公开方。这个方法的第一个参数是Vue构造器,第二个参数是一个可选的选项对象

// MyPlugin就是插件的名称
MyPlugin.install = function (Vue, options) {
  // 通过 Vue.xxxx 添加全局方法或属性
  Vue.myGlobalMethod = function () {  
    // 逻辑...
  } 
  
  // 通过 Vue.directive 来进行自定义指令 
  Vue.directive('my-directive', { 
    bind (el, binding, vnode, oldVnode) {
      // 逻辑...
    }
    ...
  })
  
   // 通过全局 mixin方法添加一些组件选项
  Vue.mixin({
    created: function () {
      // 逻辑...
    }
    ...
  })
  
  // 添加实例方法,通过把它们绑定到 Vue.prototype 上实现
  Vue.prototype.$myMethod = function (options) {  
    // 逻辑...
  }
}

 

使用

在main.js中,需要导入插件 Xxx.js 并且通过全局方法 Vue.use() 来使用插件。例如:

//Speak.js
var Speak = {};
Speak.install = function (Vue, options) {
  Vue.prototype.$words = "Hello, plugin!"
}
module.exports = Speak;

//main.js
import Vue from 'vue'

import Speak from './assets/js/speak.js' //导入插件
Vue.use(Speak) //使用插件

new Vue({
  el: '#app',
})

// xxx.vue
export default {
    created(){
        alert(this.$words);         // Hello plugin!
    }
}

 

案例:toast插件

需求

点击按钮后触发一个toast提示,内容、位置要求可以自定义。

思路

可以在body中添加一个div来显示提示信息,然后定时清除。自定义功能通过绑定Vue.prototype时传入。

实现

首先制作了一个简单的弹出模板的js。

// plugin/toast.js
var Toast = {};
Toast.install = function(Vue, options) {
	Vue.prototype.$toast = (tips) => {
            // 1.指定模板
		let toastTpl = Vue.extend({
			template: '<div class="vue-toast">' + tips + '</div>',
		});

		// 2.创建实例挂载,dom保存到变量
		let tpl = new toastTpl().$mount().$el;

		// 3、把创建的dom添加到#app中
		document.getElementById("app").appendChild(tpl);

		// 4.延迟2.5秒后移除该dom
		setTimeout(function() {
			document.getElementById("app").removeChild(tpl);
		}, 2500)
	}
}
export default Toast;

//main.js
import Toast from './plugin/toast.js'
Vue.use(Toast)

// App.vue
<template>
	<div id="app">
		<button @click="jump()">弹出</button>
	</div>
</template>

<script>
	export default {
		methods: {
			jump() {
				this.$toast("这是我自己的写的吐司");
			}
		}
	}
</script>

运行发现:
在这里插入图片描述
解决方案1(不推荐):
在根目录下新建一个新的vue.config.js的文件,添加下面内容重启serve。由于runtime-only 比 runtime-compiler高效,所以不推荐此方案。

module.exports = {
    runtimeCompiler: true
}

解决方案2:
把插件里的 template 用 render 方式展现。

// plugin/toast.js
import toastTemp from './toast.vue'

var Toast = {};
Toast.install = function(Vue, options) {
	Vue.prototype.$toast = (tips, position) => {
		let toastTpl = Vue.extend({
			// 1、指定模板
			render: h => h(toastTemp)
		});

		// 2、创建实例挂载,dom保存到变量
		let tpl = new toastTpl().$mount().$el;

		// 3、把创建的dom添加到#app中
		document.getElementById("app").appendChild(tpl);

		//4、 延迟2.5秒后移除该dom
		setTimeout(function() {
			document.getElementById("app").removeChild(tpl);
		}, 2500)
	}
}
export default Toast;

// plugin/toast.vue
<template>
	<transition name="fade">
		<div class="vue-toast" v-show="show">
			{{tips}}
		</div>
	</transition>
</template>

<script>
	export default {
		props: ['tips'],
	}
</script>

按照上面的办法已经可以正常添加dom了,但也仅仅是达到了“在页面添加dom,2.5秒后移除”的效果,没有加入位置、动画、样式等,接下来将其补全,完整代码如下。
插件相关:

// plugin/toast.js
import toastTemp from './toast.vue'

var Toast = {};
Toast.install = function(Vue, options) {
	Vue.prototype.$toast = (tips, position) => {
		let toastTpl = Vue.extend({
			// 1、指定模板
			render: h => h(toastTemp, {
				//render的第二个参数用于传参
				//传递属性
				props: {
					tips
				},
				//相当于v-bind:class
				class: {
					top: position == 'top',
					center: position == 'center',
					bottom:	position == 'bottom'
				}
			})
		});

		// 2、创建实例挂载,dom保存到变量
		let tpl = new toastTpl().$mount().$el;

		// 3、把创建的dom添加到#app中
		document.getElementById("app").appendChild(tpl);

		//4、 延迟2.5秒后移除该dom
		setTimeout(function() {
			document.getElementById("app").removeChild(tpl);
		}, 2500)
	}
}
export default Toast;

// plugin/toast.vue
<template>
	<transition name="fade">
		<div class="vue-toast" v-show="show">
			{{tips}}
		</div>
	</transition>
</template>

<script>
	export default {
		props: ['tips'],
		data() {
			return {
				show: false
			}
		},
		mounted() {
			this.show = true;
			setTimeout(() => {
				this.show = false;
			}, 2000);
		}
	}
</script>

<style>
	.vue-toast {
		position: absolute;
		padding: 8px 10px;
		background: #000;
		opacity: 0.9;
		color: #FFF;
		border-radius: 8px;
	}

	.top {
		top: 20px;
		left: 50%;
		transform: translateX(-50%);
	}

	.center {
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
	}

	.bottom {
		bottom: 20px;
		left: 50%;
		transform: translateX(-50%);
	}

	.fade-enter-active,
	.fade-leave-active {
		transition: opacity 0.5s;
	}

	.fade-enter,
	.fade-leave-to {
		opacity: 0;
	}
</style>

调用相关:

// main.js
import Toast from './plugin/toast.js'
Vue.use(Toast)

// App.vue
<template>
	<div id="app">
		<button @click="jump()">弹出</button>
	</div>
</template>

<script>
	export default {
		methods: {
			jump() {
				this.$toast("这是我自己的写的吐司", 'bottom');
			}
		}
	}
</script>

运行:
在这里插入图片描述
 

相关资料

Vue-render函数的三个参数
对Vue中 runtime-compiler 和 runtime-only 两种模式的理解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值