手摸手创建一个 Vue + Ts 项目(七)—— 封装全局反馈组件

598 阅读1分钟

系列目录

前言

NaiveUI 提供的反馈组件,如 MessageDialogNotification 等,使用时,并不是非常的直接方便,这里可以将其挂载到 window 下,然后再调用。

例如,想最终实现的效果如下:

window.$message.success("success message")

前期准备

由于使用的是 TypeScript,所以如果想要直接调用 window.$message 时会有警告信息,且也没有对应的 API 提示,这里需要先拓展下 window 对象。

首先,在根目录下,创建一个 types 文件夹,并在其下新建 window.d.ts 文件:

import { DialogApiInjection } from 'naive-ui/es/dialog/src/DialogProvider'
import { LoadingBarApiInjection } from 'naive-ui/es/loading-bar/src/LoadingBarProvider'
import { MessageApiInjection } from 'naive-ui/es/message/src/MessageProvider'
import { NotificationApiInjection } from 'naive-ui/es/notification/src/NotificationProvider'

declare global {
  interface Window {
    $message: MessageApiInjection
    $notification: NotificationApiInjection
    $dialog: DialogApiInjection
    $loadingBar: LoadingBarApiInjection
  }
}

在这里创建后,并不能直接使用,需要在 tsconfig.json 中指定该文件,将 tsconfig.jsoninclude 属性修改如下:

"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "types/**/*.d.ts"]

在后面,添加 types/**/*.d.ts 即可。

封装 Dialog 组件

src/components/AppProvider 文件夹下,创建 WindowDialog.ts 文件,将 useDialog 返回的对象挂载到 window 下:

import { useDialog } from 'naive-ui'
import { defineComponent } from 'vue'

export default defineComponent({
  setup() {
    window.$dialog = useDialog()
    return () => null
  }
})

封装 LoadingBar 组件

src/components/AppProvider 文件夹下,创建 WindowLoadingBar.ts 文件,将 useLoadingBar 返回的对象挂载到 window 下:

import { useLoadingBar } from 'naive-ui'
import { defineComponent } from 'vue'

export default defineComponent({
  setup() {
    window.$loadingBar = useLoadingBar()
    return () => null
  },
})

封装 Message 组件

src/components/AppProvider 文件夹下,创建 WindowMessage.ts 文件,将 useMessage 返回的对象挂载到 window 下:

import { useMessage } from 'naive-ui'
import { defineComponent } from 'vue'

export default defineComponent({
  setup() {
    window.$message = useMessage()
    return () => null
  },
})

封装 Notification 组件

src/components/AppProvider 文件夹下,创建 WindowNotification.ts 文件,将 useNotification 返回的对象挂载到 window 下:

import { useNotification } from 'naive-ui'
import { defineComponent } from 'vue'

export default defineComponent({
  setup() {
    window.$notification = useNotification()
    return () => null
  },
})

使用组件

src/components/AppProvider/AppProvider.vue 修改如下:

<template>
  <n-config-provider :locale="zhCN" :date-locale="dateZhCN" wh-full>
    <n-dialog-provider>
      <window-dialog />
      <n-notification-provider>
        <window-notification />
        <n-message-provider>
          <window-message />
          <n-loading-bar-provider>
            <window-loading-bar />
            <slot name="default" />
          </n-loading-bar-provider>
        </n-message-provider>
      </n-notification-provider>
    </n-dialog-provider>
  </n-config-provider>
</template>

<script setup lang="ts">
import { zhCN, dateZhCN } from "naive-ui";
import WindowDialog from "./WindowDialog";
import WindowLoadingBar from "./WindowLoadingBar";
import WindowMessage from "./WindowMessage";
import WindowNotification from "./WindowNotification";
</script>
<style scoped></style>

之后在使用时,就可以直接调用 window.$xxx 来使用了。例如:

<script setup lang="ts">
const showMessage = () => {
  window.$message.success('Show Message Success')
}
</script>

<template>
  <common-page>
    <div>
      <n-button @click="showMessage">Show Message</n-button>
    </div>
  </common-page>
</template>

<style scoped></style>