diff --git a/eslint.config.ts b/eslint.config.ts
index 2496aca..0540af3 100644
--- a/eslint.config.ts
+++ b/eslint.config.ts
@@ -4,7 +4,6 @@ import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescri
import pluginImport from 'eslint-plugin-import-x';
import oxlint from 'eslint-plugin-oxlint';
import perfectionist from 'eslint-plugin-perfectionist';
-import perfectionistPlugin from 'eslint-plugin-perfectionist';
import pluginVue from 'eslint-plugin-vue';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
@@ -13,8 +12,6 @@ const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const gitignorePath = path.resolve(__dirname, '.gitignore');
-import type { Linter } from 'eslint';
-
// To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
import { configureVueProject } from '@vue/eslint-config-typescript';
@@ -24,13 +21,13 @@ configureVueProject({ scriptLangs: ['ts', 'tsx', 'js', 'jsx'] });
export default defineConfigWithVueTs(
includeIgnoreFile(gitignorePath), // oxlint . --fix -D correctness --ignore-path .gitignore
{
- name: 'app/files-to-lint',
files: ['**/*.{ts,mts,tsx,vue}'],
+ name: 'app/files-to-lint',
},
{
- name: 'app/files-to-ignore',
ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'],
+ name: 'app/files-to-ignore',
},
pluginVue.configs['flat/essential'],
@@ -48,43 +45,9 @@ export default defineConfigWithVueTs(
oxlint.configs['flat/recommended'],
skipFormatting,
- importPluginConfig(),
- {
- rules: {
- 'vue/multi-word-component-names': 'off',
- '@typescript-eslint/no-explicit-any': 'off',
- 'vue/block-order': [
- 'error',
- {
- order: ['script', 'template', 'style'],
- },
- ],
- 'vue/define-macros-order': [
- 'error',
- {
- order: ['defineOptions', 'defineProps', 'defineEmits', 'defineSlots'],
- },
- ],
- },
- },
-
- // https://perfectionist.dev/guide/getting-started
- perfectionistPlugin.configs['recommended-natural'],
- {
- plugins: {
- perfectionist,
- },
- rules: {
- 'perfectionist/sort-imports': ['error'],
- },
- },
-);
-
-function importPluginConfig(): Linter.Config[] {
- return [
+ [
{
plugins: {
- // @ts-expect-error - This is a dynamic import
import: pluginImport,
},
rules: {
@@ -98,5 +61,35 @@ function importPluginConfig(): Linter.Config[] {
// 'import/no-webpack-loader-syntax': 'error',
},
},
- ];
-}
+ ],
+
+ {
+ rules: {
+ '@typescript-eslint/no-explicit-any': 'off',
+ 'vue/block-order': [
+ 'error',
+ {
+ order: ['script', 'template', 'style'],
+ },
+ ],
+ 'vue/define-macros-order': [
+ 'error',
+ {
+ order: ['defineOptions', 'defineProps', 'defineEmits', 'defineSlots'],
+ },
+ ],
+ 'vue/multi-word-component-names': 'off',
+ },
+ },
+
+ // https://perfectionist.dev/guide/getting-started
+
+ [
+ perfectionist.configs['recommended-natural'],
+ {
+ rules: {
+ 'perfectionist/sort-imports': ['error'],
+ },
+ },
+ ],
+);
diff --git a/fake/upload.fake.ts b/fake/upload.fake.ts
index 18eb3aa..737e226 100644
--- a/fake/upload.fake.ts
+++ b/fake/upload.fake.ts
@@ -4,14 +4,7 @@ import { defineFakeRoute } from 'vite-plugin-fake-server/client';
let fail = !false;
export default defineFakeRoute([
{
- timeout: 2000,
method: 'POST',
- url: '/fake/upload',
- response: () => {
- return {
- url: 'https://picsum.photos/200/300',
- };
- },
rawResponse(req, res) {
fail = !fail;
if (fail) {
@@ -22,5 +15,12 @@ export default defineFakeRoute([
res.end(JSON.stringify({ url: 'https://picsum.photos/200/300' }));
}
},
+ response: () => {
+ return {
+ url: 'https://picsum.photos/200/300',
+ };
+ },
+ timeout: 2000,
+ url: '/fake/upload',
},
]);
diff --git a/fake/user.fake.ts b/fake/user.fake.ts
index 8be1926..dd5d4fd 100644
--- a/fake/user.fake.ts
+++ b/fake/user.fake.ts
@@ -5,30 +5,30 @@ import { defineFakeRoute } from 'vite-plugin-fake-server/client';
export default defineFakeRoute([
{
- url: '/mock/get-user-info',
response: () => {
return Mock.mock({
- id: '@guid',
- username: '@first',
- email: '@email',
avatar: '@image("200x200")',
+ email: '@email',
+ id: '@guid',
role: 'admin',
+ username: '@first',
});
},
+ url: '/mock/get-user-info',
},
{
- url: '/fake/get-user-info',
response: () => {
return {
- id: faker.string.uuid(),
avatar: faker.image.avatar(),
birthday: faker.date.birthdate(),
email: faker.internet.email(),
firstName: faker.person.firstName(),
+ id: faker.string.uuid(),
lastName: faker.person.lastName(),
- sex: faker.person.sexType(),
role: 'admin',
+ sex: faker.person.sexType(),
};
},
+ url: '/fake/get-user-info',
},
]);
diff --git a/playwright.config.ts b/playwright.config.ts
index 4204e9d..ce88ec8 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -12,29 +12,13 @@ import { defineConfig, devices } from '@playwright/test';
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
- testDir: './tests/e2e',
- /* Run tests in files in parallel */
- fullyParallel: true,
- /* Fail the build on CI if you accidentally left test.only in the source code. */
- forbidOnly: !!process.env.CI,
- /* Retry on CI only */
- retries: process.env.CI ? 2 : 0,
- /* Opt out of parallel tests on CI. */
- workers: process.env.CI ? 1 : undefined,
- /* Reporter to use. See https://playwright.dev/docs/test-reporters */
- reporter: 'html',
- /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
- use: {
- /* Base URL to use in actions like `await page.goto('/')`. */
- baseURL: process.env.BASE_URL || 'https://vue-ts-example.oo1.dev',
-
- /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
- trace: 'on-first-retry',
- },
expect: {
timeout: 30 * 1000,
},
-
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Run tests in files in parallel */
+ fullyParallel: true,
/* Configure projects for major browsers */
projects: [
{
@@ -72,6 +56,22 @@ export default defineConfig({
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ testDir: './tests/e2e',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: process.env.BASE_URL || 'https://vue-ts-example.oo1.dev',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+ },
+
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
/* Run your local dev server before starting the tests */
// webServer: {
diff --git a/src/components/UseIntersectionObserverInfiniteLoading.vue b/src/components/UseIntersectionObserverInfiniteLoading.vue
index 890e1e7..f6f3447 100644
--- a/src/components/UseIntersectionObserverInfiniteLoading.vue
+++ b/src/components/UseIntersectionObserverInfiniteLoading.vue
@@ -6,7 +6,7 @@ function checkIsVisible(el: Element, root: Element | null = null) {
const elRect = el.getBoundingClientRect();
const rootRect = root
? root.getBoundingClientRect()
- : { top: 0, left: 0, bottom: window.innerHeight, right: window.innerWidth };
+ : { bottom: window.innerHeight, left: 0, right: window.innerWidth, top: 0 };
return (
elRect.bottom >= rootRect.top &&
@@ -32,26 +32,26 @@ function checkIsVisible(el: Element, root: Element | null = null) {
*/
const props = defineProps<{
- loading: boolean;
complete: boolean;
error: boolean;
errorText: string;
+ loading: boolean;
}>();
const emit = defineEmits<{
- load: [];
clickError: [];
+ load: [];
}>();
defineSlots<{
- // 加载中
- loading(): unknown;
- // 加载完成(还有更多)
- loaded(): unknown;
// 加载完成(没有更多了)
complete(): unknown;
// 加载失败
error(): unknown;
+ // 加载完成(还有更多)
+ loaded(): unknown;
+ // 加载中
+ loading(): unknown;
}>();
const check = (reason?: string) => {
diff --git a/src/components/primevue/upload-demo.vue b/src/components/primevue/upload-demo.vue
index 1ad1bb8..a1ca4f6 100644
--- a/src/components/primevue/upload-demo.vue
+++ b/src/components/primevue/upload-demo.vue
@@ -6,15 +6,15 @@ interface FileExt extends File {
}
interface FileUploadInst extends FileUploadState {
+ chooseDisabled?: boolean;
files: FileExt[];
uploadedFiles: {
- rawFile: FileExt;
name: string;
- url: string;
- status: 'uploading' | 'uploaded' | 'failed';
progress: number;
+ rawFile: FileExt;
+ status: 'failed' | 'uploaded' | 'uploading';
+ url: string;
}[];
- chooseDisabled?: boolean;
}
@@ -30,11 +30,11 @@ const onUploader = (event: FileUploadUploaderEvent) => {
const files = event.files as FileExt[];
for (const file of files) {
fileUploadRef.value!.uploadedFiles.push({
- rawFile: file,
name: file.name,
- url: '',
- status: 'uploading',
progress: 0,
+ rawFile: file,
+ status: 'uploading',
+ url: '',
});
const formData = new FormData();
formData.append('file', file);
diff --git a/src/components/send-sms.vue b/src/components/send-sms.vue
index 31de86a..6a145b1 100644
--- a/src/components/send-sms.vue
+++ b/src/components/send-sms.vue
@@ -1,5 +1,5 @@
diff --git a/src/layouts/sakai-vue/AppLayout.vue b/src/layouts/sakai-vue/AppLayout.vue
index bd95ae1..d3cf646 100644
--- a/src/layouts/sakai-vue/AppLayout.vue
+++ b/src/layouts/sakai-vue/AppLayout.vue
@@ -8,9 +8,9 @@ import AppSidebar from './AppSidebar.vue';
import AppTopbar from './AppTopbar.vue';
import { useLayout } from './composables/layout';
-const { layoutConfig, layoutState, isSidebarActive } = useLayout();
+const { isSidebarActive, layoutConfig, layoutState } = useLayout();
-const outsideClickListener = ref(null as Parameters[1] | null);
+const outsideClickListener = ref(null as null | Parameters[1]);
watch(isSidebarActive, (newVal) => {
if (newVal) {
@@ -22,11 +22,11 @@ watch(isSidebarActive, (newVal) => {
const containerClass = computed(() => {
return {
+ 'layout-mobile-active': layoutState.staticMenuMobileActive,
'layout-overlay': layoutConfig.menuMode === 'overlay',
+ 'layout-overlay-active': layoutState.overlayMenuActive,
'layout-static': layoutConfig.menuMode === 'static',
'layout-static-inactive': layoutState.staticMenuDesktopInactive && layoutConfig.menuMode === 'static',
- 'layout-overlay-active': layoutState.overlayMenuActive,
- 'layout-mobile-active': layoutState.staticMenuMobileActive,
};
});
@@ -43,13 +43,6 @@ function bindOutsideClickListener() {
}
}
-function unbindOutsideClickListener() {
- if (outsideClickListener.value) {
- document.removeEventListener('click', outsideClickListener.value);
- outsideClickListener.value = null;
- }
-}
-
function isOutsideClicked(event: Event) {
const sidebarEl = document.querySelector('.layout-sidebar')!;
const topbarEl = document.querySelector('.layout-menu-button')!;
@@ -61,6 +54,13 @@ function isOutsideClicked(event: Event) {
topbarEl.contains(event.target as never)
);
}
+
+function unbindOutsideClickListener() {
+ if (outsideClickListener.value) {
+ document.removeEventListener('click', outsideClickListener.value);
+ outsideClickListener.value = null;
+ }
+}
diff --git a/src/layouts/sakai-vue/AppTopbar.vue b/src/layouts/sakai-vue/AppTopbar.vue
index 2dd9522..18667b2 100644
--- a/src/layouts/sakai-vue/AppTopbar.vue
+++ b/src/layouts/sakai-vue/AppTopbar.vue
@@ -2,7 +2,7 @@
import AppConfigurator from './AppConfigurator.vue';
import { useLayout } from './composables/layout';
-const { toggleMenu, toggleDarkMode, isDarkTheme } = useLayout();
+const { isDarkTheme, toggleDarkMode, toggleMenu } = useLayout();
diff --git a/src/layouts/sakai-vue/composables/layout.ts b/src/layouts/sakai-vue/composables/layout.ts
index 0c0c381..7ac5e85 100644
--- a/src/layouts/sakai-vue/composables/layout.ts
+++ b/src/layouts/sakai-vue/composables/layout.ts
@@ -1,21 +1,21 @@
import { computed, reactive } from 'vue';
const layoutConfig = reactive({
+ darkTheme: false,
+ menuMode: 'static',
preset: 'Aura',
primary: 'emerald',
surface: null,
- darkTheme: false,
- menuMode: 'static',
});
const layoutState = reactive({
- staticMenuDesktopInactive: false,
+ activeMenuItem: null,
+ configSidebarVisible: false,
+ menuHoverActive: false,
overlayMenuActive: false,
profileSidebarVisible: false,
- configSidebarVisible: false,
+ staticMenuDesktopInactive: false,
staticMenuMobileActive: false,
- menuHoverActive: false,
- activeMenuItem: null,
});
export function useLayout() {
@@ -59,14 +59,14 @@ export function useLayout() {
const getSurface = computed(() => layoutConfig.surface);
return {
- layoutConfig,
- layoutState,
- toggleMenu,
- isSidebarActive,
- isDarkTheme,
getPrimary,
getSurface,
+ isDarkTheme,
+ isSidebarActive,
+ layoutConfig,
+ layoutState,
setActiveMenuItem,
toggleDarkMode,
+ toggleMenu,
};
}
diff --git a/src/pages/AntdV/HAPopconfirm/types.ts b/src/pages/AntdV/HAPopconfirm/types.ts
index 62995e2..96dca45 100644
--- a/src/pages/AntdV/HAPopconfirm/types.ts
+++ b/src/pages/AntdV/HAPopconfirm/types.ts
@@ -1,9 +1,9 @@
import type { PopconfirmProps } from 'ant-design-vue';
-type NotUndefined = T extends undefined ? never : T;
-type PopconfirmOnConfirmParameters = Parameters>;
export type HPopconfirmProps = {
description: PopconfirmProps['description'];
onConfirm?: (...args: PopconfirmOnConfirmParameters) => Promise;
title: PopconfirmProps['title'];
};
+type NotUndefined = T extends undefined ? never : T;
+type PopconfirmOnConfirmParameters = Parameters>;
diff --git a/src/pages/SAT/CesiumViewer.vue b/src/pages/SAT/CesiumViewer.vue
index c093296..57108b1 100644
--- a/src/pages/SAT/CesiumViewer.vue
+++ b/src/pages/SAT/CesiumViewer.vue
@@ -1,18 +1,18 @@
diff --git a/src/pages/api.page.vue b/src/pages/api.page.vue
index 3ef5c80..df2300f 100644
--- a/src/pages/api.page.vue
+++ b/src/pages/api.page.vue
@@ -1,7 +1,7 @@
diff --git a/src/pages/index.page.vue b/src/pages/index.page.vue
index add9dc3..33993c6 100644
--- a/src/pages/index.page.vue
+++ b/src/pages/index.page.vue
@@ -4,13 +4,13 @@ import { routes } from 'vue-router/auto-routes';
definePage({ meta: { title: '首页' } });
useHead({
+ // Classes
+ bodyAttrs: { class: { overflow: true } },
+ // Template params
+ templateParams: { separator: '|', siteName: 'My App' },
// Titles
title: 'Hello World',
titleTemplate: '%s %separator %siteName',
- // Template params
- templateParams: { separator: '|', siteName: 'My App' },
- // Classes
- bodyAttrs: { class: { overflow: true } },
// Deduping
// script: [{ key: '123', src: '/script.js' }],
});
@@ -21,9 +21,9 @@ const FComponent: import('vue').FunctionalComponent<{ prop: string }> = (props,
<>
函数式组件: https://cn.vuejs.org/guide/extras/render-function#typing-functional-components
diff --git a/src/pages/infinite-loading/index.page.vue b/src/pages/infinite-loading/index.page.vue
index 0a64eb1..4dfb5e1 100644
--- a/src/pages/infinite-loading/index.page.vue
+++ b/src/pages/infinite-loading/index.page.vue
@@ -2,11 +2,11 @@
const structuredClone = window.structuredClone || ((obj) => JSON.parse(JSON.stringify(obj)));
const K_INITIAL_STATE = deepFreeze({
- list: [] as Record[],
- page: 0,
- loading: false,
complete: false,
error: null as unknown,
+ list: [] as Record[],
+ loading: false,
+ page: 0,
});
let page3ShouldError = true;
@@ -33,6 +33,8 @@ const refresh = () => {
loadMore();
};
+type CurrentUse = 'use-intersection-observer-infinite-loading' | 'van-list';
+
async function loadMore() {
if (state.loading) return;
@@ -59,8 +61,6 @@ async function loadMore() {
state.loading = false;
}
}
-
-type CurrentUse = 'van-list' | 'use-intersection-observer-infinite-loading';
const currentUse = ref((sessionStorage.getItem('currentUse') as CurrentUse) || 'van-list');
watchEffect(() => {
sessionStorage.setItem('currentUse', currentUse.value);
diff --git a/src/pages/primevue/fns.tsx b/src/pages/primevue/fns.tsx
index 0d288b3..714150b 100644
--- a/src/pages/primevue/fns.tsx
+++ b/src/pages/primevue/fns.tsx
@@ -3,8 +3,8 @@ import dialogContent from './__dialog-content.vue';
const dynamicComponent = defineComponent({
props: {
'defining-props': {
- type: Object as PropType>,
default: () => ({}),
+ type: Object as PropType>,
},
},
setup(props, ctx) {
@@ -24,12 +24,6 @@ const dynamicComponent = defineComponent({
// https://primevue.org/dynamicdialog/
export const openDialog = async () => {
const dialog1 = DialogService.open(dynamicComponent, {
- props: {
- header: '对话框1 可以拖动',
- position: 'bottomleft',
- draggable: true,
- pt: { mask: { class: 'backdrop-blur-sm' } }, // 相当于: pt:mask:class="backdrop-blur-sm"
- },
data: {
用inject接收: '通过 DynamicDialogOptions.data 传递的数据',
},
@@ -39,8 +33,14 @@ export const openDialog = async () => {
'defining-props': {
'用-props-接收': '定义在-DynamicDialogOptions.emits-的数据',
},
- 绑定给组件的attrs: '定义在-DynamicDialogOptions.emits-的数据,',
onClose: () => dialog1.close(),
+ 绑定给组件的attrs: '定义在-DynamicDialogOptions.emits-的数据,',
+ },
+ props: {
+ draggable: true,
+ header: '对话框1 可以拖动',
+ position: 'bottomleft',
+ pt: { mask: { class: 'backdrop-blur-sm' } }, // 相当于: pt:mask:class="backdrop-blur-sm"
},
});
@@ -58,17 +58,17 @@ export const openDialog = async () => {
export const openConfirm = async () => {
ConfirmationService.require({
- message: '确定要继续吗?',
- header: '确认',
- icon: 'pi pi-exclamation-triangle',
- rejectProps: { label: '取消', severity: 'secondary', outlined: true },
+ accept: () => {
+ ToastService.add({ detail: '您已同意操作', life: 3000, severity: 'info', summary: '已确认' });
+ },
// rejectProps: { style: { display: 'none' } },
acceptProps: { label: '确定' },
- accept: () => {
- ToastService.add({ severity: 'info', summary: '已确认', life: 3000, detail: '您已同意操作' });
- },
+ header: '确认',
+ icon: 'pi pi-exclamation-triangle',
+ message: '确定要继续吗?',
reject: () => {
- ToastService.add({ severity: 'error', summary: '已取消', life: 3000, detail: '您已取消操作' });
+ ToastService.add({ detail: '您已取消操作', life: 3000, severity: 'error', summary: '已取消' });
},
+ rejectProps: { label: '取消', outlined: true, severity: 'secondary' },
});
};
diff --git a/src/pages/ts-enum-util.page.vue b/src/pages/ts-enum-util.page.vue
index c5ec5be..936e29e 100644
--- a/src/pages/ts-enum-util.page.vue
+++ b/src/pages/ts-enum-util.page.vue
@@ -2,10 +2,10 @@
import { $enum } from 'ts-enum-util';
enum Direction {
- Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT',
+ Up = 'UP',
}
enum TestEnum {
@@ -15,25 +15,25 @@ enum TestEnum {
const visitValue = (value: Direction | null | undefined) => {
$enum.visitValue(value).with({
- [Direction.Up]: () => {},
- [Direction.Down]: () => {},
- [Direction.Left]: () => {},
- [Direction.Right]: () => {},
[$enum.handleNull]: () => {},
[$enum.handleUndefined]: () => {},
[$enum.handleUnexpected]: () => {},
+ [Direction.Down]: () => {},
+ [Direction.Left]: () => {},
+ [Direction.Right]: () => {},
+ [Direction.Up]: () => {},
});
};
const mapValue = (value: Direction | null | undefined) => {
return $enum.mapValue(value).with({
- [Direction.Up]: 'Up',
- [Direction.Down]: 'Down',
- [Direction.Left]: 'Left',
- [Direction.Right]: 'Right',
[$enum.handleNull]: 'Null',
[$enum.handleUndefined]: 'Undefined',
[$enum.handleUnexpected]: 'Unexpected',
+ [Direction.Down]: 'Down',
+ [Direction.Left]: 'Left',
+ [Direction.Right]: 'Right',
+ [Direction.Up]: 'Up',
});
};
diff --git a/src/plugins/index.ts b/src/plugins/index.ts
index b4b1e47..8be1d47 100644
--- a/src/plugins/index.ts
+++ b/src/plugins/index.ts
@@ -1,7 +1,7 @@
+type AutoInstallModule = { [K: string]: unknown; install?: UserPlugin };
+type UserPlugin = (ctx: UserPluginContext) => void;
// https://github.com/antfu-collective/vitesse/blob/47618e72dfba76c77b9b85b94784d739e35c492b/src/modules/README.md
type UserPluginContext = { app: import('vue').App };
-type UserPlugin = (ctx: UserPluginContext) => void;
-type AutoInstallModule = { install?: UserPlugin; [K: string]: unknown };
export function setupPlugins(app: import('vue').App, modules: AutoInstallModule | Record) {
console.group('🔌 Plugins');
diff --git a/src/plugins/primevue.ts b/src/plugins/primevue.ts
index b86309f..775adf5 100644
--- a/src/plugins/primevue.ts
+++ b/src/plugins/primevue.ts
@@ -12,17 +12,17 @@ export function install({ app }: { app: import('vue').App }) {
app.use(PrimeVue, {
locale: {
...zhCN['zh-CN'],
+ completed: '已上传',
noFileChosenMessage: '未选择文件',
pending: '待上传',
- completed: '已上传',
}, // usePrimeVue().config.locale
theme: {
- preset: Aura,
options: {
- prefix: 'p',
- darkModeSelector: '.app-dark' /* 'system' */,
cssLayer: false,
+ darkModeSelector: '.app-dark' /* 'system' */,
+ prefix: 'p',
},
+ preset: Aura,
},
});
}
diff --git a/src/plugins/router.ts b/src/plugins/router.ts
index 63f8d88..74052b6 100644
--- a/src/plugins/router.ts
+++ b/src/plugins/router.ts
@@ -8,7 +8,6 @@ const setupLayoutsResult = setupLayouts(routes);
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: /* routes ?? */ setupLayoutsResult,
- strict: true,
scrollBehavior: (_to, _from, savedPosition) => {
if (savedPosition) {
return savedPosition;
@@ -16,6 +15,7 @@ const router = createRouter({
return { left: 0, top: 0 };
}
},
+ strict: true,
});
if (import.meta.hot) handleHotUpdate(router);
if ($__DEV__) Object.assign(window, { router });
@@ -23,7 +23,7 @@ router.onError((error) => {
console.debug('🚨 [router error]: ', error);
});
-export { router, setupLayoutsResult, createGetRoutes };
+export { createGetRoutes, router, setupLayoutsResult };
export function install({ app }: { app: import('vue').App }) {
app
// Register the plugin before the router
diff --git a/src/types/shims/unocss.ts b/src/types/shims/unocss.ts
index e3214ad..7b04995 100644
--- a/src/types/shims/unocss.ts
+++ b/src/types/shims/unocss.ts
@@ -14,7 +14,7 @@
declare module 'vue' {
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface HTMLAttributes
- extends Partial> {}
+ extends Partial> {}
}
export {};
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 7564a44..3276208 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -1,11 +1,11 @@
export async function PromiseConfirmationService({ message }: { message: string }) {
return await new Promise((reslove) => {
ConfirmationService.require({
- position: 'bottomright',
- modal: false,
+ accept: () => reslove(true),
header: '提示',
message: message,
- accept: () => reslove(true),
+ modal: false,
+ position: 'bottomright',
reject: () => reslove(false),
});
});
diff --git a/tests/e2e/api-page.spec.ts b/tests/e2e/api-page.spec.ts
index 932ca3c..393092b 100644
--- a/tests/e2e/api-page.spec.ts
+++ b/tests/e2e/api-page.spec.ts
@@ -1,4 +1,4 @@
-import { test, expect } from '@playwright/test';
+import { expect, test } from '@playwright/test';
test('接口请求页面', async ({ page }) => {
await page.goto('/api');
diff --git a/unocss.config.ts b/unocss.config.ts
index 88f02dd..209e81b 100644
--- a/unocss.config.ts
+++ b/unocss.config.ts
@@ -3,52 +3,6 @@ import { defineConfig, presetAttributify, presetWind3, transformerDirectives, tr
// import presetChinese, { chineseTypography } from 'unocss-preset-chinese';
export default defineConfig({
- theme: {
- // https://unocss.dev/presets/wind#differences-from-tailwind-css
- // https://www.npmjs.com/package/unocss-preset-animations
- // https://github.com/whatnickcodes/unocss-preset-tailwindcss-motion
- animation: {
- keyframes: {
- scalein: '{0% { opacity: 0; transform: scaleY(0.8); } 100% { opacity: 1; transform: scaleY(1); }}',
- fadeout: '{0% { opacity: 1; } 100% { opacity: 0; }}',
- },
- durations: {
- scalein: '0.15s',
- fadeout: '0.15s',
- },
- timingFns: {
- scalein: 'linear',
- fadeout: 'linear',
- },
- properties: {
- scalein: {
- transition: 'transform 0.12s cubic-bezier(0, 0, 0.2, 1), opacity 0.12s cubic-bezier(0, 0, 0.2, 1)',
- },
- fadeout: {},
- },
- counts: {
- scalein: '1',
- fadeout: '1',
- },
- },
-
- // https://unocss.dev/config/theme#usage
- colors: {
- 'surface-0': 'var(--p-surface-0)', // text-surface-0
- 'surface-900': 'var(--p-surface-900)', // text-surface-900
- },
- },
-
- shortcuts: [
- {
- 'logo-transform': 'i-icon:pacman w-6em h-6em transform transition-800',
- pacman: 'i-icon:pacman text-(pink 36)',
- },
- {
- // https://github.com/primefaces/tailwindcss-primeui/blob/d5e903377e015b7c63cb5edf42490b9d6954ef04/src/utils/preset.js
- 'text-muted-color': 'text-[var(--p-text-muted-color)]',
- },
- ],
presets: [
presetWind3({
/* prefix: "u-", */
@@ -64,6 +18,52 @@ export default defineConfig({
// https://unocss.dev/presets/attributify
presetAttributify(),
],
+
+ shortcuts: [
+ {
+ 'logo-transform': 'i-icon:pacman w-6em h-6em transform transition-800',
+ pacman: 'i-icon:pacman text-(pink 36)',
+ },
+ {
+ // https://github.com/primefaces/tailwindcss-primeui/blob/d5e903377e015b7c63cb5edf42490b9d6954ef04/src/utils/preset.js
+ 'text-muted-color': 'text-[var(--p-text-muted-color)]',
+ },
+ ],
+ theme: {
+ // https://unocss.dev/presets/wind#differences-from-tailwind-css
+ // https://www.npmjs.com/package/unocss-preset-animations
+ // https://github.com/whatnickcodes/unocss-preset-tailwindcss-motion
+ animation: {
+ counts: {
+ fadeout: '1',
+ scalein: '1',
+ },
+ durations: {
+ fadeout: '0.15s',
+ scalein: '0.15s',
+ },
+ keyframes: {
+ fadeout: '{0% { opacity: 1; } 100% { opacity: 0; }}',
+ scalein: '{0% { opacity: 0; transform: scaleY(0.8); } 100% { opacity: 1; transform: scaleY(1); }}',
+ },
+ properties: {
+ fadeout: {},
+ scalein: {
+ transition: 'transform 0.12s cubic-bezier(0, 0, 0.2, 1), opacity 0.12s cubic-bezier(0, 0, 0.2, 1)',
+ },
+ },
+ timingFns: {
+ fadeout: 'linear',
+ scalein: 'linear',
+ },
+ },
+
+ // https://unocss.dev/config/theme#usage
+ colors: {
+ 'surface-0': 'var(--p-surface-0)', // text-surface-0
+ 'surface-900': 'var(--p-surface-900)', // text-surface-900
+ },
+ },
transformers: [
//https://unocss.dev/transformers/variant-group
transformerVariantGroup(),
diff --git a/vite.config.plugins.ts b/vite.config.plugins.ts
index 07f3eea..8ee410a 100644
--- a/vite.config.plugins.ts
+++ b/vite.config.plugins.ts
@@ -3,7 +3,6 @@
* https://github.com/vue-macros/vue-macros/blob/main/playground/vue3/vite.config.ts
*/
-import { viteStaticCopy } from 'vite-plugin-static-copy';
import VueI18n from '@intlify/unplugin-vue-i18n/vite';
import { PrimeVueResolver } from '@primevue/auto-import-resolver';
import { unheadVueComposablesImports } from '@unhead/vue';
@@ -26,6 +25,7 @@ import { createUtils4uAutoImports } from 'utils4u/auto-imports';
import { PluginOption } from 'vite';
import cdnImport from 'vite-plugin-cdn-import';
import { vitePluginFakeServer } from 'vite-plugin-fake-server';
+import { viteStaticCopy } from 'vite-plugin-static-copy';
import VueDevTools from 'vite-plugin-vue-devtools';
import Layouts from 'vite-plugin-vue-layouts';
import MetaLayouts from 'vite-plugin-vue-meta-layouts';
@@ -42,22 +42,22 @@ export function Plugins() {
plugins.push(
VueMacros({
plugins: {
+ vue: Vue({ include: [/\.vue$/, /\.md$/] }),
+ vueJsx: VueJsx(), // 如有需要
// https://uvr.esm.is/guide/configuration.html
// https://github.com/posva/unplugin-vue-router
vueRouter: VueRouter({
- routesFolder: 'src/pages',
exclude: ['**/__*', '**/__*/**/*'],
+ extensions: ['.page.vue', '.page.md'],
getRouteName: (routeNode) => getPascalCaseRouteName(routeNode),
logs: false,
- extensions: ['.page.vue', '.page.md'],
+ routesFolder: 'src/pages',
}),
- vue: Vue({ include: [/\.vue$/, /\.md$/] }),
- vueJsx: VueJsx(), // 如有需要
},
}), // https://vue-macros.dev/zh-CN/guide/bundler-integration.html
// https://github.com/JohnCampionJr/vite-plugin-vue-layouts?tab=readme-ov-file#configuration
- Layouts({ pagesDirs: [], defaultLayout: 'sakai-vue/AppLayout' }),
+ Layouts({ defaultLayout: 'sakai-vue/AppLayout', pagesDirs: [] }),
// https://github.com/dishait/vite-plugin-vue-meta-layouts
MetaLayouts({
@@ -76,7 +76,11 @@ export function Plugins() {
// https://github.com/antfu/unplugin-auto-import
AutoImport({
- resolvers: [TDesignResolver({ library: 'mobile-vue', esm: true }), VantResolver({ importStyle: true })],
+ dirs: [
+ // 'src/composables',
+ 'src/stores',
+ 'src/utils',
+ ],
imports: [
'vue',
'vue-i18n',
@@ -95,37 +99,33 @@ export function Plugins() {
},
),
{
+ 'consola/browser': ['consola'],
// add any other imports you were relying on
'vue-router/auto': ['useLink'],
- 'consola/browser': ['consola'],
},
],
- dirs: [
- // 'src/composables',
- 'src/stores',
- 'src/utils',
- ],
+ resolvers: [TDesignResolver({ esm: true, library: 'mobile-vue' }), VantResolver({ importStyle: true })],
vueTemplate: true,
}),
// https://github.com/antfu/unplugin-vue-components
Components({
+ // __开头的
+ excludeNames: [/^__/],
// allow auto load markdown components under `./src/components/`
extensions: ['vue', 'md'],
// allow auto import and register components used in markdown
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
- // __开头的
- excludeNames: [/^__/],
resolvers: [
AntDesignVueResolver({
importStyle: false, // css in js
resolveIcons: true,
}),
IconsResolver({
- prefix: 'icon',
customCollections: ['svg'],
+ prefix: 'icon',
}), // https://github.com/unplugin/unplugin-icons?tab=readme-ov-file#auto-importing
- TDesignResolver({ library: 'mobile-vue', esm: true }),
+ TDesignResolver({ esm: true, library: 'mobile-vue' }),
VantResolver({ importStyle: true }),
PrimeVueResolver(/* { components: { prefix: 'P' } } */),
],
@@ -166,9 +166,9 @@ export function Plugins() {
// https://github.com/condorheroblog/vite-plugin-fake-server?tab=readme-ov-file#usage
vitePluginFakeServer({
- include: 'fake',
basename: 'fake-api',
enableProd: true,
+ include: 'fake',
}),
viteStaticCopy({
@@ -195,9 +195,9 @@ export function Plugins() {
// https://github.com/mmf-fe/vite-plugin-cdn-import/blob/HEAD/README.zh-CN.md
// 会对 Components 插件的自动导入产生影响。
cdnImport({
+ enableInDevMode: true,
modules: ['vue'],
prodUrl: '//fastly.jsdelivr.net/npm/{name}@{version}/{path}',
- enableInDevMode: true,
}),
);
};
diff --git a/vite.config.ts b/vite.config.ts
index 0c27c46..b13a732 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -7,29 +7,14 @@ import { defineConfig, loadEnv } from 'vite';
import { cesiumBaseUrl, Plugins } from './vite.config.plugins';
// https://vitejs.dev/config/
-export default defineConfig(({ mode, command }) => {
+export default defineConfig(({ command, mode }) => {
const isBuild = command === 'build';
const env = loadEnv(mode, process.cwd());
return {
base: env.VITE_BASE,
- plugins: Plugins(),
- define: {
- $__DEV__: JSON.stringify(!isBuild),
- CESIUM_BASE_URL: JSON.stringify(`/${cesiumBaseUrl}`),
- },
- resolve: {
- alias: {
- '@': fileURLToPath(new URL('./src', import.meta.url)),
- },
- },
- server: {
- proxy: createViteProxy(),
- allowedHosts: ['.nwct.dev'],
- },
build: {
minify: 'terser',
- sourcemap: mode !== 'production' || env.VITE_SOURCE_MAP === 'true',
rollupOptions: {
onwarn: (warning, warn) => {
if (warning.code === 'EMPTY_BUNDLE') return;
@@ -54,6 +39,21 @@ export default defineConfig(({ mode, command }) => {
// },
},
},
+ sourcemap: mode !== 'production' || env.VITE_SOURCE_MAP === 'true',
+ },
+ define: {
+ $__DEV__: JSON.stringify(!isBuild),
+ CESIUM_BASE_URL: JSON.stringify(`/${cesiumBaseUrl}`),
+ },
+ plugins: Plugins(),
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
+ },
+ },
+ server: {
+ allowedHosts: ['.nwct.dev'],
+ proxy: createViteProxy(),
},
};
});