插件一般用来为 Vue 添加全局功能,通常有下面几种:html
Vue.prototype
上实现。更加详细说明查看官网文档 https://cn.vuejs.org/v2/guide...vue
1.简单的插件
建立一个countdown.vuewebpack
<template> <div>封装一个最简单的插件</div> </template> <script> export default { name: 'count-down' } </script>
建立一个index.jsweb
import countDown from './countdown'; //暴露一个 `install` 方法。这个方法的第一个参数是 `Vue` 构造器,第二个参数是一个可选的选项对象 countDown.install = function (Vue) { Vue.component(countDown.name, countDown); }; export default countDown;
目录结构为:数组
在main.js中引入,页面中<count-down></count-down>
就能够使用less
import countDown from './components/global/index'; //经过全局方法 `Vue.use()` 使用插件 Vue.use(countDown);
2.添加全局方法或属性ide
countDown.install = function (Vue) { Vue.prototype.$msg = '全局的属性'; Vue.prototype.$myMethod = function () { console.log('全局定义的方法'); } Vue.component(countDown.name, countDown); };
3.添加全局资源函数
countDown.install = function (Vue) { //全局自定义指令 Vue.directive('focus', { //当节点插入的时候 inserted: function (el) { el.focus(); } }) Vue.component(countDown.name, countDown); };
4.注入组件选项flex
countDown.install = function (Vue) { //全局混入 Vue.mixin({ created() { console.log('i am jello') }, }) Vue.component(countDown.name, countDown); };
建立一个VsButton.vueui
<template> <button class="vs-button" :class="type" @click="fn"> <slot></slot> </button> </template> <script> export default { name: 'VsButton', props: { type: { type: String, default: 'warning' } }, methods: { fn() { this.$emit('click'); } }, } </script> <style lang='less' scoped> .vs-button { width: 100px; height: 40px; background: #ccc; border-radius: 4px; } .warning { background: yellow } .danger { background: red } .success { background: green } </style>
建立VsMsg.vue
<template> <transition name="fade"> <div class='vs-msg' v-show='visible'> <img src='../../../assets/msg.png' class='pic' /> <span class='msg-text' @click='close'> <slot></slot> </span> </div> </transition> </template> <script> export default { name: 'VsMsg', props: { visible: { type: Boolean, default: false } }, methods: { close() { this.$emit('update:visible', false); } }, } </script> <style lang='less' scoped> .vs-msg { width: 330px; min-height: 280px; display: flex; flex-direction: column; padding: 30px; background: #eee; .pic { width: 100%; height: 200px; } .msg-text { height: 80px; line-height: 80px; background: rgba(255, 255, 255, 1); border-radius: 0px 0px 10px 10px; font-size: 16px; color: rgba(255, 162, 26, 1); } } .fade-enter-active, .fade-leave-active { transition: opacity .3s ease; } .fade-enter, .fade-leave-to { opacity: 0; } </style>
建立一个index.js
import VsMsg from '../plugins/msg/VsMsg'; import VsButton from '../plugins/button/VsButton'; let plugin = {}; plugin.install = function (Vue) { Vue.component(VsMsg.name, VsMsg); Vue.component(VsButton.name, VsButton); } export default plugin;
每次使用都须要import和Vue.component(),可采用webpack的require.context(),实现自动导入和注册组件。
1)require.context函数接受三个参数:
2)require.context函数执行后返回的是一个函数,而且这个函数有3个属性
const requireComponent = require.context('./', true, /\.vue$/); //获取一个特定的上下文,主要用来实现自动化导入模块 const install = (Vue) => { if (install.installed) return; install.installed; requireComponent.keys().forEach(fileName => { //第i个组件 const config = requireComponent(fileName); //组件名 const componentName = config.default.name; Vue.component(componentName, config.default || config); }) } //检测环境 if (typeof window !== undefined && window.Vue) { install(Vue); } export default install;
在main.js中引入
import index from "./components/plugins/index.js"; Vue.use(index);
页面中使用插件
<template> <VsButton type='warning' @click="open">默认按钮</VsButton> <VsMsg :visible.sync="visible">我是一个消息</VsMsg> </template> <script> export default { data() { return { visible: false }, methods: { open() { this.visible = true; } } } </script>
实现效果以下: