更新
的确不对,应该写个插件,然后使用inject 和 provide进行调用
新建组件 Message.vue
<template>
<div class="messages ">
<div class="message " v-for="item in messages">
<div class="content">
<div :class="item.style"></div>
{{ item.value }}</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive } from 'vue';
const props = defineProps({
myProvide: {
type: Function,
required: true
},
})
onMounted(()=>{
props.myProvide('$message', showMessage)
})
const messages:MessageCustomInterface[] = reactive([])
const clearFirstMessage = ()=>{
setTimeout(()=>{
if(messages.length>0) messages.splice(0,1)
},3000)
}
const success =(content:string)=>{
updateMessage(content,'success')
}
const warning =(content:string)=>{
updateMessage(content,'warning')
}
const error =(content:string)=>{
updateMessage(content,'error')
}
const showMessage = {
success:success,
warning:warning,
error:error,
}
const updateMessage = (content:string,type:string)=>{
messages.push({
value:content,
style:type
})
clearFirstMessage()
}
defineExpose({
success,
warning,
error
})
</script>
<style lang="less" scoped>
.messages{
margin: 20px auto;
line-height: 30px;
height: 30px;
text-align: center;
.message{
margin-top: 30px;
.content{
display: inline-block;
padding-left: 10px;
padding-right: 20px;
font-size: 14px;
background-position: left 10px top 5px;
background-size: 20px 20px;
background-color: #1A3D96;
// border: 1px solid #4573d679;
border-radius: 6px;
color: #fff;
background-repeat: no-repeat;
// box-shadow: 0 0 0 20px inset #285EE5;
box-shadow: 0px 0px 10px 0px rgba(40, 94, 229, 0.7);
div{
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
margin-right: 10px;
}
}
}
}
.success{
background-image: url(@/assets/custom/info.png);
color: #4DE4FF;
}
.warning{
color: orange;
background-image: url(@/assets/custom/warning.png);
}
.error{
background-image: url(@/assets/custom/error.png);
color: #ff0000;
}
</style>
新建插件
import Message from '@/components/custom/Message';
import { createApp } from 'vue'
export default {
install: (app, options) => {
const myProvide = app.provide;
const messageConstructor = createApp(MessageCustom,{myProvide});
const panel = document.createElement('div')
panel.className = 'message_overall';
panel.id = 'message_overall';
document.body.appendChild(panel);
const message_overall = document.getElementById('message_overall')
const messageOverall = messageConstructor.mount(message_overall);
app.config.globalProperties.$messageOverall = messageOverall;
}
}
组件引用
import { inject } from 'vue';
const $message:any = inject("$message");
$message.success("成功!!!")
不知道能不能用hooks实现
以下是原文
我不知道我这个对不对,映像里好像不建议直接操作dom,但我一下想不到别的方式 如果我思路不对或者有什么可以改进的地方希望大佬提示下
定义
class MessageBox {
constructor(){
const panel = document.createElement('div')
panel.className = 'message_overall'
panel.id = 'message_overall'
document.body.appendChild(panel)
this.message_overall = document.getElementById('message_overall')
}
getDom(class_name,content ){
const div = document.createElement('div')
div.className = class_name;
div.innerHTML = `
<div class="content">${content}</div>
`
return div
}
success(content){
const dom = this.getDom('message success',content)
this.message_overall.insertBefore(dom,this.message_overall.childNodes[0])
this.clearDom()
}
warning(content){
const dom = this.getDom('message warning',content)
this.message_overall.insertBefore(dom,this.message_overall.childNodes[0])
this.clearDom()
}
error(content){
const dom = this.getDom('message error',content)
this.message_overall.insertBefore(dom,this.message_overall.childNodes[0])
this.clearDom()
}
clearDom(){
setTimeout(()=>{
this.message_overall.removeChild(this.message_overall.lastElementChild)
},3000)
}
}
export const messageOverall = new MessageBox();
main.js 里面导入
import { createApp } from 'vue'
import App from './App.vue'
import {messageOverall} from '@/utils/model'
import router from './router'
const app = createApp(AsyncApp);
window.$messageOverall = messageOverall
// app.config.globalProperties.$messageOverall = messageOverall; // 不知道为啥无效
app.use(router).mount('#app')
样式我随便写的
.message_overall{
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
pointer-events: none;
.message{
margin: 20px auto;
line-height: 30px;
height: 30px;
text-align: center;
.content{
display: inline-block;
background-color: black;
padding-left: 10px;
padding-right: 40px;
}
}
.success{
color: #00ff00;
}
.warning{
color: orange;
}
.error{
color: #ff0000;
}
}
使用
<template>
<button @click="messageTip('success')">全局提示-成功</button>
<button @click="messageTip('warning')">全局提示-失败</button>
<button @click="messageTip('error')">全局提示-报警</button>
</template>
<script setup>
const messageTip = (type)=>{
$messageOverall[type]('体魄提示'+type)
}
</script>