mirror of
https://github.com/sunniejs/vue-h5-template.git
synced 2026-04-29 18:34:09 +08:00
fix: 修复已知的问题和更新相关的依赖
This commit is contained in:
parent
58addfde56
commit
293bcb0291
@ -16,6 +16,7 @@
|
|||||||
"ShallowRef": true,
|
"ShallowRef": true,
|
||||||
"Slot": true,
|
"Slot": true,
|
||||||
"Slots": true,
|
"Slots": true,
|
||||||
|
"Snackbar": true,
|
||||||
"VNode": true,
|
"VNode": true,
|
||||||
"WritableComputedRef": true,
|
"WritableComputedRef": true,
|
||||||
"acceptHMRUpdate": true,
|
"acceptHMRUpdate": true,
|
||||||
@ -71,6 +72,7 @@
|
|||||||
"shallowReactive": true,
|
"shallowReactive": true,
|
||||||
"shallowReadonly": true,
|
"shallowReadonly": true,
|
||||||
"shallowRef": true,
|
"shallowRef": true,
|
||||||
|
"showToast": true,
|
||||||
"storeToRefs": true,
|
"storeToRefs": true,
|
||||||
"toRaw": true,
|
"toRaw": true,
|
||||||
"toRef": true,
|
"toRef": true,
|
||||||
|
|||||||
21
.vscode/extensions.json
vendored
21
.vscode/extensions.json
vendored
@ -1,5 +1,22 @@
|
|||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"vue.volar"
|
// Vue 3 的语言支持
|
||||||
|
"Vue.volar",
|
||||||
|
// 将 ESLint JavaScript 集成到 VS Code 中。
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
// 使用 Prettier 的代码格式化程序
|
||||||
|
"esbenp.prettier-vscode",
|
||||||
|
// 支持 dotenv 文件语法
|
||||||
|
"mikestead.dotenv",
|
||||||
|
// 源代码的拼写检查器
|
||||||
|
"streetsidesoftware.code-spell-checker",
|
||||||
|
// i18n 插件
|
||||||
|
"Lokalise.i18n-ally",
|
||||||
|
// CSS 变量提示
|
||||||
|
"vunguyentuan.vscode-css-variables",
|
||||||
|
],
|
||||||
|
"unwantedRecommendations": [
|
||||||
|
// 和 volar 冲突
|
||||||
|
"octref.vetur"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
24
.vscode/settings.json
vendored
24
.vscode/settings.json
vendored
@ -87,21 +87,8 @@
|
|||||||
"source.fixAll.eslint": "explicit"
|
"source.fixAll.eslint": "explicit"
|
||||||
},
|
},
|
||||||
"[vue]": {
|
"[vue]": {
|
||||||
"editor.codeActionsOnSave": {
|
|
||||||
"source.fixAll.eslint": "explicit",
|
|
||||||
"source.fixAll.stylelint": "explicit"
|
|
||||||
},
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
},
|
},
|
||||||
"i18n-ally.localesPaths": ["src/locales/lang"],
|
|
||||||
"i18n-ally.keystyle": "nested",
|
|
||||||
"i18n-ally.sortKeys": true,
|
|
||||||
"i18n-ally.namespace": true,
|
|
||||||
"i18n-ally.pathMatcher": "{locale}/{namespaces}.{ext}",
|
|
||||||
"i18n-ally.enabledParsers": ["ts"],
|
|
||||||
"i18n-ally.sourceLanguage": "en",
|
|
||||||
"i18n-ally.displayLanguage": "zh-CN",
|
|
||||||
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"antd",
|
"antd",
|
||||||
"antv",
|
"antv",
|
||||||
@ -147,5 +134,14 @@
|
|||||||
"windi",
|
"windi",
|
||||||
"windicss",
|
"windicss",
|
||||||
"zxcvbn"
|
"zxcvbn"
|
||||||
]
|
],
|
||||||
|
"i18n-ally.localesPaths": ["src/locales/langs"],
|
||||||
|
"i18n-ally.pathMatcher": "{locale}/{namespace}.{ext}",
|
||||||
|
"i18n-ally.enabledParsers": ["json"],
|
||||||
|
"i18n-ally.sourceLanguage": "en",
|
||||||
|
"i18n-ally.displayLanguage": "zh-CN",
|
||||||
|
"i18n-ally.enabledFrameworks": ["vue", "react"],
|
||||||
|
"i18n-ally.keystyle": "nested",
|
||||||
|
"i18n-ally.sortKeys": true,
|
||||||
|
"i18n-ally.namespace": true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,6 @@ export const ConfigAutoComponentsPlugin = () => {
|
|||||||
directives: true,
|
directives: true,
|
||||||
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
|
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
|
||||||
exclude: [/[\\/]node_modules[\\/]/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/],
|
exclude: [/[\\/]node_modules[\\/]/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/],
|
||||||
resolvers: [VueUseComponentsResolver(), VantResolver(), VarletImportResolver(), NutUIResolver({ importStyle: 'sass' })],
|
resolvers: [VueUseComponentsResolver(), VantResolver(), VarletImportResolver(), NutUIResolver()],
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import skipFormatting from '@vue/eslint-config-prettier/skip-formatting';
|
|||||||
export default defineConfigWithVueTs(
|
export default defineConfigWithVueTs(
|
||||||
pluginVue.configs['flat/essential'],
|
pluginVue.configs['flat/essential'],
|
||||||
vueTsConfigs.recommended,
|
vueTsConfigs.recommended,
|
||||||
|
|
||||||
skipFormatting,
|
skipFormatting,
|
||||||
{
|
{
|
||||||
name: 'app/files-to-lint',
|
name: 'app/files-to-lint',
|
||||||
@ -17,6 +16,5 @@ export default defineConfigWithVueTs(
|
|||||||
'vue/multi-word-component-names': 'off',
|
'vue/multi-word-component-names': 'off',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
|
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
|
||||||
);
|
);
|
||||||
|
|||||||
2554
package-lock.json
generated
2554
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
77
package.json
77
package.json
@ -16,65 +16,65 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nutui/icons-vue": "^0.1.1",
|
"@nutui/icons-vue": "^0.1.1",
|
||||||
"@nutui/nutui": "^4.3.13",
|
"@nutui/nutui": "^4.3.13",
|
||||||
"@varlet/ui": "^3.12.0",
|
"@varlet/ui": "^3.13.0",
|
||||||
"@vueuse/core": "13.9.0",
|
"@vueuse/core": "14.1.0",
|
||||||
"@vueuse/integrations": "13.9.0",
|
"@vueuse/integrations": "14.1.0",
|
||||||
"axios": "1.12.2",
|
"axios": "1.13.2",
|
||||||
"dayjs": "^1.11.18",
|
"dayjs": "^1.11.19",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"pinia": "^3.0.2",
|
"pinia": "^3.0.4",
|
||||||
"pinia-plugin-persistedstate": "^4.5.0",
|
"pinia-plugin-persistedstate": "^4.7.1",
|
||||||
"universal-cookie": "^8.0.1",
|
"universal-cookie": "^8.0.1",
|
||||||
"vant": "^4.9.19",
|
"vant": "^4.9.22",
|
||||||
"vue": "^3.5.22",
|
"vue": "^3.5.27",
|
||||||
"vue-i18n": "^11.1.12",
|
"vue-i18n": "^11.2.8",
|
||||||
"vue-router": "^4.6.3"
|
"vue-router": "^4.6.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^20.1.0",
|
"@commitlint/cli": "^20.3.1",
|
||||||
"@commitlint/config-conventional": "^20.0.0",
|
"@commitlint/config-conventional": "^20.3.1",
|
||||||
"@nutui/auto-import-resolver": "^1.0.0",
|
"@nutui/auto-import-resolver": "^1.0.0",
|
||||||
"@stylistic/stylelint-plugin": "^4.0.0",
|
"@stylistic/stylelint-plugin": "^4.0.0",
|
||||||
"@tsconfig/node22": "^22.0.2",
|
"@tsconfig/node22": "^22.0.5",
|
||||||
"@types/jsdom": "^21.1.7",
|
"@types/jsdom": "^21.1.7",
|
||||||
"@types/node": "^24.8.1",
|
"@types/node": "^24.8.1",
|
||||||
"@typescript-eslint/parser": "^8.46.1",
|
"@typescript-eslint/parser": "^8.53.1",
|
||||||
"@vant/auto-import-resolver": "^1.3.0",
|
"@vant/auto-import-resolver": "^1.3.0",
|
||||||
"@varlet/import-resolver": "^3.12.0",
|
"@varlet/import-resolver": "^3.13.0",
|
||||||
"@vitejs/plugin-basic-ssl": "^2.0.0",
|
"@vitejs/plugin-basic-ssl": "^2.1.4",
|
||||||
"@vitejs/plugin-legacy": "^7.2.1",
|
"@vitejs/plugin-legacy": "^7.2.1",
|
||||||
"@vitejs/plugin-vue": "^6.0.1",
|
"@vitejs/plugin-vue": "^6.0.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^5.1.1",
|
"@vitejs/plugin-vue-jsx": "^5.1.3",
|
||||||
"@vue/eslint-config-prettier": "^10.2.0",
|
"@vue/eslint-config-prettier": "^10.2.0",
|
||||||
"@vue/eslint-config-typescript": "^14.5.0",
|
"@vue/eslint-config-typescript": "^14.5.0",
|
||||||
"@vue/test-utils": "^2.4.0",
|
"@vue/test-utils": "^2.4.0",
|
||||||
"@vue/tsconfig": "^0.8.1",
|
"@vue/tsconfig": "^0.8.1",
|
||||||
"@zhaojjiang/vite-plugin-eruda": "^0.0.5",
|
"@zhaojjiang/vite-plugin-eruda": "^0.0.5",
|
||||||
"amfe-flexible": "^2.2.1",
|
"amfe-flexible": "^2.2.1",
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.23",
|
||||||
"cnjm-postcss-px-to-viewport": "^1.0.1",
|
"cnjm-postcss-px-to-viewport": "^1.0.1",
|
||||||
"consola": "^3.4.2",
|
"consola": "^3.4.2",
|
||||||
"cross-env": "^10.0.0",
|
"cross-env": "^10.1.0",
|
||||||
"cz-git": "^1.11.1",
|
"cz-git": "^1.11.1",
|
||||||
"czg": "^1.11.1",
|
"czg": "^1.11.1",
|
||||||
"eruda": "^3.4.1",
|
"eruda": "^3.4.1",
|
||||||
"eslint": "^9.37.0",
|
"eslint": "^9.39.2",
|
||||||
"eslint-define-config": "^2.1.0",
|
"eslint-define-config": "^2.1.0",
|
||||||
"eslint-plugin-import": "^2.31.0",
|
"eslint-plugin-import": "^2.31.0",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"eslint-plugin-prettier": "^5.5.5",
|
||||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||||
"eslint-plugin-vue": "^10.5.1",
|
"eslint-plugin-vue": "^10.7.0",
|
||||||
"git-cz": "^4.9.0",
|
"git-cz": "^4.9.0",
|
||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
"jsdom": "^26.1.0",
|
"jsdom": "^27.4.0",
|
||||||
"lint-staged": "16.2.4",
|
"lint-staged": "16.2.7",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"node": "^22.18.0",
|
"node": "^22.18.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"postcss": "^8.5.3",
|
"postcss": "^8.5.3",
|
||||||
"postcss-html": "1.8.0",
|
"postcss-html": "1.8.1",
|
||||||
"postcss-scss": "^4.0.9",
|
"postcss-scss": "^4.0.9",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.8.0",
|
||||||
"rollup-plugin-visualizer": "^6.0.5",
|
"rollup-plugin-visualizer": "^6.0.5",
|
||||||
"stylelint": "^16.25.0",
|
"stylelint": "^16.25.0",
|
||||||
"stylelint-config-recess-order": "^7.4.0",
|
"stylelint-config-recess-order": "^7.4.0",
|
||||||
@ -82,27 +82,27 @@
|
|||||||
"stylelint-config-recommended-scss": "^16.0.0",
|
"stylelint-config-recommended-scss": "^16.0.0",
|
||||||
"stylelint-config-recommended-vue": "^1.5.0",
|
"stylelint-config-recommended-vue": "^1.5.0",
|
||||||
"stylelint-config-standard": "^39.0.1",
|
"stylelint-config-standard": "^39.0.1",
|
||||||
"stylelint-order": "^7.0.0",
|
"stylelint-order": "^7.0.1",
|
||||||
"stylelint-prettier": "^5.0.3",
|
"stylelint-prettier": "^5.0.3",
|
||||||
"stylelint-scss": "^6.11.0",
|
"stylelint-scss": "^6.11.0",
|
||||||
"terser": "^5.19.0",
|
"terser": "^5.46.0",
|
||||||
"typescript": "5.9.3",
|
"typescript": "5.9.3",
|
||||||
"unplugin-auto-import": "^20.2.0",
|
"unplugin-auto-import": "^21.0.0",
|
||||||
"unplugin-vue-components": "^29.1.0",
|
"unplugin-vue-components": "^31.0.0",
|
||||||
"vite": "^7.1.10",
|
"vite": "^7.3.1",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-imagemin": "^0.6.1",
|
"vite-plugin-imagemin": "^0.6.1",
|
||||||
"vite-plugin-mock": "^3.0.2",
|
"vite-plugin-mock": "^3.0.2",
|
||||||
"vite-plugin-pages": "^0.33.0",
|
"vite-plugin-pages": "^0.33.2",
|
||||||
"vite-plugin-progress": "^0.0.7",
|
"vite-plugin-progress": "^0.0.7",
|
||||||
"vite-plugin-pwa": "^1.1.0",
|
"vite-plugin-pwa": "^1.2.0",
|
||||||
"vite-plugin-qrcode": "^0.3.0",
|
"vite-plugin-qrcode": "^0.3.0",
|
||||||
"vite-plugin-restart": "^1.0.0",
|
"vite-plugin-restart": "^2.0.0",
|
||||||
"vite-plugin-svg-icons": "^2.0.1",
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
"vite-plugin-vue-setup-extend-plus": "^0.1.0",
|
"vite-plugin-vue-setup-extend-plus": "^0.1.0",
|
||||||
"vitest": "^3.1.3",
|
"vitest": "^4.0.17",
|
||||||
"vue-eslint-parser": "^10.1.3",
|
"vue-eslint-parser": "^10.1.3",
|
||||||
"vue-tsc": "^3.1.1"
|
"vue-tsc": "^3.2.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.10.0",
|
"node": ">=20.10.0",
|
||||||
@ -141,7 +141,6 @@
|
|||||||
"prettier --write"
|
"prettier --write"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.26.2",
|
|
||||||
"config": {
|
"config": {
|
||||||
"commitizen": {
|
"commitizen": {
|
||||||
"path": "node_modules/cz-git"
|
"path": "node_modules/cz-git"
|
||||||
|
|||||||
2338
pnpm-lock.yaml
generated
2338
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 63 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.4 KiB |
@ -1,27 +0,0 @@
|
|||||||
import { createI18n } from 'vue-i18n';
|
|
||||||
|
|
||||||
export function loadLang() {
|
|
||||||
const modules: Record<string, any> = import.meta.glob('./lang/*.ts', { eager: true });
|
|
||||||
const langs: Record<string, any> = {};
|
|
||||||
|
|
||||||
for (const path in modules) {
|
|
||||||
const name = path.replace(/(\.\/lang\/|\.ts)/g, '');
|
|
||||||
langs[name] = modules[path].lang;
|
|
||||||
}
|
|
||||||
return langs;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const i18n = createI18n({
|
|
||||||
// globalInjection: true,
|
|
||||||
legacy: false,
|
|
||||||
locale: 'zh-cn',
|
|
||||||
fallbackLocale: 'zh-cn',
|
|
||||||
messages: loadLang(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export function setLang(locale?: string) {
|
|
||||||
if (locale) {
|
|
||||||
localStorage.setItem('lang', locale);
|
|
||||||
}
|
|
||||||
i18n.global.locale.value = locale || localStorage.getItem('lang') || '';
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import type { langType } from './lang-base';
|
|
||||||
|
|
||||||
export const lang: langType = {
|
|
||||||
title: 'VUE H5 development template',
|
|
||||||
tabbar: {
|
|
||||||
home: 'Home',
|
|
||||||
list: 'List',
|
|
||||||
member: 'Member',
|
|
||||||
demo: 'demo',
|
|
||||||
},
|
|
||||||
language: {
|
|
||||||
en: 'English',
|
|
||||||
zh: 'Chinese',
|
|
||||||
},
|
|
||||||
introduction: 'A rapid development vue3 of mobile terminal template',
|
|
||||||
home: {
|
|
||||||
support: 'support',
|
|
||||||
cssMultiLanguage: 'CSS picture multi-language',
|
|
||||||
},
|
|
||||||
list: {
|
|
||||||
details: 'list details',
|
|
||||||
},
|
|
||||||
btn: {
|
|
||||||
confirm: 'confirm',
|
|
||||||
cancel: 'cancel',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import type { langType } from './lang-base';
|
|
||||||
|
|
||||||
export const lang: langType = {
|
|
||||||
title: 'VUE H5开发模板',
|
|
||||||
tabbar: {
|
|
||||||
home: '首页',
|
|
||||||
list: '列表',
|
|
||||||
member: '我的',
|
|
||||||
demo: '示例',
|
|
||||||
},
|
|
||||||
language: {
|
|
||||||
en: '英文',
|
|
||||||
zh: '中文',
|
|
||||||
},
|
|
||||||
introduction: '一个快速开发vue3的移动端模板',
|
|
||||||
home: {
|
|
||||||
support: '支持',
|
|
||||||
cssMultiLanguage: 'css图片多语言',
|
|
||||||
},
|
|
||||||
list: {
|
|
||||||
details: '列表详情',
|
|
||||||
},
|
|
||||||
btn: {
|
|
||||||
confirm: '确认',
|
|
||||||
cancel: '取消',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@ -1,16 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<van-nav-bar :title="$t($route.meta.title as string)" :left-arrow="!tabbarVisible" @click-left="goBack" />
|
<div class="main-page">
|
||||||
<div class="main-page" :class="{ tabbar: tabbarVisible, border: showBorder }">
|
<van-nav-bar :title="$t($route.meta.title as string)" :left-arrow="!tabbarVisible" @click-left="goBack" />
|
||||||
<RouterView v-slot="{ Component }" v-if="$route.meta.keepAlive">
|
<div class="main-box" :class="{ tabbar: tabbarVisible, border: showBorder }">
|
||||||
<keep-alive>
|
<RouterView v-slot="{ Component }" v-if="$route.meta.keepAlive">
|
||||||
<component :is="Component" :key="$route.path" />
|
<keep-alive>
|
||||||
</keep-alive>
|
<component :is="Component" :key="$route.path" />
|
||||||
</RouterView>
|
</keep-alive>
|
||||||
<RouterView v-if="!$route.meta.keepAlive" :key="$route.path" />
|
</RouterView>
|
||||||
|
<RouterView v-if="!$route.meta.keepAlive" :key="$route.path" />
|
||||||
|
</div>
|
||||||
|
<nut-tabbar
|
||||||
|
unactive-color="#364636"
|
||||||
|
active-color="#1989fa"
|
||||||
|
v-model="activeTab"
|
||||||
|
v-show="tabbarVisible"
|
||||||
|
@tab-switch="tabSwitch"
|
||||||
|
safe-area-inset-bottom
|
||||||
|
>
|
||||||
|
<nut-tabbar-item v-for="item in tabItem" :key="item.key" :tab-title="$t(`common.tabbar.${item.key}`)" :icon="item.icon" />
|
||||||
|
</nut-tabbar>
|
||||||
</div>
|
</div>
|
||||||
<nut-tabbar unactive-color="#364636" active-color="#1989fa" bottom v-model="activeTab" v-show="tabbarVisible" @tab-switch="tabSwitch">
|
|
||||||
<nut-tabbar-item v-for="item in tabItem" :key="item.key" :tab-title="$t(`tabbar.${item.key}`)" :icon="item.icon" />
|
|
||||||
</nut-tabbar>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="BasicLayoutPage">
|
<script lang="ts" setup name="BasicLayoutPage">
|
||||||
@ -43,7 +52,7 @@
|
|||||||
{ deep: true, immediate: true },
|
{ deep: true, immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
const tabSwitch = (_item, index) => {
|
const tabSwitch = (_item: any, index: number) => {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
router.push('/home');
|
router.push('/home');
|
||||||
@ -72,14 +81,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.main-page {
|
.main-page {
|
||||||
box-sizing: border-box;
|
display: flex;
|
||||||
height: calc(100vh - 92px);
|
flex-direction: column;
|
||||||
overflow: hidden scroll;
|
width: 100dvw;
|
||||||
}
|
height: 100dvh;
|
||||||
|
|
||||||
.tabbar {
|
.main-box {
|
||||||
height: calc(100vh - 92px);
|
flex: auto;
|
||||||
padding-bottom: 100px;
|
min-height: 0;
|
||||||
|
overflow: hidden auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.border {
|
.border {
|
||||||
|
|||||||
78
src/locales/index.ts
Normal file
78
src/locales/index.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { createI18n } from 'vue-i18n';
|
||||||
|
import type { App } from 'vue';
|
||||||
|
|
||||||
|
const LOCALE_KEY = 'lang';
|
||||||
|
const DEFAULT_LOCALE = 'zh-CN';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扫描所有语言文件(懒加载)
|
||||||
|
*/
|
||||||
|
const modules = import.meta.glob('./langs/**/*.json');
|
||||||
|
|
||||||
|
const localeLoaders: Record<string, () => Promise<any>> = {};
|
||||||
|
|
||||||
|
Object.keys(modules).forEach((path) => {
|
||||||
|
// ./langs/zh-CN/common.json
|
||||||
|
const match = path.match(/\.\/langs\/([^/]+)\/(.+)\.json$/);
|
||||||
|
if (!match) return;
|
||||||
|
|
||||||
|
const locale: any = match[1];
|
||||||
|
|
||||||
|
if (!localeLoaders[locale]) {
|
||||||
|
localeLoaders[locale] = async () => {
|
||||||
|
const messages: Record<string, any> = {};
|
||||||
|
|
||||||
|
for (const p in modules) {
|
||||||
|
const m = p.match(new RegExp(`./langs/${locale}/(.+)\\.json$`));
|
||||||
|
if (!m) continue;
|
||||||
|
|
||||||
|
const namespace: any = m[1];
|
||||||
|
if (modules[p]) {
|
||||||
|
const mod: any = await modules[p]();
|
||||||
|
messages[namespace] = mod.default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* i18n 实例(初始不加载 messages)
|
||||||
|
*/
|
||||||
|
export const i18n = createI18n({
|
||||||
|
legacy: false,
|
||||||
|
globalInjection: true,
|
||||||
|
locale: '',
|
||||||
|
fallbackLocale: DEFAULT_LOCALE,
|
||||||
|
messages: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置语言
|
||||||
|
*/
|
||||||
|
export async function setLang(locale?: string) {
|
||||||
|
const target = locale || localStorage.getItem(LOCALE_KEY) || DEFAULT_LOCALE;
|
||||||
|
|
||||||
|
if (!i18n.global.availableLocales.includes(target)) {
|
||||||
|
const loader = localeLoaders[target];
|
||||||
|
if (loader) {
|
||||||
|
const messages = await loader();
|
||||||
|
console.log(messages);
|
||||||
|
i18n.global.setLocaleMessage(target, messages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i18n.global.locale.value = target;
|
||||||
|
localStorage.setItem(LOCALE_KEY, target);
|
||||||
|
document.documentElement.lang = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化(main.ts 调用)
|
||||||
|
*/
|
||||||
|
export async function setupI18n(app: App) {
|
||||||
|
app.use(i18n);
|
||||||
|
await setLang();
|
||||||
|
}
|
||||||
@ -13,7 +13,6 @@ export type langType = {
|
|||||||
introduction: string;
|
introduction: string;
|
||||||
home: {
|
home: {
|
||||||
support: string;
|
support: string;
|
||||||
cssMultiLanguage: string;
|
|
||||||
};
|
};
|
||||||
list: {
|
list: {
|
||||||
details: string;
|
details: string;
|
||||||
25
src/locales/langs/en-US/common.json
Normal file
25
src/locales/langs/en-US/common.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"title": "VUE H5 development template",
|
||||||
|
"tabbar": {
|
||||||
|
"home": "Home",
|
||||||
|
"list": "List",
|
||||||
|
"member": "Member",
|
||||||
|
"demo": "demo"
|
||||||
|
},
|
||||||
|
"language": {
|
||||||
|
"en": "English",
|
||||||
|
"zh": "Chinese"
|
||||||
|
},
|
||||||
|
"introduction": "A rapid development vue3 of mobile terminal template",
|
||||||
|
"home": {
|
||||||
|
"support": "support"
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"details": "list details"
|
||||||
|
},
|
||||||
|
"btn": {
|
||||||
|
"confirm": "confirm",
|
||||||
|
"cancel": "cancel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
24
src/locales/langs/zh-CN/common.json
Normal file
24
src/locales/langs/zh-CN/common.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"title": "VUE H5开发模板",
|
||||||
|
"tabbar": {
|
||||||
|
"home": "首页",
|
||||||
|
"list": "列表",
|
||||||
|
"member": "我的",
|
||||||
|
"demo": "示例"
|
||||||
|
},
|
||||||
|
"language": {
|
||||||
|
"en": "英文",
|
||||||
|
"zh": "中文"
|
||||||
|
},
|
||||||
|
"introduction": "一个快速开发vue3的移动端模板",
|
||||||
|
"home": {
|
||||||
|
"support": "支持"
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"details": "列表详情"
|
||||||
|
},
|
||||||
|
"btn": {
|
||||||
|
"confirm": "确认",
|
||||||
|
"cancel": "取消"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,10 @@
|
|||||||
import { createApp } from 'vue';
|
import { createApp } from 'vue';
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
import { i18n } from '@/i18n';
|
import { setupI18n } from '@/locales';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
import store from '@/store';
|
import store from '@/store';
|
||||||
import './assets/font/iconfont.css';
|
import './assets/font/iconfont.css';
|
||||||
|
import '@/styles/index.scss';
|
||||||
|
|
||||||
import '@nutui/nutui/dist/packages/toast/style/css';
|
import '@nutui/nutui/dist/packages/toast/style/css';
|
||||||
import '@nutui/nutui/dist/packages/notify/style/css';
|
import '@nutui/nutui/dist/packages/notify/style/css';
|
||||||
@ -16,7 +17,7 @@ const app = createApp(App);
|
|||||||
app.use(router);
|
app.use(router);
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
app.use(i18n);
|
await setupI18n(app);
|
||||||
|
|
||||||
// 状态管理
|
// 状态管理
|
||||||
app.use(store);
|
app.use(store);
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
export const routes = [
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
|
export const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
redirect: '/home',
|
redirect: '/home',
|
||||||
@ -8,7 +10,7 @@ export const routes = [
|
|||||||
path: 'home',
|
path: 'home',
|
||||||
component: () => import('@/views/home/index.vue'),
|
component: () => import('@/views/home/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'tabbar.home',
|
title: 'common.tabbar.home',
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -16,7 +18,7 @@ export const routes = [
|
|||||||
path: 'list',
|
path: 'list',
|
||||||
component: () => import('@/views/list/index.vue'),
|
component: () => import('@/views/list/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'tabbar.list',
|
title: 'common.tabbar.list',
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -24,7 +26,7 @@ export const routes = [
|
|||||||
path: 'member',
|
path: 'member',
|
||||||
component: () => import('@/views/member/index.vue'),
|
component: () => import('@/views/member/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'tabbar.member',
|
title: 'common.tabbar.member',
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -32,7 +34,7 @@ export const routes = [
|
|||||||
path: 'demo',
|
path: 'demo',
|
||||||
component: () => import('@/views/demo/index.vue'),
|
component: () => import('@/views/demo/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'tabbar.demo',
|
title: 'common.tabbar.demo',
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -41,7 +43,7 @@ export const routes = [
|
|||||||
path: '/details',
|
path: '/details',
|
||||||
component: () => import('@/views/list/details/index.vue'),
|
component: () => import('@/views/list/details/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'list.details',
|
title: 'common.list.details',
|
||||||
border: false,
|
border: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,16 +1,32 @@
|
|||||||
.abc {
|
*,
|
||||||
width: 10px;
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
html,
|
body {
|
||||||
body,
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6,
|
|
||||||
p {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
font-family:
|
||||||
|
Inter,
|
||||||
|
-apple-system,
|
||||||
|
BlinkMacSystemFont,
|
||||||
|
'Segoe UI',
|
||||||
|
Roboto,
|
||||||
|
Oxygen,
|
||||||
|
Ubuntu,
|
||||||
|
Cantarell,
|
||||||
|
'Fira Sans',
|
||||||
|
'Droid Sans',
|
||||||
|
'Helvetica Neue',
|
||||||
|
sans-serif;
|
||||||
|
color: var(--color-text);
|
||||||
|
background: var(--color-background);
|
||||||
|
text-rendering: optimizelegibility;
|
||||||
|
transition:
|
||||||
|
color 0.5s,
|
||||||
|
background-color 0.5s;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
@mixin main-lang-bg($width, $height, $preUrl, $posUrl) {
|
|
||||||
width: $width;
|
|
||||||
height: $height;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
|
|
||||||
@include loop-lang-bg($preUrl, $posUrl);
|
|
||||||
}
|
|
||||||
// 背景图多语言
|
|
||||||
@mixin loop-lang-bg($preUrl, $posUrl) {
|
|
||||||
$list: zh-cn, en-us;
|
|
||||||
|
|
||||||
@each $i in $list {
|
|
||||||
&.#{$i} {
|
|
||||||
background-image: url('#{$preUrl}/#{$i}/#{$posUrl}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin center {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
:root {
|
|
||||||
.van-popup {
|
|
||||||
max-width: 750px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
0
src/styles/variable.scss
Normal file
0
src/styles/variable.scss
Normal file
@ -1,2 +0,0 @@
|
|||||||
$primary-color: green;
|
|
||||||
$primary-color-end: #496af2;
|
|
||||||
@ -1,42 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<img src="https://cdn.jsdelivr.net/gh/fonghehe/picture/vue-h5-template/logo.png" alt="" /><span> {{ $t('title') }}</span>
|
<img src="https://cdn.jsdelivr.net/gh/fonghehe/picture/vue-h5-template/logo.png" alt="" /><span> {{ $t('common.title') }}</span>
|
||||||
</header>
|
</header>
|
||||||
<div class="intro-header">
|
<div class="intro-header">
|
||||||
<div>{{ $t('introduction') }}</div>
|
<div>{{ $t('common.introduction') }} </div>
|
||||||
<a href="https://github.com/sunniejs/vue-h5-template.git">
|
<a href="https://github.com/sunniejs/vue-h5-template.git">
|
||||||
<Github />
|
<Github />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<nut-cell-group :title="$t('home.support')" class="supportList">
|
<nut-cell-group :title="$t('common.home.support')" class="supportList">
|
||||||
<nut-cell v-for="(item, index) in cellList" :key="index" :title="item">
|
<nut-cell v-for="(item, index) in cellList" :key="index" :title="item">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<Check />
|
<Check />
|
||||||
</template>
|
</template>
|
||||||
</nut-cell>
|
</nut-cell>
|
||||||
</nut-cell-group>
|
</nut-cell-group>
|
||||||
<nut-cell-group :title="$t('home.cssMultiLanguage')" class="supportList">
|
|
||||||
<nut-cell>
|
|
||||||
<div :class="['btn-confirm', locale]"></div>
|
|
||||||
</nut-cell>
|
|
||||||
</nut-cell-group>
|
|
||||||
<div class="btn-wrap">
|
<div class="btn-wrap">
|
||||||
<nut-button shape="square" size="small" type="default" @click="changeLang('zh-cn')">
|
<nut-button shape="square" size="small" type="default" @click="changeLang('zh-CN')">
|
||||||
{{ $t('language.zh') }}
|
{{ $t('common.language.zh') }}
|
||||||
</nut-button>
|
|
||||||
<nut-button shape="square" size="small" type="default" @click="changeLang('en-us')">
|
|
||||||
{{ $t('language.en') }}
|
|
||||||
</nut-button>
|
</nut-button>
|
||||||
|
<nut-button shape="square" size="small" type="default" @click="changeLang('en-US')"> {{ $t('common.language.en') }}</nut-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { setLang } from '@/i18n';
|
import { setLang } from '@/locales';
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { Github, Check } from '@nutui/icons-vue';
|
import { Github, Check } from '@nutui/icons-vue';
|
||||||
|
|
||||||
const { locale } = useI18n();
|
|
||||||
|
|
||||||
const cellList = ['vue3', 'vite', 'vue-router', 'axios', 'Pinia', 'vue-i18n', 'postcss-px-to-viewport', 'varlet / vant / nutUI', 'eruda'];
|
const cellList = ['vue3', 'vite', 'vue-router', 'axios', 'Pinia', 'vue-i18n', 'postcss-px-to-viewport', 'varlet / vant / nutUI', 'eruda'];
|
||||||
|
|
||||||
const changeLang = (type: string) => {
|
const changeLang = (type: string) => {
|
||||||
@ -45,18 +35,16 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@use '@/styles/mixin.scss' as *;
|
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
font-size: 40px;
|
font-size: 36px;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 90px;
|
width: 60px;
|
||||||
height: 90px;
|
height: 60px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,8 +67,4 @@
|
|||||||
.btn-wrap {
|
.btn-wrap {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-confirm {
|
|
||||||
@include main-lang-bg(302px, 82px, '@/assets/button', 'confirm.png');
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -12,13 +12,29 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span>{{ details.data?.title }}}</span>
|
<span>{{ details.data?.title }}</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- 底部固定购买栏 -->
|
||||||
|
<div :gutter="4" class="bottom-bar">
|
||||||
|
<div class="btn-icon">
|
||||||
|
<Dshop color="#fa2c19" />
|
||||||
|
<span>店铺</span>
|
||||||
|
</div>
|
||||||
|
<div class="btn-icon"><Dongdong /> <span>店铺</span></div>
|
||||||
|
<div class="btn-icon"><Cart /> <span>店铺</span></div>
|
||||||
|
<div class="btn-group">
|
||||||
|
<nut-button type="primary"> 加入购物车 </nut-button>
|
||||||
|
<nut-button type="warning"> 立即购买 </nut-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { detailsData } from '../data';
|
import { detailsData } from '../data';
|
||||||
|
import { Dshop, Dongdong, Cart } from '@nutui/icons-vue';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const page = ref(1);
|
const page = ref(1);
|
||||||
|
|
||||||
@ -50,10 +66,52 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
color: #f2270c;
|
color: #f2270c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
em {
|
.bottom-bar {
|
||||||
font-size: 56px;
|
position: fixed;
|
||||||
font-style: normal;
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 100;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 -2px 8px rgb(0 0 0 / 10%);
|
||||||
|
|
||||||
|
.btn-icon {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex: 0 0 14%;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
.nut-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin-top: 12px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-group {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.nut-button {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0;
|
||||||
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.nut-card {
|
.nut-card {
|
||||||
padding: 15px;
|
padding: 15px 0;
|
||||||
border-bottom: 1px solid #e5e5e5;
|
border-bottom: 1px solid #e5e5e5;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -13,7 +13,7 @@ export default function ({ command, mode }: ConfigEnv): UserConfig {
|
|||||||
const env = loadEnv(mode, root);
|
const env = loadEnv(mode, root);
|
||||||
const viteEnv = wrapperEnv(env);
|
const viteEnv = wrapperEnv(env);
|
||||||
|
|
||||||
const devOptimizeDepsInclude: Array<string> = ['eruda', 'vant/es,@varlet/ui'];
|
const devOptimizeDepsInclude: Array<string> = ['eruda'];
|
||||||
if (!isProduction) {
|
if (!isProduction) {
|
||||||
const excludedDirs = ['utils', 'style', 'composables'];
|
const excludedDirs = ['utils', 'style', 'composables'];
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
@ -80,7 +80,8 @@ export default function ({ command, mode }: ConfigEnv): UserConfig {
|
|||||||
preprocessorOptions: {
|
preprocessorOptions: {
|
||||||
scss: {
|
scss: {
|
||||||
// 配置 nutui 全局 scss 变量
|
// 配置 nutui 全局 scss 变量
|
||||||
additionalData: `@import "@/styles/varible.scss";@import "@nutui/nutui/dist/styles/variables-jdt.scss";`
|
additionalData: `@use "@/styles/variable.scss" as *;@use "@nutui/nutui/dist/styles/variables.scss" as *;`,
|
||||||
|
quietDeps: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user