Remember a custom message pop-up window pit

To achieve the goal, call a message box through $message to customize the content and set the duration.
Insert picture description here
First customize a message component

<template>
    <transition name="fade">
        <div class="dialog" v-if="show">
            <span>{
    
    {
    
    message}}</span>
        </div>
    </transition>
</template>

<script>
    export default {
    
    
        name: "Cdialog",
        data(){
    
    
            return{
    
    
                show:false
            }
        },
        props:{
    
    
            title:{
    
    
                type:String
            },
            message:{
    
    
                type:String
            },
            duration:{
    
    
                type:Number,
                default:()=>{
    
    
                    return 1000
                }
            }
        },
        methods:{
    
    
            onhide(){
    
    
                this.show = false 
                setTimeout(()=>{
    
    
                    this.remove()
                },500)
            },
            onshow(){
    
    
                this.show = true
                setTimeout(this.onhide,this.duration)
            },
        }
    }
</script>

<style scoped>
.fade-enter-active, .fade-leave-active {
    
    
    transition: all 0.5s;
}
.fade-enter, .fade-leave-to {
    
    
    transform: translateY(-20px);
    opacity: 0;
}
.dialog{
    
    
    background-color: white;
    position:fixed;
    top:100px;
    left:40%;
    right:40%;
    padding:10px 20px;
    border: #61ff00 solid 1px;
    box-shadow: 0 0px 2px #61ff00;
    border-radius: 10px;
}
</style>

Directly mount a method to call it globally. After thinking for a long time, I think this pop-up window should be at the same level as the outermost mounted app, and I have to convert this vue to real dom and append it to the body. I just want to use Vue directly. The createElement method to generate a real dom, which is render: h => h(Cdialog,{props}), and then mount the generated real dom to the body, try

function showMsg(props){
    
    
  const vm = new Vue({
    
    
    render:h => h(Cdialog,{
    
    props})
  }).$mount(document.body)
  const comp = vm.$children[0]
  comp.remove = ()=>{
    
    
    document.body.removeChild(vm.$el)
    vm.$destroy()
  }
  comp.onshow()
  return comp
}

The effect is there, but the elements in the original body are replaced, which creates a problem, because the message pop-up window component must undergo an update process when accepting parameters, but the mounted and update methods must also be mounted The update method will be executed after mounting. A virtual mounting method is used here, that is, the node in the mount is removed, and only the mounting method is executed. This can also play an update method and modify the code:

function showMsg(props){
    
    
  const vm = new Vue({
    
    
    render:h => h(Cdialog,{
    
    props})
  }).$mount()
  document.body.appendChild(vm.$el)
  const comp = vm.$children[0]
  comp.remove = ()=>{
    
    
    document.body.removeChild(vm.$el)
    vm.$destroy()
  }
  comp.onshow()
  return comp
}
Vue.prototype.$message = showMsg

The operation was successful without an error. It seemed to be successful, but when I checked the dom module, I found a problem.
Insert picture description here
Although the pop-up box has been hidden, it was not executed by the remove method. The settimeout in the hide method was removed. Wrong, the problem is that when the show becomes false, the dom here does not exist anymore, causing the remove method after 0.5s to fail to find the dom node and cause memory loss. There are two solutions, one is the most Embed a layer of div in the outer layer or change v-if="show" to v-show.

Guess you like

Origin blog.csdn.net/qq_37195804/article/details/106872387