feat(package): 新增一些案例;但是 tailwindcss 仅在子项目生效

This commit is contained in:
2025-12-31 15:54:36 +08:00
parent 4fc473fff2
commit c8b0361e59
22 changed files with 887 additions and 32 deletions

View File

@@ -0,0 +1,38 @@
<script setup lang="ts">
import { zhCN, dateZhCN } from 'naive-ui';
import { omit } from 'naive-ui/es/_utils';
import { useAttrs } from 'vue';
import { storeToRefs } from 'pinia';
import { useLocalConfigStore } from '../../stores/useLocalConfigStore';
import { LayoutProvider } from '../layouts';
const { naiveThemeProps } = storeToRefs(useLocalConfigStore());
defineOptions({
inheritAttrs: false,
});
const attrs = useAttrs();
</script>
<template>
<n-config-provider
v-bind="omit(attrs, ['locale', 'date-locale', 'theme-overrides'])"
:locale="zhCN"
:date-locale="dateZhCN"
:theme-overrides="naiveThemeProps"
>
<n-dialog-provider>
<n-message-provider>
<n-notification-provider>
<n-loading-bar-provider>
<layout-provider>
<slot />
</layout-provider>
</n-loading-bar-provider>
</n-notification-provider>
</n-message-provider>
</n-dialog-provider>
</n-config-provider>
</template>

View File

@@ -0,0 +1,3 @@
import ConfigProvider from './ConfigProvider.vue';
export const AppConfigProvider = ConfigProvider;

View File

@@ -0,0 +1 @@
export * from './config-provider';

View File

@@ -0,0 +1,8 @@
<script setup lang="ts">
import Default from './default/Index.vue';
console.log('Provider layout loaded');
</script>
<template>
<Default> <slot /> </Default>
</template>

View File

@@ -0,0 +1,33 @@
<script setup lang="ts">
import { useLoadingBar } from 'naive-ui';
import { loadingBarRef } from '../../../core/router/guards';
import { onMounted } from 'vue';
import { storeToRefs } from 'pinia';
import { useLocalConfigStore } from '../../../stores/useLocalConfigStore';
const { primaryColor } = storeToRefs(useLocalConfigStore());
const loadingBar = useLoadingBar();
onMounted(() => {
loadingBarRef.value = loadingBar;
});
function pickerThemeColor() {
loadingBarRef.value?.start();
setTimeout(() => {
loadingBarRef.value?.finish();
}, 500);
}
</script>
<template>
<n-layout position="absolute">
<n-layout-header bordered class="h-12"> </n-layout-header>
<n-layout position="absolute" has-sider class="top-12!">
<n-layout-sider bordered />
<n-layout-content>
<slot />
</n-layout-content>
</n-layout>
</n-layout>
</template>

View File

@@ -0,0 +1,6 @@
import Provider from './Provider.vue';
import Default from './default/index.vue';
export const LayoutProvider = Provider;
export const LayoutDefault = Default;

View File

View File

@@ -0,0 +1,31 @@
import { createApp, type App, type Component, type Plugin } from 'vue';
import { createWebRouter, type WebRouterOptions } from './createWebRouter';
import { createPinia } from 'pinia';
import piniaPluginPersistedState from 'pinia-plugin-persistedstate';
export interface WebAppOptions {
mount: string;
plugins?: Plugin<unknown[]>[];
requestPrefix: string;
router: WebRouterOptions;
}
// 封装一个创建 Web 应用的函数
// 用于替代 Vue 3 项目中的 main.ts 默认的应用逻辑
export function createWebApp(rootComponent: Component, options: WebAppOptions): App {
const app = createApp(rootComponent);
const router = createWebRouter(options.router);
app.use(router);
if (options.plugins && options.plugins.length > 0) {
options.plugins.forEach((plugin) => {
app.use(plugin);
});
}
app.use(createPinia().use(piniaPluginPersistedState));
app.mount(options.mount);
return app;
}

View File

@@ -0,0 +1,50 @@
import {
createMemoryHistory,
createRouter,
createWebHashHistory,
createWebHistory,
type Router,
type RouterHistory,
type RouterOptions,
} from 'vue-router';
import { setRouterTranslateGuard } from './router/guards';
type RouterHistoryMode = 'hash' | 'history' | 'memory';
type RouterHistoryFunction = (base?: string) => RouterHistory;
function _useHistory(mode: RouterHistoryMode): RouterHistoryFunction {
const historyObject: Record<RouterHistoryMode, RouterHistoryFunction> = {
hash: createWebHashHistory,
history: createWebHistory,
memory: createMemoryHistory,
};
return historyObject[mode];
}
// 创建一个 Web 路由实例的函数
// 默认是 history 模式
export interface WebRouterOptions extends Omit<RouterOptions, 'history'> {
mode?: RouterHistoryMode;
base?: string;
guards?: ((router: Router) => void)[];
}
export function createWebRouter(options: WebRouterOptions): Router {
const history = _useHistory(options?.mode || 'history')?.(options?.base);
const routes = options?.routes || [];
const scrollBehavior = options?.scrollBehavior || (() => ({ left: 0, top: 0 }));
const guards = [setRouterTranslateGuard].concat(options?.guards || []);
const router = createRouter({
history,
routes,
scrollBehavior,
});
if (guards && guards.length > 0) {
guards.forEach((guard) => {
guard(router);
});
}
return router;
}

View File

@@ -0,0 +1,11 @@
import { type ShallowRef, shallowRef } from 'vue';
import { type LoadingBarApi } from 'naive-ui';
import type { Router } from 'vue-router';
export const loadingBarRef: ShallowRef<LoadingBarApi | null> = shallowRef(null);
export function setRouterTranslateGuard(router: Router) {
console.log('Router translate guard set');
router.beforeEach(() => loadingBarRef.value?.start());
router.afterEach(() => loadingBarRef.value?.finish());
}

View File

@@ -1,3 +1,2 @@
export function createWebApp() {
console.log('Created web app');
}
export * from './core/createWebApp';
export * from './components';

View File

@@ -0,0 +1,68 @@
import type { GlobalThemeOverrides } from 'naive-ui';
import { defineStore } from 'pinia';
import { computed, shallowRef } from 'vue';
import { colord } from 'colord';
const LOCAL_FIXED_THEME_PRIMARY_COLOR = '#31A848FF';
export const useLocalConfigStore = defineStore(
'localConfig',
() => {
// 本地主题色配置
const { primaryColor, resetPrimaryColor, grayMode, toggleGrayMode, naiveThemeProps } = (function () {
const primaryColor = shallowRef<string>(LOCAL_FIXED_THEME_PRIMARY_COLOR);
// naive-ui 主题色变更
const naiveThemeProps = computed((): GlobalThemeOverrides => {
const hsColor = colord(primaryColor.value).lighten(0.035);
const pColor = colord(primaryColor.value).darken(0.1);
return {
common: {
primaryColor: primaryColor.value,
primaryColorHover: hsColor.toHex(),
primaryColorPressed: pColor.toHex(),
primaryColorSuppl: hsColor.toHex(),
},
LoadingBar: {
colorLoading: primaryColor.value,
},
};
});
function resetPrimaryColor() {
primaryColor.value = LOCAL_FIXED_THEME_PRIMARY_COLOR;
}
const grayMode = shallowRef<boolean>(false);
function toggleGrayMode() {
grayMode.value = !grayMode.value;
if (grayMode.value) {
document.documentElement.style.filter = 'grayscale(1)';
} else {
document.documentElement.style.filter = 'grayscale(0)';
}
}
return {
primaryColor,
resetPrimaryColor,
grayMode,
toggleGrayMode,
naiveThemeProps,
};
})();
// 布局配置
return {
primaryColor,
resetPrimaryColor,
grayMode,
toggleGrayMode,
naiveThemeProps,
};
},
{
persist: true,
}
);

View File

@@ -1,3 +1,4 @@
{
"extends": "../../tsconfig.app.json"
"extends": "../../tsconfig.app.json",
"include": ["./**/*.vue", "./**/*.ts", "./**/*.tsx", "./**/*.js", "./**/*.jsx"]
}