首頁 > 軟體

vue3封裝Notification元件的完整步驟記錄

2022-03-31 16:00:57

跳過新手教學的小白,很多東西都不明白,不過是為了滿足一下虛榮心,寫程式碼的成就感

彈窗元件的思路基本一致:向body插入一段HTML。我將從建立、插入、移除這三個方面來說我的做法

先來建立檔案吧

|-- packages
    |-- notification
        |-- index.js # 元件的入口
        |-- src
            |-- Notification.vue # 模板
            |-- notification.ts

建立

用到h,render,h是vue3對createVnode()的簡寫。h()把Notification.vue變成虛擬dom,render()把虛擬dom變成節點。render在渲染時需要一個節點(第二個引數),建立一個只用來裝Notification.vue的容器,我要的只是Notification.vue裡面的HTML結構,所以建立了container先將vm變成節點,也就是HTML,這樣才能插到body中

import { h, render } from "vue"
import NotificationVue from "./Notification.vue"

let container = document.createElement('div')
let vm = h(NotificationVue)
render(vm, container)

懵逼點:為什麼.vue檔案在App.vue中能渲染出來,在這裡需要先轉成虛擬dom再轉成節點

插入

通過document.body.appendChild把這個節點內的第一個子元素插入body中,這樣就能在頁面上顯示出來了。

document.body.appendChild(container.firstElementChild)

移除

vue不能直接操作dom,只能操作虛擬dom了,用null覆蓋掉原來的內容即可

render(null, container)

沒懂vue實現原理也只是把效果做出來而已,網上查閱資料也差不多一個月了才做出來,看來我確實不適合程式設計

完整程式碼

// Notification.vue
<template>
  <div class="notification">
    Notification
    <button @click="onClose">x</button>
  </div>
</template>

<script setup lang="ts">
interface Props {
  onClose?: () => void
}

defineProps<Props>()
</script>

有個疑問為什麼.vue檔案在app中又能直接被渲染出來

// notification.ts
import { h, render } from "vue"
import NotificationVue from "./Notification.vue"
const notification = () => {
  let container = document.createElement('div')
  let vm = h(NotificationVue, {onClose: close})
  render(vm, container)
  document.body.appendChild(container.firstElementChild)

  // 手動關閉
  function close() {
    render(null, container)
  }
}
export default notification

在App.vue中使用

// App.vue
<script setup lang="ts">
import {
  BNotification
} from "../packages"

BNotification()
</script>

總結

到此這篇關於vue3封裝Notification元件的文章就介紹到這了,更多相關vue3封裝Notification元件內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com