vue 3.0 封装一个message提示组件
前言vue2.x中,可以使用 Vue.extends 来封装一个弹框,在vue 3.0中,该api已经被废除。本篇文章使用了typescript,如果不需要,只需要把ts部分去掉即可,实现效果图放在文章末尾。实现后使用方式: Message.info(‘提示’); Message.error(‘错误’);附上vue3.0文档:Vue3中文文档 - vuejs1.新建一个ts文件注:createAp
·
前言
vue2.x中,可以使用 Vue.extends 来封装一个弹框,在vue 3.0中,该api已经被废除。
实现后使用方式: Message.info(‘提示’); Message.error(‘错误’);
本篇文章使用了typescript,如果不需要,只需要把ts部分去掉即可,实现效果图放在文章末尾。
附上vue3.0文档:Vue3中文文档 - vuejs
1.修改index.html
注: 添加 < div id=“message”></ div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<div id="message"></div>
<!-- built files will be auto injected -->
</body>
</html>
2.新建一个index.ts文件
注:
- 使用class类方式来写调用方法。
- createApp(组件) mount(id / class / div), 可以参考main.ts。
- h函数第一个参数是组件,第二个是组件的props,第三个是插槽的属性。
import { createApp, h, ref, reactive } from 'vue';
// 注意这里替换成存放路径
import MessageComponent from './MessageComponent.vue';
// 初始消息列表
interface MessageList {
type: string;
title: string;
}
const messageList = reactive<MessageList[]>([]);
// 消息显示时长
const timer = ref<number>(3000);
// 处理数据
function handleData(type: string, title: string): void {
// 数据添加
messageList.push({ type, title });
// 数据删除
setTimeout(() => {
if (messageList.length > 0) {
messageList.shift();
}
}, timer.value);
// 创建
const app = createApp({
render() {
return h(MessageComponent, { messageList });
}
});
// 容器挂载
app.mount('#message');
}
interface MessageImplements {
info(title: string): void;
wraning(title: string): void;
success(title: string): void;
error(title: string): void;
}
class MessageClass implements MessageImplements {
// 普通提示
info(title: string): void {
handleData('info', title);
}
// 警告提示
wraning(title: string): void {
handleData('wraning', title);
}
// 成功提示
success(title: string): void {
handleData('success', title);
}
// 错误提示
error(title: string): void {
handleData('error', title);
}
}
const Message = new MessageClass();
export default Message;
3.MessageComponent.vue, 弹框内容部分
注:< script lang=“ts” setup=“props”></ script> 是 setup(){} 入口函数的语法糖写法(实验性新特性)
<template>
<ul class="message-list">
<li
:class="`message-item ${setClass(item.type)}`"
v-for="(item, index) in messageList"
:key="index"
>
{{ item.title }}
</li>
</ul>
</template>
<script lang="ts" setup="props">
import { reactive } from 'vue';
interface MessageList {
type: string;
title: string;
}
declare const props: {
messageList: {
type: Array<MessageList[]>;
default: [];
};
};
export function setClass(type: string): string {
if (type === 'info') {
return 'message-info-item';
} else if (type === 'wraning') {
return 'message-wraning-item';
} else if (type === 'success') {
return 'message-success-item';
} else if (type === 'error') {
return 'message-error-item';
}
return '';
}
</script>
<style lang="less" scoped>
.message-list {
position: fixed;
top: 24px;
right: 24px;
z-index: 1000;
max-width: 200px;
margin-bottom: 0;
text-align: right;
.message-item {
display: inline-block;
padding: 12px 24px;
border: 1px solid #b3d0cf;
margin-left: 8px;
margin-bottom: 12px;
background-color: #e6f3ff;
font-size: 14p;
color: #007bff;
text-align: left;
box-shadow: 0 1px 1px 0 hsla(0, 0%, 80.4%, 0.5);
border-radius: 2px;
cursor: default;
}
.message-info-item {
border: 1px solid #b3d0cf;
background-color: #e6f3ff;
color: #007bff;
}
.message-error-item {
border: 1px solid #e99;
background-color: #f6e3e3;
color: #e33;
}
}
</style>
使用
<template>
<button @click="clickMe">点我</button>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
// 注意这里替换成存放路径
import Message from '@components/message/index.ts';
export default defineComponent({
setup() {
function clickMe(): void {
Message.info('详情跳转');
}
return {
clickMe
};
}
});
</script>
效果图
如果本篇文章对你有帮助的话,很高兴能够帮助上你。
当然,如果你觉得文章有什么让你觉得不合理、或者有更简单的实现方法又或者有理解不来的地方,希望你在看到之后能够在评论里指出来,我会在看到之后尽快的回复你。
更多推荐
已为社区贡献18条内容
所有评论(0)