vue3 打造一個整個頁面都能直接使用的Alert組件

Vue3 Alert組件

需求

  1. 要能定義要顯示的文字
  2. 要能設定秒數
  3. 要能夠在任何地方直接使用不需要重新註冊
  4. 要能夠鍊式調用回調函式
  5. 動態出現與消除

知識點

  1. createApp(創建組件實例)
  2. mount(綁定到頁面上)
  3. unmount(從頁面上移除)
  4. install(如何寫vue插件)
  5. use(使用寫好的外掛)
  6. promise

組件

#Alert.vue
<template>
    <div>{{ message }}</div>
</template>
<script>
export default {
    name: 'Alert',
    props: {
        message: {
            type: String,
            default: '默認訊息'
        }
    }
}
</script>

app.use使用的js檔案

#index.js
import { createApp } from 'vue'
import Alert from './Alert.vue'

const alertPlugin = {}

function alert(message, time) {
    return new Promise((res) => {
    
        // 組件實例第一個參數接收組,件第二個接收props
        const instance = createApp(Alert, {
            message: message || 'message',
        })
        
        // 組件容器
        const parentNode = document.createElement('div')
        document.body.appendChild(parentNode)
        instance.mount(parentNode)
        
        // 組件解綁
        function unmount() {
            instance.unmount()
            document.body.removeChild(parentNode)
        }
        
        // 解綁定時器
        setTimeout(() => {
            unmount()
            res()
        }, time)
    })
}


//使用app.use時候會自動調用install屬性上的function
//參數中的Vue會自動傳進來
//options是app.use的第二個參數
export default alertPlugin.install = function (Vue, options) {
    let { name } = options
    //這裡設定的屬性在getCurrentInstance().proxy裡面可以找到
    Vue.config.globalProperties[name] = alert
}

插件引入

import { createApp } from 'vue'

import App from './App.vue'
import alertPlugin from './libs/Alert/index'
const app = createApp(App)

//這裡的第二個參數會傳給install裡面的第二個形式參數
app.use(alertPlugin, { name: '$alert' })
app.mount('#app')

使用

使用時候記得要引入getCurrentInstance才能拿到原型上的方法

<script setup>
import { getCurrentInstance } from 'vue';
let instance = getCurrentInstance()
//使用Vue.config.globalProperties實例上的方法在proxy裡面可以找到
instance.proxy.$alert('alert', 1000).then(() => {
  console.log('test')
})
</script>

參考

https://juejin.cn/post/7042907056843522085

https://segmentfault.com/q/1010000016082860

https://v3.cn.vuejs.org/api/global-api.html#createapp