vue3+ts项目自定义message组件

  • 应用场景
  可以实现vue2通过this.$message({})调用element-ui的信息提示组件效果
  • 实现思路
  通过操作dom的增加和删除节点来控制组件的显示与隐藏
  • 举例文件
    • 组件vue页面

      目前组件只支持三种信息提示类型(type:success,error,info),持续时间(duration),显示信息(message)

<template>
    <transition name="el-fade-in">
        <div :id="id" class="nc_message_container" v-if="isVisible">
            <CircleCheck v-if="type=='success'" style="width: 1em; height: 1em; margin-right: 8px" />
            <Warning v-if="type=='info'" style="width: 1em; height: 1em; margin-right: 8px" />
            <CircleClose v-if="type=='error'" style="width: 1em; height: 1em; margin-right: 8px" />
            {{ message }}
        </div>
    </transition>
</template>
<script setup lang="ts">
import {CircleCheck,Warning,CircleClose} from '@element-plus/icons-vue'
import { watch, ref } from 'vue';
const props = defineProps({
    message: {
        type: String,
        default: ''
    },
    duration: {
        type: Number,
        default: 1500
    },
    type:{
        type:String,
        default:'info'
    }
});
let isVisible = ref(false);
let id = ref('');

watch(
    () => isVisible,
    newVal => {
        if (newVal) {
            setTimeout(() => {
                let remoel = document.getElementById(id.value);
                remoel && document.body.removeChild(remoel);
            }, props.duration);
        }
    },
    { immediate: true }
);
</script>
<style scoped>
.nc_message_container {
    font-size: 14px;
    padding: 2px 60px;
    border-radius: 6px;
    background: rgba(250, 128, 114, 0.8);
    color: white;
    display: flex;
    flex-direction: row;
    align-items: center;
    position: fixed;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    box-shadow: 0px 2px 6px 0px rgba(102,102,102,0.1);
}
</style>
    • 组件封装ts文件
import {App,createApp} from 'vue'
import NcMessage from './Index.vue'

function appendToBody(app:APP<any>){
    const el=document.createElement('div')
    document.body.appendChild(el)
    app.mount(el)
    if(el.firstChild){
        document.body.appendChild(el.firstChild)
    }
    document.body.removeChild(el)
}
function mount(node:any){
    let idNum=10
    const nodeHandler:any=(options:{[key:string]:any})=>{
        setTimeout(()=>{
            const messageNode=createApp({
                ...node,
                mounted(){
                    const id='message_'+idNum++
                    this.isVisible=true
                    this.$el.id=id
                    this.id=id
                }
            },options)
            appendToBody(messageNode)
        })
    }
    return nodeHandler
}

export default{
    install(app:App){
        app.config.globalProperties.$message=mount(NcMessage)
    }
}
    • 入口文件main.ts  
...
import message from './components/NcMessageV3/index.ts'
...
app.use(message)
    • 调用示例页面  
const { proxy } = getCurrentInstance()  as any
...
proxy.$message({
        message:'Past life could never hold me down ~',
        duration:2000,
        type:'success'
    })
    • 实现效果  

 

 

posted @ 2022-10-13 19:46  南无、  阅读(843)  评论(0)    收藏  举报