修改结构
This commit is contained in:
parent
8bf6270833
commit
9055685cea
@ -13,7 +13,6 @@
|
||||
"antfu.goto-alias",
|
||||
"mikestead.dotenv",
|
||||
"redhat.vscode-yaml",
|
||||
"Lokalise.i18n-ally",
|
||||
"Vue.volar",
|
||||
"steoates.autoimport",
|
||||
"dbaeumer.vscode-eslint",
|
||||
|
4
.env
4
.env
@ -4,7 +4,7 @@
|
||||
VITE_API_BASE_URL = /api
|
||||
|
||||
# 标题
|
||||
VITE_APP_TITLE = tov
|
||||
VITE_APP_TITLE = 后台
|
||||
|
||||
|
||||
# markdown 渲染支持
|
||||
@ -12,7 +12,7 @@ VITE_APP_MARKDOWN = true
|
||||
|
||||
|
||||
# 开发时的开发面板
|
||||
VITE_APP_DEV_TOOLS = true
|
||||
VITE_APP_DEV_TOOLS = false
|
||||
|
||||
|
||||
# 生产时 mock 支持
|
||||
|
1373
README_EN.md
1373
README_EN.md
File diff suppressed because it is too large
Load Diff
42
mock/test.ts
42
mock/test.ts
@ -1,42 +0,0 @@
|
||||
import { MockMethod } from 'vite-plugin-mock'
|
||||
export default [
|
||||
{
|
||||
url: '/api/mock/get',
|
||||
method: 'get',
|
||||
response: () => {
|
||||
return {
|
||||
code: 0,
|
||||
data: {
|
||||
name: 'mock',
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
url: '/api/mock/post',
|
||||
method: 'post',
|
||||
timeout: 2000,
|
||||
response: {
|
||||
code: 0,
|
||||
data: {
|
||||
name: 'mock',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
url: '/api/mock/text',
|
||||
method: 'post',
|
||||
rawResponse: async (req, res) => {
|
||||
let reqbody = ''
|
||||
await new Promise((resolve) => {
|
||||
req.on('data', (chunk) => {
|
||||
reqbody += chunk
|
||||
})
|
||||
req.on('end', () => resolve(undefined))
|
||||
})
|
||||
res.setHeader('Content-Type', 'text/plain')
|
||||
res.statusCode = 200
|
||||
res.end(`hello, ${reqbody}`)
|
||||
},
|
||||
},
|
||||
] as MockMethod[]
|
30
package.json
30
package.json
@ -1,36 +1,17 @@
|
||||
{
|
||||
"name": "tov-template",
|
||||
"name": "后台",
|
||||
"version": "1.19.0",
|
||||
"description": "vite + vue3 + ts 开箱即用现代开发模板 | vite + vue3 + ts out-of-the-box modern development template",
|
||||
"description": "后台",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"test": "vitest",
|
||||
"build": "vite build",
|
||||
"prepare": "husky install",
|
||||
"dev:host": "vite --host",
|
||||
"dev:open": "vite --open",
|
||||
"preview": "vite preview",
|
||||
"coverage": "vitest --coverage",
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"typecheck": "npx vue-tsc --noEmit",
|
||||
"preview:host": "vite preview --host",
|
||||
"preview:open": "vite preview --open",
|
||||
"lint": "eslint --ext .ts,.js,.jsx,.vue .",
|
||||
"release": "plop --plopfile scripts/release.cjs",
|
||||
"auto:remove": "plop --plopfile scripts/remove.cjs",
|
||||
"auto:create": "plop --plopfile scripts/create.cjs",
|
||||
"build:debug": "cross-env NODE_ENV=debug vite build",
|
||||
"safe:init": "plop --plopfile scripts/safe-init.cjs",
|
||||
"deps:fresh": "plop --plopfile scripts/deps-fresh.cjs",
|
||||
"lint:fix": "eslint --fix --ext .ts,.js,.jsx,.vue,.cjs ."
|
||||
"build": "vite build"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.12.2"
|
||||
},
|
||||
"packageManager": "pnpm@8.15.8",
|
||||
"devDependencies": {
|
||||
"@intlify/unplugin-vue-i18n": "^3.0.1",
|
||||
"@types/ityped": "^1.0.3",
|
||||
"@types/node": "^20.12.7",
|
||||
"@typescript-eslint/parser": "7.8.0",
|
||||
@ -60,7 +41,6 @@
|
||||
"lightningcss": "^1.24.1",
|
||||
"lint-staged": "^15.2.2",
|
||||
"local-pkg": "^0.5.0",
|
||||
"markdown-it-prism": "^2.3.0",
|
||||
"mockjs": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"perfect-debounce": "^1.0.0",
|
||||
@ -84,16 +64,12 @@
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-env-types": "^0.1.4",
|
||||
"vite-plugin-legacy-swc": "^1.1.0",
|
||||
"vite-plugin-mock": "2.9.8",
|
||||
"vite-plugin-removelog": "^0.2.2",
|
||||
"vite-plugin-use-modules": "^1.4.8",
|
||||
"vite-plugin-vue-devtools": "^7.1.3",
|
||||
"vite-plugin-vue-meta-layouts": "^0.4.3",
|
||||
"vitest": "^1.5.3",
|
||||
"vue": "^3.4.26",
|
||||
"vue-dark-switch": "^1.0.6",
|
||||
"vue-echarts": "^6.7.1",
|
||||
"vue-i18n": "^9.13.1",
|
||||
"vue-request": "2.0.4",
|
||||
"vue-router": "^4.3.2",
|
||||
"vue-toastification": "2.0.0-rc.5"
|
||||
|
860
pnpm-lock.yaml
generated
860
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,3 @@
|
||||
import Prism from 'markdown-it-prism'
|
||||
import UnoCss from 'unocss/vite'
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import {
|
||||
@ -28,13 +27,9 @@ import Router from 'unplugin-vue-router/vite'
|
||||
import { AutoGenerateImports, vue3Presets } from 'vite-auto-import-resolvers'
|
||||
import Compression from 'vite-plugin-compression'
|
||||
import EnvTypes from 'vite-plugin-env-types'
|
||||
import { viteMockServe as Mock } from 'vite-plugin-mock'
|
||||
import Removelog from 'vite-plugin-removelog'
|
||||
import Modules from 'vite-plugin-use-modules'
|
||||
import VueDevTools from 'vite-plugin-vue-devtools'
|
||||
import Layouts from 'vite-plugin-vue-meta-layouts'
|
||||
|
||||
import I18N from '@intlify/unplugin-vue-i18n/vite'
|
||||
import Legacy from 'vite-plugin-legacy-swc'
|
||||
import Vue from '@vitejs/plugin-vue'
|
||||
import Jsx from '@vitejs/plugin-vue-jsx'
|
||||
@ -121,13 +116,7 @@ export default function () {
|
||||
Layouts({
|
||||
skipTopLevelRouteLayout: true,
|
||||
}),
|
||||
/**
|
||||
* mock 服务
|
||||
* https://github.com/vbenjs/vite-plugin-mock
|
||||
*/
|
||||
Mock({
|
||||
prodEnabled: env.VITE_APP_MOCK_IN_PRODUCTION,
|
||||
}),
|
||||
|
||||
/**
|
||||
* 组件自动按需引入
|
||||
* https://github.com/antfu/unplugin-vue-components
|
||||
@ -165,15 +154,7 @@ export default function () {
|
||||
],
|
||||
}),
|
||||
}),
|
||||
/**
|
||||
* i18n 国际化支持
|
||||
* https://www.npmjs.com/package/@intlify/unplugin-vue-i18n
|
||||
*/
|
||||
I18N({
|
||||
runtimeOnly: false,
|
||||
compositionOnly: true,
|
||||
include: ['locales/**'],
|
||||
}),
|
||||
|
||||
/**
|
||||
* jsx 和 tsx 支持
|
||||
* https://www.npmjs.com/package/@vitejs/plugin-vue-jsx
|
||||
@ -213,28 +194,6 @@ export default function () {
|
||||
plugins.push(VueDevTools())
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产环境下移除 console.log, console.warn, console.error
|
||||
* https://github.com/dishait/vite-plugin-removelog
|
||||
*/
|
||||
if (process.env.NODE_ENV !== 'debug') {
|
||||
plugins.push(Removelog())
|
||||
}
|
||||
|
||||
/**
|
||||
* markdown 渲染插件
|
||||
* https://github.com/mdit-vue/unplugin-vue-markdown
|
||||
*/
|
||||
if (env.VITE_APP_MARKDOWN) {
|
||||
plugins.push(
|
||||
Markdown({
|
||||
wrapperClasses: safelist,
|
||||
markdownItSetup(md) {
|
||||
md.use(Prism)
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* api 自动按需引入
|
||||
|
1
presets/types/vite.d.ts
vendored
1
presets/types/vite.d.ts
vendored
@ -3,7 +3,6 @@
|
||||
/// <reference types="unplugin-vue-router/client" />
|
||||
/// <reference types="vite-plugin-use-modules/client" />
|
||||
/// <reference types="vite-plugin-vue-meta-layouts/client" />
|
||||
/// <reference types="@intlify/vite-plugin-vue-i18n/client" />
|
||||
|
||||
declare module "*.vue" {
|
||||
import type { DefineComponent } from "vue";
|
||||
|
@ -1,6 +0,0 @@
|
||||
import { useRequest } from 'vue-request'
|
||||
|
||||
export const testRequest = () => {
|
||||
const { data, loading, error } = useRequest(() => http.post('/mock/post'))
|
||||
return { data, loading, error }
|
||||
}
|
@ -3,8 +3,7 @@
|
||||
* @param data
|
||||
*/
|
||||
export function login(data: any) {
|
||||
|
||||
|
||||
return http.post("/api/login", data)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -12,5 +11,15 @@ export function login(data: any) {
|
||||
* @param data
|
||||
*/
|
||||
export function register(data: any) {
|
||||
|
||||
return http.post("/api/register", data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param data
|
||||
*/
|
||||
export function userInfo(userId: any) {
|
||||
return http.get("/api/userInfo", {
|
||||
params: { userId: userId }
|
||||
})
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { vOnClickOutside } from '@vueuse/components'
|
||||
|
||||
const visiable = ref(false)
|
||||
function dropdownHandler() {
|
||||
visiable.value = false
|
||||
}
|
||||
|
||||
const { availableLocales, locale } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative">
|
||||
<div class="inline-flex items-center overflow-hidden rounded-md">
|
||||
<button
|
||||
class="h-full cursor-pointer border-0 bg-white p-2 text-gray-600 hover:bg-gray-200 hover:text-gray-700"
|
||||
dark="bg-transparent hover:bg-gray-500"
|
||||
:class="visiable ? 'bg-gray-200 bg-gray-500 dark:bg-gray-500' : ''"
|
||||
@click.stop="visiable = !visiable"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-4 w-4"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Transition name="fade" mode="out-in">
|
||||
<div
|
||||
v-if="visiable"
|
||||
v-on-click-outside.bubble="dropdownHandler"
|
||||
dark="bg-gray-500"
|
||||
class="absolute end-0 z-10 mt-2 w-56 rounded-md bg-white shadow-lg divide-y divide-gray-100"
|
||||
>
|
||||
<div class="p-2">
|
||||
<span
|
||||
v-for="availableLocale of availableLocales"
|
||||
:key="availableLocale"
|
||||
:class="
|
||||
locale === availableLocale
|
||||
? 'bg-gray-100 text-gray-800 dark:bg-gray-400'
|
||||
: ''
|
||||
"
|
||||
class="block cursor-pointer rounded-lg px-4 py-2 text-sm text-gray-500 hover:text-gray-900"
|
||||
dark="text-light-500 hover:text-light-900"
|
||||
@click="locale = availableLocale"
|
||||
>
|
||||
{{ availableLocale }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
@ -1,59 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { getRoutes } from '@/plugins/router'
|
||||
import { SwitchIcon } from 'vue-dark-switch'
|
||||
|
||||
const { te, t } = useI18n()
|
||||
|
||||
const routes = getRoutes()
|
||||
.filter((r) => !r.path.includes('notFound'))
|
||||
.map((r) => {
|
||||
let { path, name } = r
|
||||
if (path === safeResolve('/')) {
|
||||
return { path, name: 'home' }
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
name = path
|
||||
}
|
||||
|
||||
return { path, name: name.toString().slice(1).replaceAll('/', ' · ') }
|
||||
})
|
||||
|
||||
const $route = useRoute()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav
|
||||
aria-label="Site Nav"
|
||||
class="mx-auto h-80px max-w-3xl flex items-center justify-between p-4"
|
||||
>
|
||||
<div class="flex items-center justify-center space-x-5">
|
||||
<SwitchIcon unmount-persets />
|
||||
<a href="https://pc.dishait.cn/" target="_blank">
|
||||
<span
|
||||
style="
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
border-radius: 3px 0 0 3px;
|
||||
padding: 4px 4px 4px 4px;
|
||||
background: #00b894;
|
||||
"
|
||||
>帝莎编程</span
|
||||
>
|
||||
<span
|
||||
style="
|
||||
border-radius: 0 3px 3px 0;
|
||||
padding: 5px 10px 5px 2px;
|
||||
background: #00dc8220;
|
||||
font-size: 13px;
|
||||
color: rgba(37, 99, 235);
|
||||
"
|
||||
>
|
||||
https://pc.dishait.cn/
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<ul class="flex items-center gap-2 text-sm font-medium">
|
||||
<li v-for="r of routes" :key="r.path" class="hidden !block">
|
||||
<RouterLink
|
||||
@ -61,86 +10,23 @@ const $route = useRoute()
|
||||
:class="$route.path === r.path ? 'text-blue-700' : ''"
|
||||
:to="r.path"
|
||||
>
|
||||
{{ te(r.name) ? t(r.name) : r.name }}
|
||||
{{ r.name }}
|
||||
</RouterLink>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a
|
||||
class="inline-flex items-center gap-2 rounded-lg px-3 py-2"
|
||||
href="https://github.com/dishait/tov-template"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<mask id="lineMdGithubLoop0" width="24" height="24" x="0" y="0">
|
||||
<g fill="#fff">
|
||||
<ellipse cx="9.5" cy="9" rx="1.5" ry="1" />
|
||||
<ellipse cx="14.5" cy="9" rx="1.5" ry="1" />
|
||||
</g>
|
||||
</mask>
|
||||
<g
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path
|
||||
stroke-dasharray="30"
|
||||
stroke-dashoffset="30"
|
||||
d="M12 4C13.6683 4 14.6122 4.39991 15 4.5C15.5255 4.07463 16.9375 3 18.5 3C18.8438 4 18.7863 5.21921 18.5 6C19.25 7 19.5 8 19.5 9.5C19.5 11.6875 19.017 13.0822 18 14C16.983 14.9178 15.8887 15.3749 14.5 15.5C15.1506 16.038 15 17.3743 15 18C15 18.7256 15 21 15 21M12 4C10.3317 4 9.38784 4.39991 9 4.5C8.47455 4.07463 7.0625 3 5.5 3C5.15625 4 5.21371 5.21921 5.5 6C4.75 7 4.5 8 4.5 9.5C4.5 11.6875 4.98301 13.0822 6 14C7.01699 14.9178 8.1113 15.3749 9.5 15.5C8.84944 16.038 9 17.3743 9 18C9 18.7256 9 21 9 21"
|
||||
>
|
||||
<animate
|
||||
fill="freeze"
|
||||
attributeName="stroke-dashoffset"
|
||||
dur="0.6s"
|
||||
values="30;0"
|
||||
/>
|
||||
</path>
|
||||
<path stroke-dasharray="10" stroke-dashoffset="10" d="M9 19">
|
||||
<animate
|
||||
fill="freeze"
|
||||
attributeName="stroke-dashoffset"
|
||||
begin="0.7s"
|
||||
dur="0.2s"
|
||||
values="10;0"
|
||||
/>
|
||||
<animate
|
||||
attributeName="d"
|
||||
dur="3s"
|
||||
repeatCount="indefinite"
|
||||
values="M9 19c-1.406 0-2.844-.563-3.688-1.188C4.47 17.188 4.22 16.157 3 15.5;M9 19c-1.406 0-3-.5-4-.5-.532 0-1 0-2-.5;M9 19c-1.406 0-2.844-.563-3.688-1.188C4.47 17.188 4.22 16.157 3 15.5"
|
||||
/>
|
||||
</path>
|
||||
</g>
|
||||
<rect
|
||||
width="8"
|
||||
height="4"
|
||||
x="8"
|
||||
y="11"
|
||||
fill="currentColor"
|
||||
mask="url(#lineMdGithubLoop0)"
|
||||
>
|
||||
<animate
|
||||
attributeName="y"
|
||||
dur="10s"
|
||||
keyTimes="0;0.45;0.46;0.54;0.55;1"
|
||||
repeatCount="indefinite"
|
||||
values="11;11;7;7;11;11"
|
||||
/>
|
||||
</rect>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="hidden !block">
|
||||
<Dropdown />
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
const routes = [
|
||||
{
|
||||
"path": "/",
|
||||
"name": "首页"
|
||||
},
|
||||
|
||||
]
|
||||
console.log(routes)
|
||||
const $route = useRoute()
|
||||
</script>
|
||||
|
@ -1,6 +1,12 @@
|
||||
<!--基础折线图样式-->
|
||||
<!--https://v-charts.js.org/#/line-->
|
||||
<template>
|
||||
<div>
|
||||
<v-chart class="chart" :option="option" autoresize />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { use } from 'echarts/core'
|
||||
import { isDark } from 'vue-dark-switch'
|
||||
import { PieChart } from 'echarts/charts'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
import {
|
||||
@ -8,8 +14,7 @@ import {
|
||||
TooltipComponent,
|
||||
LegendComponent,
|
||||
} from 'echarts/components'
|
||||
import VChart, { THEME_KEY } from 'vue-echarts'
|
||||
import type { EChartsOption } from 'echarts'
|
||||
import VChart from 'vue-echarts'
|
||||
|
||||
use([
|
||||
CanvasRenderer,
|
||||
@ -18,15 +23,9 @@ use([
|
||||
TooltipComponent,
|
||||
LegendComponent,
|
||||
])
|
||||
|
||||
provide(
|
||||
THEME_KEY,
|
||||
computed(() => (isDark.value ? 'dark' : '')),
|
||||
)
|
||||
|
||||
const option = ref<EChartsOption>({
|
||||
const option = ref<any>({
|
||||
title: {
|
||||
text: 'Traffic Sources',
|
||||
text: 'Traffic Sources111',
|
||||
left: 'center',
|
||||
},
|
||||
tooltip: {
|
||||
@ -62,14 +61,6 @@ const option = ref<EChartsOption>({
|
||||
],
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- @vue-ignore -->
|
||||
<v-chart class="chart" :option="option" autoresize />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.chart {
|
||||
width: 100vw;
|
@ -1,12 +0,0 @@
|
||||
# About
|
||||
|
||||
> The page is markdown file
|
||||
|
||||
```js
|
||||
console.log("hello");
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
<!-- 支持嵌入组件 -->
|
||||
<Counter />
|
@ -1,32 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="grid grid-cols-3">
|
||||
<a href="https://github.com/dishait/tov-template" target="_blank">
|
||||
<img :src="safeResolve('/logo.png')" class="logo" alt="Vite logo" />
|
||||
</a>
|
||||
<a href="https://vitejs.dev" target="_blank">
|
||||
<img :src="safeResolve('/vite.svg')" class="logo" alt="Vite logo" />
|
||||
</a>
|
||||
<a href="https://vuejs.org/" target="_blank">
|
||||
<img :src="safeResolve('/vue.svg')" class="logo vue" alt="Vue logo" />
|
||||
</a>
|
||||
</div>
|
||||
<HelloWorld msg="Tov + Vite + Vue" />
|
||||
</div>
|
||||
<foundation-line></foundation-line>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.logo {
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
padding: 1.5rem;
|
||||
will-change: filter;
|
||||
transition: filter 300ms;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.logo.vue:hover {
|
||||
filter: drop-shadow(0 0 2em #42b883aa);
|
||||
}
|
||||
|
||||
</style>
|
||||
<script setup lang="ts">
|
||||
import FoundationLine from '~/components/view/foundation-line.vue'
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
@ -1,36 +0,0 @@
|
||||
import { defu } from 'defu'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
|
||||
const yamls = import.meta.glob('../../locales/*/**.y(a)?ml', {
|
||||
eager: true,
|
||||
})
|
||||
|
||||
const languages = Object.entries(yamls).map(([key, value]) => {
|
||||
const yaml = key.endsWith('.yaml')
|
||||
key = key.slice(14, yaml ? -5 : -4)
|
||||
// 如果有子模块,则分割
|
||||
if (key.includes('/')) {
|
||||
key = key.split('/')[0]
|
||||
}
|
||||
// @ts-ignore
|
||||
return { [key]: value.default }
|
||||
})
|
||||
|
||||
const messages = defu({}, ...languages)
|
||||
|
||||
// localStorage 中的 locale,第二个参数为默认值
|
||||
// https://vueuse.org/core/useStorage/#usestorage
|
||||
const storageLocale = useStorage('locale', '简体中文')
|
||||
|
||||
export const i18n = createI18n({
|
||||
messages,
|
||||
legacy: false,
|
||||
globalInjection: true,
|
||||
allowComposition: true,
|
||||
})
|
||||
|
||||
// 同步本地 localStorage 和 i18n
|
||||
// https://vueuse.org/shared/syncRef/#syncref
|
||||
syncRef(storageLocale, i18n.global.locale)
|
||||
|
||||
export default i18n
|
@ -1,7 +1,6 @@
|
||||
/**
|
||||
* 该模块主要给生产时的 mock 用,一般情况下你并不需要关注
|
||||
*/
|
||||
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'
|
||||
import { createFetchSever } from '../../presets/shared/mock'
|
||||
|
||||
const shouldCreateServer =
|
||||
@ -18,6 +17,5 @@ if (shouldCreateServer) {
|
||||
mockModules.push(...v.default)
|
||||
}
|
||||
})
|
||||
createProdMockServer(mockModules)
|
||||
createFetchSever(mockModules)
|
||||
}
|
||||
|
@ -1,15 +1,8 @@
|
||||
import { createGetRoutes, setupLayouts } from 'virtual:meta-layouts'
|
||||
import { setupLayouts } from 'virtual:meta-layouts'
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { routes as fileRoutes } from 'vue-router/auto-routes'
|
||||
|
||||
declare module 'vue-router' {
|
||||
// 在这里定义你的 meta 类型
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
interface RouteMeta {
|
||||
title?: string
|
||||
layout?: string
|
||||
}
|
||||
}
|
||||
declare module 'vue-router' {}
|
||||
|
||||
// 重定向 BASE_URL
|
||||
fileRoutes.flat(Infinity).forEach((route) => {
|
||||
@ -21,6 +14,20 @@ export const router = createRouter({
|
||||
routes: setupLayouts(fileRoutes),
|
||||
})
|
||||
|
||||
export const getRoutes = createGetRoutes(router)
|
||||
// 路由拦截
|
||||
router.beforeEach((to, from, next) => {
|
||||
// 在这里编写拦截逻辑
|
||||
// 例如,检查用户是否认证
|
||||
const isLogin = userStore().isLogin
|
||||
const authList=["/"]
|
||||
if (authList.includes(to.fullPath) && !isLogin) {
|
||||
toast.warning("未登录或者登录过期~")
|
||||
// 如果用户未认证,则跳转到登录页面
|
||||
next('/login');
|
||||
} else {
|
||||
// 如果用户已认证,或者不需要认证,则继续
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
export default router
|
||||
|
@ -1,14 +1,15 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export default defineStore('counter', {
|
||||
export default defineStore('userStore', {
|
||||
state() {
|
||||
return {
|
||||
count: 0,
|
||||
isLogin: false,
|
||||
token: "",
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
inc() {
|
||||
this.count++
|
||||
|
||||
},
|
||||
},
|
||||
persist: true,
|
@ -1,4 +1,3 @@
|
||||
@import './md.css';
|
||||
|
||||
|
||||
html.dark {
|
||||
|
@ -1,83 +0,0 @@
|
||||
@import 'prism-theme-vars/base.css';
|
||||
|
||||
.prose {
|
||||
--prism-font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica,
|
||||
Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
|
||||
}
|
||||
|
||||
.prose pre {
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
html:not(.dark) {
|
||||
--prism-foreground: #393a34;
|
||||
--prism-background: #f8f8f8;
|
||||
|
||||
--prism-comment: #868e96;
|
||||
--prism-namespace: #444444;
|
||||
--prism-string: #bc8671;
|
||||
--prism-punctuation: #80817d;
|
||||
--prism-literal: #36acaa;
|
||||
--prism-keyword: #d73a49;
|
||||
--prism-function: #0c4c7d;
|
||||
--prism-deleted: #9a050f;
|
||||
--prism-class: #2b91af;
|
||||
--prism-builtin: #800000;
|
||||
--prism-property: #ce9178;
|
||||
--prism-regex: #ad502b;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
--prism-foreground: #d4d4d4;
|
||||
--prism-background: #1e1e1e;
|
||||
|
||||
--prism-namespace: #aaaaaa;
|
||||
--prism-comment: #868e96;
|
||||
--prism-namespace: #444444;
|
||||
--prism-string: #ce9178;
|
||||
--prism-punctuation: #d4d4d4;
|
||||
--prism-literal: #36acaa;
|
||||
--prism-keyword: #0ca678;
|
||||
--prism-function: #dcdcaa;
|
||||
--prism-deleted: #9a050f;
|
||||
--prism-class: #4ec9b0;
|
||||
--prism-builtin: #d16969;
|
||||
--prism-property: #ce9178;
|
||||
--prism-regex: #ad502b;
|
||||
}
|
||||
ol {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.prose blockquote p:first-of-type::before {
|
||||
content: none;
|
||||
}
|
||||
|
||||
.prose pre {
|
||||
color: #495057;
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.prose-sm p {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.prose blockquote {
|
||||
margin: 0;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
html.dark .prose blockquote {
|
||||
color: white;
|
||||
}
|
||||
|
||||
html.dark .prose pre {
|
||||
color: #f8f9fa;
|
||||
background: #2a2f33;
|
||||
}
|
||||
|
||||
.token.comment {
|
||||
font-style: normal;
|
||||
font-size: 0.5rem;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
// Vitest Snapshot v1
|
||||
|
||||
exports[`suite name > snapshot 1`] = `
|
||||
{
|
||||
"foo": "bar",
|
||||
}
|
||||
`;
|
@ -1,16 +0,0 @@
|
||||
import { assert, describe, expect, it } from 'vitest'
|
||||
|
||||
describe('suite name', () => {
|
||||
it('foo', () => {
|
||||
expect(1 + 1).toEqual(2)
|
||||
expect(true).to.be.true
|
||||
})
|
||||
|
||||
it('bar', () => {
|
||||
assert.equal(Math.sqrt(4), 2)
|
||||
})
|
||||
|
||||
it('snapshot', () => {
|
||||
expect({ foo: 'bar' }).toMatchSnapshot()
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user