Vue3 封装命令式组件

414 字
2 分钟
Vue3 封装命令式组件

前言#

命令式组件就是通过 $message()、ElMessage() 这种方式调用的组件,而不是在模板里写 <Message />。

创建命令式组件#

<script setup>
import { ref } from "vue";
const messageShow = ref(false);
function showMessage(text) {
messageShow.value = true;
}
function closeMessage() {
messageShow.value = false;
}
defineProps({
message: String,
close: {
type: Function,
default: () => {
messageShow.value = false;
},
},
});
</script>
<template>
<div v-if="messageShow">{{ message }}</div>
</template>

创建调用函数#

import MessageBox from "./MessageBox.vue";
import { createApp } from "vue";
export default function(text, handler) {
const app = createApp(MessageBox, {
message: text,
close: () => {
handler?.();
app.unmount();
document.body.removeChild(div);
},
});
const div = document.createElement("div");
app.mount(div);
document.body.appendChild(div);
return {
close() {
app.unmount();
document.body.removeChild(div);
},
};
}

使用#

const msg = showMessage("你好");
msg.close(); // 手动关闭

缺陷#

这种方式创建的组件无法接收组件内的状态更新,比如子组件要主动关闭时,close 函数无法被正确调用。需要借助 reactive 或其他方式传递上下文。

方式二:基于回调函数#

<script setup>
import { ref } from "vue";
const messageShow = ref(false);
const messageText = ref("");
function showMessage(text, onClose) {
messageText.value = text;
messageShow.value = true;
}
function closeMessage() {
messageShow.value = false;
onClose?.();
}
defineProps({
text: String,
});
defineExpose({ showMessage, closeMessage });
</script>
<template>
<div v-if="messageShow">{{ text }}</div>
</template>

使用#

import Message from "./Message.vue";
import { createApp } from "vue";
function showMessage(text, onClose) {
const div = document.createElement("div");
const app = createApp(Message, {
text,
onClose,
});
app.mount(div);
document.body.appendChild(div);
}

缺陷#

每次调用都会创建新的组件实例和 DOM 节点,且不支持多个消息同时存在。

总结#

方式优点缺点
方式一简单直观无法接收子组件状态更新
方式二支持回调每次调用都创建新实例,无法同时显示多个

实际项目中,通常会结合发布订阅模式或单例模式来优化这些问题。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
Vue3 封装命令式组件
https://blog.ddlyt.top/posts/2026/0420/
作者
兜兜里有糖
发布于
2026-04-20
许可协议
CC BY-NC-ND 4.0

评论区

Profile Image of the Author
兜兜里有糖
越努力,越幸运。
公告
欢迎来到 DBlog,这里记录前端开发、技术学习和一些实用工具。
分类
标签
最新动态
站点统计
文章
20
分类
2
标签
18
总字数
12,351
运行时长
0 天
最后活动
0 天前
访问次数
--
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v2.0.0
文章许可
CC BY-NC-ND 4.0
文章目录