Vue中可以根据需要去加载插件,一些自己写的插件在多个项目中都是需要用到的,通过把它们插件化,可以实现在需要用到的项目中便捷地复用,实现热拔插。
以弹窗表单组件为例,平常我们使用弹窗组件都是通过页面中引入dialog组件,然后用一个visible参数去控制显示隐藏,还要加入一些打开关闭的方法。因此,在每个需要弹窗的地方都需要这么操作:(引入组件并祖册、添加一个控制显隐的参数visible、添加一个open方法和一个close方法),虽然用着没什么毛病......
但是,这样子会存在一些问题:
①每当我们需要使用,都需要复制粘贴这么多东西,
②在改变显隐逻辑的时候,还需要查找一下代码中所有出现visible的地方,梳理一下如何控制,
③每次搬走弹窗的时候,不仅仅要搬走组件,还要搬走参数、方法。
这个过程相当繁琐,也容易出错
1.首先,在写好了弹窗表单组件之后,在该文件夹下再新建一个dialog.js文件,写入以下内容:
import component from './index.vue'
function useDialogWrap(Vue) {
Vue.prototype.$dialogwrap = (options => {
// vue.extend(options):使用基础 Vue 构造器,通过原型继承,创建一个“子类”,参数是一个包含组件选项的对象。
let Constructor = Vue.extend(component)//继承弹窗组件
// 创建组件实例
let instance = new Constructor()
// 将插槽内容传递给组件
if (options.slots) {
instance.$slots = options.slots
}
// 挂载时,编译组件,挂载到一个元素上
instance.$mount()
// 将编译后的组件挂载到 body 下
document.body.appendChild(instance.$el)
// 指令式调用时,添加 isFunctional 为 true 标识
Object.assign(instance, options, { isFunctional: true })
// 立即展示弹窗
return instance.show()
})
}
// 暴露使用方法
export default useDialogWrap
// 创建弹窗组件实例
// 继承选项插槽内容
// 编译,挂载弹窗到 body
// 合并组件选项
// 显示弹窗
ps:关于全局使用插件,为了不让main.js的代码过于臃肿,选择了在这里进行使用。
2.接着,来到plugins下的modules文件夹下,新建一个components.js文件,写入以下内容:
// 导入刚刚暴露出来的方法
import useDialogWrap from "@/components/DialogWrap/index.js"
// Vue.js 的插件应该暴露一个 install 方法。
export default {
install(Vue) {
useDialogWrap(Vue)
}
}
3.之后,在plugins下新建一个index.js文件,写入以下内容(只需要写一次,它对modules里面已有的所有自定义的插件都已经做了遍历):
import Vue from 'vue'
// require.context返回modules文件夹下所有的文件对象,参考https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)
/*
*通过直接获取modules文件夹下的所有文件添加进入modules对象
*回调函数参数:
*modules:文件对象
*modulePath:文件路径
*/
modulesFiles.keys().reduce((modules, modulePath) => {
// 获取文件名称
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
// 获取路径保存在modulePath文件内容
const value = modulesFiles(modulePath)
// 修改modules对象
modules[moduleName] = value.default
// 过全局方法 Vue.use() 使用插件。Vue.use 会自动阻止多次注册相同插件,届时即使多次调用也只会注册一次该插件。
Vue.use(value.default)//它需要在你调用 new Vue() 启动应用之前完成
return modules
}, {})
5.来到main.js里面,把刚刚用来遍历并使用插件的index.js导进来
import '@/plugins/index.js'
6.在页面中进行使用
this.$dialogwrap({
// 传入组件透传属性
attrs: that.$attrs,
// 弹窗事件
on: {
click: () => that.clickTest(),
},
//插槽内容
slots: {
content: ' content 插槽组件',
},
// 弹窗标题
title: "测试弹窗",
// 弹窗表单数据
data: {
test: "测试数据",
},
// 弹窗表单配置项
items:[]
}).then((comfirm) => {
console.log("===dialogwrap=comfirm=", comfirm);
}).catch((cancel) => {
console.log("===dialogwrap=cancel=", cancel);
});
至此,我们就已经完成了把组件变成插件化使用的所有操作步骤。
1.减少代码量,提高可读性。
将组件进行配置化,可以让代码量大大减少,也更容易定位各项内容。
2.提高可复用性和可维护性
由于这样操作之后,代码块更加集中了,耦合度也降低了,更容易迁移,在需求发生变动的时候也更加方便在对应位置进行更改。
3.使用方便
我们只需要对弹窗组件进行一些配置,不再需要牵一发而动全身,使用起来更加方便。