通过 Vite 实现 Uniapp 全局自定义 Toast !

1,494 阅读2分钟

Root

借助 Vite 模拟出虚拟的全局组件,解决 uniapp 无根组件导致无法使用全局共享组件问题

🤔 问题

对于Vue很熟悉的你,曾经是否认为,要实现一个全局共享的组件,为什么不能跟 VueRouter 中一样,直接放在 App.vue 下呢?但是介于 Uniapp 无法使用 Template Block而止步于此

🐣 诞生

针对以上问题,@uni-ku/root 孕育而生,Ta是借助 Vite 模拟出虚拟的全局共享组件,解决 Uniapp 无法使用全局共享组件问题的库

现阶段,你可以放入任意想让其成全局共享的组件,如:Toast | Loading | LoginModal 组件等等!

注意:从 v0.1.0 起,不再支持 App.vue 而是采用 App.ku.vue,这一改进修复了无法使用SFC问题、无法热更新问题,PageMeta无法正常渲染问题,使 @uni-ku/root 功能更加强大

📦 安装

pnpm add -D @uni-ku/root@latest

🚀 使用

  1. 引入 @uni-ku/root
// vite.config.*

import { defineConfig } from 'vite'
import UniKuRoot from '@uni-ku/root'

export default defineConfig({
  plugins: [
    // 若存在改变 pages.json 的插件,请将 UniKuRoot 放置其后
    UniKuRoot()
  ]
})
  1. 根目录下创建 App.ku.vue 并添加全局所需组件或代码

通过标签 <KuRootView /><ku-root-view /> 实现指定共享组件存放位置,该功能与 VueRouter 中的 RouterView 实现类似

从 v0.1.0 起,现已完全支持 VueSFC

<!-- App.ku.vue -->

<script setup lang="ts">
import { ref } from 'vue'
import GlobalToast from './components/GlobalToast.vue'

const helloVueRef = ref('test')
</script>

<template>
  <div>Hello AppKuVue</div>
  <KuRootView />
  <div>{{ helloVueRef }}</div>
  <GlobalToast />
</template>

✨ 例子

  1. 编写 Toast 组件
// src/components/GlobalToast.vue

<script setup lang="ts">
import { useToast } from '@/composables/useToast'

const { globalToastState, hideToast } = useToast()
</script>

<template>
  <div v-if="globalToastState" class="toast-wrapper" @click="hideToast">
    <div class="toast-box">
      welcome to use @uni-ku/root
    </div>
  </div>
</template>

<style scoped>
.toast-wrapper{
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}

.toast-box{
  background: white;
  color: black;
}
</style>

  1. 实现调用 Toast 组合式API
// src/composables/useToast

import { ref } from 'vue'

const globalToastState = ref(false)

export function useToast() {
  function showToast() {
    globalToastState.value = true
  }

  function hideToast() {
    globalToastState.value = false
  }

  return {
    globalToastState,
    showToast,
    hideToast,
  }
}

  1. 挂载共享
// App.ku.vue
<script setup lang="ts">
import GlobalToast from '@/components/GlobalToast.vue'

const helloVueRef = ref('test')
</script>

<template>
  <KuRootView />
  <GlobalToast />
</template>
  1. 任意页面下触发 Toast
// src/pages/xxx.vue

<script setup lang="ts">
import { useToast } from '@/composables/useToast'

const { globalToastState, showToast, hideToast } = useToast()

function handleClick() {
  return globalToastState.value ? hideToast() : showToast()
}
</script>

<template>
  <view>
    Hello UniKuRoot
  </view>
  <button @click="handleClick">
    展示Toast
  </button>
</template>

enjoy ❤

📝 待办

  • 支持热更新
  • 支持VueSFC
  • 支持小程序PageMeta
  • 补全单元测试

📫 项目地址

欢迎各位朋友的 Issue 与 PR

如果对此项目感到兴奋,可以点个 star ⭐💜