feat: 重构 PrimeVue 相关插件,优化对话框和通知服务的使用,更新样式和组件结构
This commit is contained in:
@ -1,6 +1,14 @@
|
|||||||
|
.p-confirmdialog,
|
||||||
.p-toast {
|
.p-toast {
|
||||||
max-width: calc(100% - 50px);
|
max-width: calc(100% - 50px);
|
||||||
}
|
}
|
||||||
.p-toast .p-toast-message-text {
|
.p-toast .p-toast-message-text {
|
||||||
margin-top: -0.2rem;
|
margin-top: -0.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-floatlabel:has(.p-fileupload) label {
|
||||||
|
top: var(--p-floatlabel-over-active-top);
|
||||||
|
transform: translateY(0);
|
||||||
|
font-size: var(--p-floatlabel-active-font-size);
|
||||||
|
font-weight: var(--p-floatlabel-label-active-font-weight);
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useDialogRef } from '@/utils/primevue';
|
import { useDialogRef } from '@/plugins/primevue';
|
||||||
|
|
||||||
const dialogRef = useDialogRef();
|
const dialogRef = useDialogRef();
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts"></script>
|
<script lang="ts"></script>
|
||||||
|
|
||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
import { ConfirmationService, DialogService, ToastService, useDialogRef } from '@/utils/primevue';
|
import { ConfirmationService, DialogService, ToastService, useDialogRef } from '@/plugins/primevue';
|
||||||
import dialogContent from './dialog-content.vue';
|
import dialogContent from './dialog-content.vue';
|
||||||
|
|
||||||
const dynamicComponent = defineComponent({
|
const dynamicComponent = defineComponent({
|
||||||
@ -61,6 +61,7 @@ const openDialog = async () => {
|
|||||||
};
|
};
|
||||||
const openToast = () => {
|
const openToast = () => {
|
||||||
ToastService.add({ severity: 'info', summary: '提示', detail: '消息内容', life: 3000 });
|
ToastService.add({ severity: 'info', summary: '提示', detail: '消息内容', life: 3000 });
|
||||||
|
ToastService.add({ severity: 'info', summary: '提示', detail: '消息内容', life: 0 });
|
||||||
};
|
};
|
||||||
const openConfirm = async () => {
|
const openConfirm = async () => {
|
||||||
ConfirmationService.require({
|
ConfirmationService.require({
|
||||||
@ -77,11 +78,20 @@ const openConfirm = async () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onAdvancedUpload = () => {
|
||||||
|
ToastService.add({ severity: 'info', summary: 'Success', detail: 'File Uploaded', life: 3000 });
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="primevue">
|
<div class="primevue p-4 flex flex-wrap gap-6">
|
||||||
<InputText placeholder="请输入" />
|
<FloatLabel>
|
||||||
|
<InputText default-value="DEFAULT_VALUE" id="username" />
|
||||||
|
<label for="username">Username</label>
|
||||||
|
</FloatLabel>
|
||||||
|
|
||||||
|
<FloatLabel>
|
||||||
<Select
|
<Select
|
||||||
:options="[
|
:options="[
|
||||||
{ name: '纽约', code: 'NY' },
|
{ name: '纽约', code: 'NY' },
|
||||||
@ -91,11 +101,31 @@ const openConfirm = async () => {
|
|||||||
{ name: '巴黎', code: 'PRS' },
|
{ name: '巴黎', code: 'PRS' },
|
||||||
]"
|
]"
|
||||||
optionLabel="name"
|
optionLabel="name"
|
||||||
placeholder="选择城市"
|
|
||||||
class="min-w-[200px]"
|
class="min-w-[200px]"
|
||||||
/>
|
/>
|
||||||
|
<label>SELECT</label>
|
||||||
|
</FloatLabel>
|
||||||
|
|
||||||
<DatePicker dateFormat="dd/mm/yy" />
|
<FloatLabel>
|
||||||
|
<FileUpload
|
||||||
|
name="demo[]"
|
||||||
|
url="/api/upload"
|
||||||
|
@upload="onAdvancedUpload()"
|
||||||
|
:multiple="true"
|
||||||
|
accept="image/*"
|
||||||
|
:maxFileSize="1000000"
|
||||||
|
>
|
||||||
|
<template #empty>
|
||||||
|
<span>Drag and drop files to here to upload.</span>
|
||||||
|
</template>
|
||||||
|
</FileUpload>
|
||||||
|
<label>FileUpload</label>
|
||||||
|
</FloatLabel>
|
||||||
|
|
||||||
|
<FloatLabel>
|
||||||
|
<DatePicker showButtonBar dateFormat="dd/mm/yy" :default-value="new Date()" />
|
||||||
|
<label>DatePicker</label>
|
||||||
|
</FloatLabel>
|
||||||
|
|
||||||
<Button @click="openToast">提示服务</Button>
|
<Button @click="openToast">提示服务</Button>
|
||||||
<Button @click="openDialog">对话框服务</Button>
|
<Button @click="openDialog">对话框服务</Button>
|
||||||
|
61
src/main.ts
61
src/main.ts
@ -4,63 +4,28 @@ import 'virtual:uno.css';
|
|||||||
|
|
||||||
import { createHead } from '@unhead/vue';
|
import { createHead } from '@unhead/vue';
|
||||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
|
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
|
||||||
|
import { setupEruda } from './plugins/eruda';
|
||||||
|
import { setupPrimeVue } from './plugins/primevue';
|
||||||
|
import { setupRouter } from './plugins/router';
|
||||||
|
import { setupVueI18n } from './plugins/vue-i18n';
|
||||||
|
|
||||||
import { DataLoaderPlugin } from 'unplugin-vue-router/data-loaders';
|
|
||||||
import { createI18n } from 'vue-i18n';
|
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
import { router } from './router';
|
|
||||||
|
|
||||||
import Aura from '@primevue/themes/aura';
|
|
||||||
import zhCN from 'primelocale/zh-CN.json';
|
|
||||||
import PrimeVue from 'primevue/config';
|
|
||||||
import 'primeicons/primeicons.css';
|
|
||||||
|
|
||||||
/* https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n#static-bundle-importing
|
|
||||||
* All i18n resources specified in the plugin `include` option can be loaded
|
|
||||||
* at once using the import syntax
|
|
||||||
*/
|
|
||||||
import messages from '@intlify/unplugin-vue-i18n/messages';
|
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
if ((import.meta.env.MODE === 'development' || 1 === 1) && 0) {
|
if ((import.meta.env.MODE === 'development' || 1 === 1) && 0) {
|
||||||
// TODO: https://github.com/hu3dao/vite-plugin-debug/
|
await setupEruda();
|
||||||
// https://eruda.liriliri.io/zh/docs/#快速上手
|
|
||||||
await import('eruda').then(({ default: eruda }) => {
|
|
||||||
eruda.init({
|
|
||||||
defaults: {
|
|
||||||
transparency: 0.9,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
// eruda.show();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.debug(`messages :>> `, messages);
|
const app = createApp(App) //
|
||||||
const app = createApp(App)
|
|
||||||
.use(createHead())
|
.use(createHead())
|
||||||
.use(createPinia().use(piniaPluginPersistedstate))
|
.use(createPinia().use(piniaPluginPersistedstate));
|
||||||
// Register the plugin before the router
|
|
||||||
.use(DataLoaderPlugin, { router })
|
setupVueI18n(app);
|
||||||
// adding the router will trigger the initial navigation
|
setupPrimeVue(app);
|
||||||
.use(router)
|
setupRouter(app);
|
||||||
.use(
|
|
||||||
// https://vue-i18n.intlify.dev/guide/essentials/started.html#registering-the-i18n-plugin
|
|
||||||
createI18n({
|
|
||||||
legacy: false, // you must set `false`, to use Composition API
|
|
||||||
locale: navigator.language,
|
|
||||||
messages,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.use(PrimeVue, {
|
|
||||||
locale: zhCN['zh-CN'], // usePrimeVue().config.locale
|
|
||||||
theme: { preset: Aura },
|
|
||||||
options: {
|
|
||||||
prefix: 'p',
|
|
||||||
darkModeSelector: 'system',
|
|
||||||
cssLayer: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
app.config.globalProperties.$__DEV__ = $__DEV__;
|
app.config.globalProperties.$__DEV__ = $__DEV__;
|
||||||
|
|
||||||
app.mount('#app');
|
app.mount('#app');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
src/plugins/eruda.ts
Normal file
12
src/plugins/eruda.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export async function setupEruda() {
|
||||||
|
// TODO: https://github.com/hu3dao/vite-plugin-debug/
|
||||||
|
// https://eruda.liriliri.io/zh/docs/#快速上手
|
||||||
|
await import('eruda').then(({ default: eruda }) => {
|
||||||
|
eruda.init({
|
||||||
|
defaults: {
|
||||||
|
transparency: 0.9,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// eruda.show();
|
||||||
|
});
|
||||||
|
}
|
@ -13,7 +13,7 @@ interface HConfirmationOptions extends ConfirmationOptions {
|
|||||||
rejectProps?: import('primevue/button').ButtonProps;
|
rejectProps?: import('primevue/button').ButtonProps;
|
||||||
acceptProps?: import('primevue/button').ButtonProps;
|
acceptProps?: import('primevue/button').ButtonProps;
|
||||||
}
|
}
|
||||||
export const ConfirmationService = {
|
const ConfirmationService = {
|
||||||
require: (options: HConfirmationOptions) => {
|
require: (options: HConfirmationOptions) => {
|
||||||
ConfirmationEventBus.emit('confirm', options);
|
ConfirmationEventBus.emit('confirm', options);
|
||||||
},
|
},
|
||||||
@ -29,7 +29,7 @@ export const ConfirmationService = {
|
|||||||
import ToastEventBus from 'primevue/toasteventbus';
|
import ToastEventBus from 'primevue/toasteventbus';
|
||||||
import type { ToastServiceMethods } from 'primevue/toastservice';
|
import type { ToastServiceMethods } from 'primevue/toastservice';
|
||||||
// https://github.com/primefaces/primevue/blob/61929eae7526015af0362fc5889f2af7527403d1/packages/primevue/src/toastservice/ToastService.js
|
// https://github.com/primefaces/primevue/blob/61929eae7526015af0362fc5889f2af7527403d1/packages/primevue/src/toastservice/ToastService.js
|
||||||
export const ToastService: ToastServiceMethods = {
|
const ToastService: ToastServiceMethods = {
|
||||||
add: (message) => {
|
add: (message) => {
|
||||||
ToastEventBus.emit('add', message);
|
ToastEventBus.emit('add', message);
|
||||||
},
|
},
|
||||||
@ -51,7 +51,7 @@ export const ToastService: ToastServiceMethods = {
|
|||||||
import DynamicDialogEventBus from 'primevue/dynamicdialogeventbus';
|
import DynamicDialogEventBus from 'primevue/dynamicdialogeventbus';
|
||||||
import type { DialogServiceMethods } from 'primevue/dialogservice';
|
import type { DialogServiceMethods } from 'primevue/dialogservice';
|
||||||
// https://github.com/primefaces/primevue/blob/18367429f624285ff32d0ef775c1825a43a02fb1/packages/primevue/src/dialogservice/DialogService.js#L7
|
// https://github.com/primefaces/primevue/blob/18367429f624285ff32d0ef775c1825a43a02fb1/packages/primevue/src/dialogservice/DialogService.js#L7
|
||||||
export const DialogService: DialogServiceMethods = {
|
const DialogService: DialogServiceMethods = {
|
||||||
open: (content, options) => {
|
open: (content, options) => {
|
||||||
const instance = {
|
const instance = {
|
||||||
content: content && markRaw(content),
|
content: content && markRaw(content),
|
||||||
@ -68,7 +68,34 @@ export const DialogService: DialogServiceMethods = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useDialogRef() {
|
function useDialogRef() {
|
||||||
type DialogRef = ComputedRef<import('primevue/dynamicdialogoptions').DynamicDialogInstance>;
|
type DialogRef = ComputedRef<import('primevue/dynamicdialogoptions').DynamicDialogInstance>;
|
||||||
return inject<DialogRef>('dialogRef');
|
return inject<DialogRef>('dialogRef');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import Aura from '@primevue/themes/aura';
|
||||||
|
import zhCN from 'primelocale/zh-CN.json';
|
||||||
|
import PrimeVue from 'primevue/config';
|
||||||
|
import 'primeicons/primeicons.css';
|
||||||
|
function setupPrimeVue(app: import('vue').App) {
|
||||||
|
app.use(PrimeVue, {
|
||||||
|
locale: {
|
||||||
|
...zhCN['zh-CN'],
|
||||||
|
noFileChosenMessage: '未选择文件',
|
||||||
|
}, // usePrimeVue().config.locale
|
||||||
|
theme: { preset: Aura },
|
||||||
|
options: {
|
||||||
|
prefix: 'p',
|
||||||
|
darkModeSelector: 'system',
|
||||||
|
cssLayer: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
ConfirmationService,
|
||||||
|
ToastService,
|
||||||
|
DialogService,
|
||||||
|
useDialogRef,
|
||||||
|
setupPrimeVue, //
|
||||||
|
};
|
28
src/plugins/router.ts
Normal file
28
src/plugins/router.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { DataLoaderPlugin } from 'unplugin-vue-router/data-loaders';
|
||||||
|
import { createLogGuard, createProgressGuard, createStackGuard } from 'utils4u/vue-router';
|
||||||
|
import { createRouter, createWebHistory } from 'vue-router';
|
||||||
|
import { handleHotUpdate, routes } from 'vue-router/auto-routes';
|
||||||
|
|
||||||
|
export const router = createRouter({
|
||||||
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
|
routes,
|
||||||
|
strict: true,
|
||||||
|
});
|
||||||
|
router.onError((error) => {
|
||||||
|
console.debug('🚨 [router error]: ', error);
|
||||||
|
});
|
||||||
|
if (import.meta.hot) handleHotUpdate(router);
|
||||||
|
if ($__DEV__) Object.assign(window, { router });
|
||||||
|
|
||||||
|
export function setupRouter(app: import('vue').App) {
|
||||||
|
app
|
||||||
|
// Register the plugin before the router
|
||||||
|
.use(DataLoaderPlugin, { router })
|
||||||
|
// adding the router will trigger the initial navigation
|
||||||
|
.use(router);
|
||||||
|
|
||||||
|
// 警告:路由守卫的创建顺序会影响执行流程,请勿调整
|
||||||
|
createProgressGuard(router);
|
||||||
|
createLogGuard(router);
|
||||||
|
Object.assign(window, { stack: createStackGuard(router) });
|
||||||
|
}
|
19
src/plugins/vue-i18n.ts
Normal file
19
src/plugins/vue-i18n.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { createI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
/* https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n#static-bundle-importing
|
||||||
|
* All i18n resources specified in the plugin `include` option can be loaded
|
||||||
|
* at once using the import syntax
|
||||||
|
*/
|
||||||
|
import messages from '@intlify/unplugin-vue-i18n/messages';
|
||||||
|
console.debug(`messages :>> `, messages);
|
||||||
|
|
||||||
|
export function setupVueI18n(app: import('vue').App) {
|
||||||
|
app.use(
|
||||||
|
// https://vue-i18n.intlify.dev/guide/essentials/started.html#registering-the-i18n-plugin
|
||||||
|
createI18n({
|
||||||
|
legacy: false, // you must set `false`, to use Composition API
|
||||||
|
locale: navigator.language,
|
||||||
|
messages,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
@ -1,28 +0,0 @@
|
|||||||
import { createProgressGuard, createLogGuard, createStackGuard } from 'utils4u/vue-router';
|
|
||||||
import { createRouter, createWebHistory, type Router } from 'vue-router';
|
|
||||||
import { routes, handleHotUpdate } from 'vue-router/auto-routes';
|
|
||||||
|
|
||||||
export const router = createRouter({
|
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
|
||||||
routes,
|
|
||||||
strict: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($__DEV__) Object.assign(window, { router });
|
|
||||||
|
|
||||||
setupRouterGuard(router);
|
|
||||||
|
|
||||||
// Don't change the order of creation
|
|
||||||
function setupRouterGuard(router: Router) {
|
|
||||||
createProgressGuard(router);
|
|
||||||
createLogGuard(router);
|
|
||||||
Object.assign(window, { stack: createStackGuard(router) });
|
|
||||||
|
|
||||||
router.onError((error) => {
|
|
||||||
console.debug('🚨 [router error]: ', error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (import.meta.hot) {
|
|
||||||
handleHotUpdate(router);
|
|
||||||
}
|
|
Reference in New Issue
Block a user