一、介绍
vue-create-api 是一个能够让 Vue 组件通过 API 方式调用的插件,通常用在 dialog 组件上。
二、安装
npm i -S vue-create-api
三、完整示例
1、创建 customerDialog 组件
<template>
<el-dialog
title="提示"
:visible.sync="dialogVisible"
@close="handleClose"
>
<span>{{content}}</span>
<span slot="footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
name: "customerDialog",
props: {
content: String,
},
data() {
return {
dialogVisible: false,
}
},
methods: {
show() {
this.dialogVisible = true;
},
handleClose() {
// 多例模式才需要销毁弹窗
// 如果不想去外部销毁(即不$emit('close')),可以在 el-dialog 上设置 v-if="dialogVisible",但这样的话每次弹窗调用后会在 body 下留下一行注释,DOM 和组件删除的不彻底。
this.$emit('close');
},
}
}
</script>
2、用 createAPI 封装组件
import CreateAPI from 'vue-create-api';
import CustomerDialog from './components/customerDialog.vue';
Vue.use(CreateAPI)
// 调用 createAPI 生成对应 API,并挂载到 Vue.prototype 和 Dialog 实例上
// 第2个参数:是否采用单例模式实例化组件。
// 如果采用单例模式,每次弹窗弹出用的都是同一个实例,弹出组件的 created, mounted 这些生命周期只会执行一次。
// 如果采用多例模式,每次弹窗弹出时都会重新生成一个弹窗。
Vue.createAPI(CustomerDialog, false);
3. 在业务场景中使用
/* 使用方式一:在普通的 js 文件中使用 */
import CustomerDialog from './components/customerDialog.vue';
CustomerDialog.$create({
$props: {
content: 'I am from pure JS'
}
}).show();
/* 使用方式二:在 vue 组件内调用 */
const instance = this.$createCustomerDialog({
// 组件的 Prop
$props: {
content: 'I am from a vue component'
},
// 组件的事件回调
$events: {
close: () => {
// instance.remove();
}
},
$attrs: {
id: 'customer-dialog'
},
$class: {
'my-class': true
},
}).show();
四、要点
- 组件必须定义 name 属性,例如,this.$createHello 里的 hello 就是组件名
- 调用 $create 方法时,组件会被添加到 body
- 调用 $create 方法返回组件实例,可以调用返回组件的 remove() 方法去销毁组件和删除添加到 body 下DOM元素
五、避坑指南
1. 如果在调用 $create 时,$create 报错 undefined 时可以这么处理:
import Vue from 'vue';
export const useCreateApi = (Component, single = true) => {
if (Component?.$create) {
return Component;
}
Vue.createAPI(Component, single);
return Component;
};
useCreateApi(CustomerDialog).$create().show();
2. $createCustomerDialog 的 $props 传入的值是对象时,CustomerDialog 组件内拿到的会出现不是最新的值。
解决办法:
参数通过 show() 传入,而不用 $props 传入。