chore: Rename the website directory to docs
This commit is contained in:
306
docs/src/guide/in-depth/access.md
Normal file
306
docs/src/guide/in-depth/access.md
Normal file
@@ -0,0 +1,306 @@
|
||||
---
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# 权限
|
||||
|
||||
框架内置了两种权限控制方式:
|
||||
|
||||
- 通过用户角色来判断菜单或者按钮是否可以访问
|
||||
- 通过接口来判断菜单或者按钮是否可以访问
|
||||
|
||||
## 前端访问控制
|
||||
|
||||
**实现原理**: 在前端固定写死路由的权限,指定路由有哪些权限可以查看。只初始化通用的路由,需要权限才能访问的路由没有被加入路由表内。在登陆后或者其他方式获取用户角色后,通过角色去遍历路由表,获取该角色可以访问的路由表,生成路由表,再通过 `router.addRoutes` 添加到路由实例,实现权限的过滤。
|
||||
|
||||
**缺点**: 权限相对不自由,如果后台改动角色,前台也需要跟着改动。适合角色较固定的系统
|
||||
|
||||
### 步骤
|
||||
|
||||
- 确保当前模式为前端访问控制模式
|
||||
|
||||
调整对应应用目录下的`preferences.ts`,确保`accessMode='frontend'`。
|
||||
|
||||
```ts
|
||||
import { defineOverridesPreferences } from '@vben/preferences';
|
||||
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
app: {
|
||||
// 默认值,可不填
|
||||
accessMode: 'frontend',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
- 配置路由权限
|
||||
|
||||
**如果不配置,默认可见**
|
||||
|
||||
```ts {3}
|
||||
{
|
||||
meta: {
|
||||
authority: ['super'],
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
- 确保接口返回的角色和路由表的权限匹配
|
||||
|
||||
可查看应用下的 `src/store/auth`,找到下面代码,
|
||||
|
||||
```ts
|
||||
// 设置登录用户信息,需要确保 userInfo.roles 是一个数组,且包含路由表中的权限
|
||||
// 例如:userInfo.roles=['super', 'admin']
|
||||
authStore.setUserInfo(userInfo);
|
||||
```
|
||||
|
||||
到这里,就已经配置完成,你需要确保登录后,接口返回的角色和路由表的权限匹配,否则无法访问。
|
||||
|
||||
### 菜单可见,但禁止访问
|
||||
|
||||
有时候,我们需要菜单可见,但是禁止访问,可以通过下面的方式实现,设置 `menuVisibleWithForbidden` 为 `true`,此时菜单可见,但是禁止访问,会跳转403页面。
|
||||
|
||||
```ts
|
||||
{
|
||||
meta: {
|
||||
menuVisibleWithForbidden: true,
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
## 后端访问控制
|
||||
|
||||
**实现原理**: 是通过接口动态生成路由表,且遵循一定的数据结构返回。前端根据需要处理该数据为可识别的结构,再通过 router.addRoutes 添加到路由实例,实现权限的动态生成。
|
||||
|
||||
**缺点**: 后端需要提供符合规范的数据结构,前端需要处理数据结构,适合权限较为复杂的系统。
|
||||
|
||||
### 步骤
|
||||
|
||||
- 确保当前模式为后端访问控制模式
|
||||
|
||||
调整对应应用目录下的`preferences.ts`,确保`accessMode='backend'`。
|
||||
|
||||
```ts
|
||||
import { defineOverridesPreferences } from '@vben/preferences';
|
||||
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
app: {
|
||||
accessMode: 'backend',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
- 确保接口返回的菜单数据结构正确
|
||||
|
||||
可查看应用下的 `src/router/access.ts`,找到下面代码,
|
||||
|
||||
```ts {5}
|
||||
async function generateAccess(options: GenerateMenuAndRoutesOptions) {
|
||||
return await generateAccessible(preferences.app.accessMode, {
|
||||
fetchMenuListAsync: async () => {
|
||||
// 这个接口为后端返回的菜单数据
|
||||
return await getAllMenus();
|
||||
},
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
- 接口返回菜单数据,可看注释说明
|
||||
|
||||
::: details 接口返回菜单数据示例
|
||||
|
||||
```ts
|
||||
const dashboardMenus = [
|
||||
{
|
||||
// 这里固定写死 BasicLayout,不可更改
|
||||
component: 'BasicLayout',
|
||||
meta: {
|
||||
order: -1,
|
||||
title: 'page.dashboard.title',
|
||||
},
|
||||
name: 'Dashboard',
|
||||
path: '/',
|
||||
redirect: '/analytics',
|
||||
children: [
|
||||
{
|
||||
name: 'Analytics',
|
||||
path: '/analytics',
|
||||
// 这里为页面的路径,需要去掉 views/ 和 .vue
|
||||
component: '/dashboard/analytics/index',
|
||||
meta: {
|
||||
affixTab: true,
|
||||
title: 'page.dashboard.analytics',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Workspace',
|
||||
path: '/workspace',
|
||||
component: '/dashboard/workspace/index',
|
||||
meta: {
|
||||
title: 'page.dashboard.workspace',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
到这里,就已经配置完成,你需要确保登录后,接口返回的菜单格式正确,否则无法访问。
|
||||
|
||||
## 按钮细粒度控制
|
||||
|
||||
在某些情况下,我们需要对按钮进行细粒度的控制,我们可以借助接口或者角色来控制按钮的显示。
|
||||
|
||||
### 权限码
|
||||
|
||||
权限码为接口返回的权限码,通过权限码来判断按钮是否显示,逻辑在`src/store/auth`下:
|
||||
|
||||
```ts
|
||||
const [fetchUserInfoResult, accessCodes] = await Promise.all([
|
||||
fetchUserInfo(),
|
||||
getAccessCodes(),
|
||||
]);
|
||||
|
||||
userInfo = fetchUserInfoResult;
|
||||
authStore.setUserInfo(userInfo);
|
||||
accessStore.setAccessCodes(accessCodes);
|
||||
```
|
||||
|
||||
找到 `getAccessCodes` 对应的接口,可根据业务逻辑进行调整。
|
||||
|
||||
权限吗返回的数据结构为字符串数组,例如:`['AC_100100', 'AC_100110', 'AC_100120', 'AC_100010']`
|
||||
|
||||
有了权限码,就可以使用 `@vben/access` 提供的`AccessControl`组件及API来进行按钮的显示与隐藏。
|
||||
|
||||
#### 组件方式
|
||||
|
||||
```vue
|
||||
<script lang="ts" setup>
|
||||
import { AccessControl, useAccess } from '@vben/access';
|
||||
|
||||
const { accessMode, hasAccessByCodes } = useAccess();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 需要指明 type="code" -->
|
||||
<AccessControl :codes="['AC_100100']" type="code">
|
||||
<Button> Super 账号可见 ["AC_1000001"] </Button>
|
||||
</AccessControl>
|
||||
<AccessControl :codes="['AC_100030']" type="code">
|
||||
<Button> Admin 账号可见 ["AC_100010"] </Button>
|
||||
</AccessControl>
|
||||
<AccessControl :codes="['AC_1000001']" type="code">
|
||||
<Button> User 账号可见 ["AC_1000001"] </Button>
|
||||
</AccessControl>
|
||||
<AccessControl :codes="['AC_100100', 'AC_100010']" type="code">
|
||||
<Button> Super & Admin 账号可见 ["AC_100100","AC_1000001"] </Button>
|
||||
</AccessControl>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### API方式
|
||||
|
||||
```vue
|
||||
<script lang="ts" setup>
|
||||
import { AccessControl, useAccess } from '@vben/access';
|
||||
|
||||
const { hasAccessByCodes } = useAccess();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Button v-if="hasAccessByCodes(['AC_100100'])">
|
||||
Super 账号可见 ["AC_1000001"]
|
||||
</Button>
|
||||
<Button v-if="hasAccessByCodes(['AC_100030'])">
|
||||
Admin 账号可见 ["AC_100010"]
|
||||
</Button>
|
||||
<Button v-if="hasAccessByCodes(['AC_1000001'])">
|
||||
User 账号可见 ["AC_1000001"]
|
||||
</Button>
|
||||
<Button v-if="hasAccessByCodes(['AC_100100', 'AC_1000001'])">
|
||||
Super & Admin 账号可见 ["AC_100100","AC_1000001"]
|
||||
</Button>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 指令方式
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<Button class="mr-4" v-access:code="['AC_100100']">
|
||||
Super 账号可见 ["AC_1000001"]
|
||||
</Button>
|
||||
<Button class="mr-4" v-access:code="['AC_100030']">
|
||||
Admin 账号可见 ["AC_100010"]
|
||||
</Button>
|
||||
<Button class="mr-4" v-access:code="['AC_1000001']">
|
||||
User 账号可见 ["AC_1000001"]
|
||||
</Button>
|
||||
<Button class="mr-4" v-access:code="['AC_100100', 'AC_1000001']">
|
||||
Super & Admin 账号可见 ["AC_100100","AC_1000001"]
|
||||
</Button>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 角色
|
||||
|
||||
角色判断方式不需要接口返回的权限码,直接通过角色来判断按钮是否显示。
|
||||
|
||||
#### 组件方式
|
||||
|
||||
```vue
|
||||
<script lang="ts" setup>
|
||||
import { AccessControl } from '@vben/access';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AccessControl :codes="['super']">
|
||||
<Button> Super 角色可见 </Button>
|
||||
</AccessControl>
|
||||
<AccessControl :codes="['admin']">
|
||||
<Button> Admin 角色可见 </Button>
|
||||
</AccessControl>
|
||||
<AccessControl :codes="['user']">
|
||||
<Button> User 角色可见 </Button>
|
||||
</AccessControl>
|
||||
<AccessControl :codes="['super', 'admin']">
|
||||
<Button> Super & Admin 角色可见 </Button>
|
||||
</AccessControl>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### API方式
|
||||
|
||||
```vue
|
||||
<script lang="ts" setup>
|
||||
import { useAccess } from '@vben/access';
|
||||
|
||||
const { hasAccessByRoles } = useAccess();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Button v-if="hasAccessByRoles(['super'])"> Super 账号可见 </Button>
|
||||
<Button v-if="hasAccessByRoles(['admin'])"> Admin 账号可见 </Button>
|
||||
<Button v-if="hasAccessByRoles(['user'])"> User 账号可见 </Button>
|
||||
<Button v-if="hasAccessByRoles(['super', 'admin'])">
|
||||
Super & Admin 账号可见
|
||||
</Button>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 指令方式
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<Button class="mr-4" v-access:role="['super']"> Super 角色可见 </Button>
|
||||
<Button class="mr-4" v-access:role="['admin']"> Admin 角色可见 </Button>
|
||||
<Button class="mr-4" v-access:role="['user']"> User 角色可见 </Button>
|
||||
<Button class="mr-4" v-access:role="['super', 'admin']">
|
||||
Super & Admin 角色可见
|
||||
</Button>
|
||||
</template>
|
||||
```
|
48
docs/src/guide/in-depth/check-updates.md
Normal file
48
docs/src/guide/in-depth/check-updates.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# 检查更新
|
||||
|
||||
## 介绍
|
||||
|
||||
当网站有更新时,您可能需要检查更新。框架提供了这一功能,通过定时检查更新,您可以在应用的 preferences.ts 文件中配置 `checkUpdatesInterval`和 `enableCheckUpdates` 字段,以开启和设置检查更新的时间间隔(单位:分钟)。
|
||||
|
||||
```ts
|
||||
import { defineOverridesPreferences } from '@vben/preferences';
|
||||
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
app: {
|
||||
// 是否开启检查更新
|
||||
enableCheckUpdates: true,
|
||||
// 检查更新的时间间隔,单位为分钟
|
||||
checkUpdatesInterval: 1,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 效果
|
||||
|
||||
检测到更新时,会弹出提示框,询问用户是否刷新页面:
|
||||
|
||||

|
||||
|
||||
## 替换为其他检查更新方式
|
||||
|
||||
如果需要通过其他方式检查更新,例如通过接口来更灵活地控制更新逻辑(如强制刷新、显示更新内容等),你可以通过修改 `@vben/layouts` 下面的 `src/widgets/check-updates/check-updates.vue`文件来实现。
|
||||
|
||||
```ts
|
||||
// 这里可以替换为你的检查更新逻辑
|
||||
async function getVersionTag() {
|
||||
try {
|
||||
const response = await fetch('/', {
|
||||
cache: 'no-cache',
|
||||
method: 'HEAD',
|
||||
});
|
||||
|
||||
return (
|
||||
response.headers.get('etag') || response.headers.get('last-modified')
|
||||
);
|
||||
} catch {
|
||||
console.error('Failed to fetch version tag');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
84
docs/src/guide/in-depth/features.md
Normal file
84
docs/src/guide/in-depth/features.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# 常用功能
|
||||
|
||||
一些常用的功能合集。
|
||||
|
||||
## 登录认证过期
|
||||
|
||||
当接口返回`401`状态码时,框架会认为登录认证过期,登录超时会跳转到登录页或者打开登录弹窗。在应用目录下的`preferences.ts`可以配置:
|
||||
|
||||
### 跳转登录页面
|
||||
|
||||
登录超时会跳转到登录页
|
||||
|
||||
```ts
|
||||
import { defineOverridesPreferences } from '@vben/preferences';
|
||||
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
app: {
|
||||
loginExpiredMode: 'page',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### 打开登录弹窗
|
||||
|
||||
登录超时会打开登录弹窗
|
||||
|
||||

|
||||
|
||||
配置:
|
||||
|
||||
```ts
|
||||
import { defineOverridesPreferences } from '@vben/preferences';
|
||||
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
app: {
|
||||
loginExpiredMode: 'model',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 动态标题
|
||||
|
||||
- 默认值:`true`
|
||||
|
||||
开启后网页标题随着路由的`title`而变化。在应用目录下的`preferences.ts`,开启或者关闭即可。
|
||||
|
||||
```ts
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
app: {
|
||||
dynamicTitle: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 页面水印
|
||||
|
||||
- 默认值:`false`
|
||||
|
||||
开启后网页会显示水印,在应用目录下的`preferences.ts`,开启或者关闭即可。
|
||||
|
||||
```ts
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
app: {
|
||||
watermark: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
如果你想更新水印的内容,可以这么做,参数可以参考 [watermark-js-plus](https://zhensherlock.github.io/watermark-js-plus/):
|
||||
|
||||
```ts
|
||||
import { useWatermark } from '@vben/hooks';
|
||||
|
||||
const { destroyWatermark, updateWatermark } = useWatermark();
|
||||
|
||||
await updateWatermark({
|
||||
// 水印内容
|
||||
content: 'hello my watermark',
|
||||
});
|
||||
```
|
1
docs/src/guide/in-depth/layout.md
Normal file
1
docs/src/guide/in-depth/layout.md
Normal file
@@ -0,0 +1 @@
|
||||
# 布局
|
37
docs/src/guide/in-depth/loading.md
Normal file
37
docs/src/guide/in-depth/loading.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 全局loading
|
||||
|
||||
全局 loading 指的是页面刷新时出现的加载效果,通常是一个旋转的图标:
|
||||
|
||||

|
||||
|
||||
## 原理
|
||||
|
||||
由 `vite-plugin-inject-app-loading` 插件实现,插件会在每个页面的注入一个全局的 loading html。
|
||||
|
||||
## 关闭
|
||||
|
||||
如果你不需要全局 loading,可以在 `.env` 文件中关闭:
|
||||
|
||||
```bash
|
||||
VITE_INJECT_APP_LOADING=false
|
||||
```
|
||||
|
||||
## 自定义
|
||||
|
||||
如果你想要自定义全局 loading,可以在应用目录下,与`index.html`同级,创建一个`loading.html`文件,插件会自动读取并注入。这个html可以自行定义样式和动画。
|
||||
|
||||
::: tip
|
||||
|
||||
- 你可以使用跟`index.html`一样的语法,比如`VITE_APP_TITLE`变量,来获取应用的标题。
|
||||
- 必须保证有一个`id="__app-loading__"`的元素。
|
||||
- 必须保证有一个`style[data-app-loading="inject-css"]`的元素。
|
||||
|
||||
```html{1,4}
|
||||
<style data-app-loading="inject-css">
|
||||
/* ... */
|
||||
</style>
|
||||
<div id="__app-loading__">
|
||||
<!-- ... -->
|
||||
<div class="title"><%= VITE_APP_TITLE %></div>
|
||||
</div>
|
||||
```
|
223
docs/src/guide/in-depth/locale.md
Normal file
223
docs/src/guide/in-depth/locale.md
Normal file
@@ -0,0 +1,223 @@
|
||||
# 国际化
|
||||
|
||||
项目已经集成了 [Vue i18n](https://kazupon.github.io/vue-i18n/),并且已经配置好了中文和英文的语言包。
|
||||
|
||||
## IDE 插件
|
||||
|
||||
如果你使用的 vscode 开发工具,则推荐安装 [i18n Ally](https://marketplace.visualstudio.com/items?itemName=Lokalise.i18n-ally) 这个插件。它可以帮助你更方便的管理国际化的文案,安装了该插件后,你的代码内可以实时看到对应的语言内容:
|
||||
|
||||

|
||||
|
||||
## 配置默认语言
|
||||
|
||||
只需要覆盖默认的偏好设置即可,在对应的应用内,找到 `src/preferences.ts` 文件,修改 `locale` 的值即可:
|
||||
|
||||
```ts {3}
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
app: {
|
||||
locale: 'en-US',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 动态切换语言
|
||||
|
||||
切换语言有两部分组成:
|
||||
|
||||
- 更新偏好设置
|
||||
- 加载对应的语言包
|
||||
|
||||
```ts
|
||||
import type { SupportedLanguagesType } from '@vben/locales';
|
||||
import { loadLocaleMessages } from '@vben/locales';
|
||||
import { updatePreferences } from '@vben/preferences';
|
||||
|
||||
async function updateLocale(value: string) {
|
||||
// 1. 更新偏好设置
|
||||
const locale = value as SupportedLanguagesType;
|
||||
updatePreferences({
|
||||
app: {
|
||||
locale,
|
||||
},
|
||||
});
|
||||
// 2. 加载对应的语言包
|
||||
await loadLocaleMessages(locale);
|
||||
}
|
||||
|
||||
updateLocale('en-US');
|
||||
```
|
||||
|
||||
## 新增翻译文本
|
||||
|
||||
::: warning 注意
|
||||
|
||||
- 请不要将业务翻译文本放到 `@vben/locales` 内,这样可以更好的管理业务和通用的翻译文本。
|
||||
- 有多个语言包的情况下,新增翻译文本时,需要在所有语言包内新增对应的文本。
|
||||
|
||||
:::
|
||||
|
||||
新增翻译文本,只需要在对应的应用内,找到 `src/locales/langs/`,新增对应的文本即可,例:
|
||||
|
||||
**src/locales/langs/zh-CN.ts**
|
||||
|
||||
````ts
|
||||
```json
|
||||
{
|
||||
"about": {
|
||||
"desc": "Vben Admin 是一个现代的管理模版。"
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
**src/locales/langs/en-US.ts**
|
||||
|
||||
````ts
|
||||
```json
|
||||
{
|
||||
"about": {
|
||||
"desc": "Vben Admin is a modern management template."
|
||||
}
|
||||
}
|
||||
````
|
||||
|
||||
## 使用翻译文本
|
||||
|
||||
通过 `@vben/locales`,你可以很方便的使用翻译文本:
|
||||
|
||||
### 在代码中使用
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { $t } from '@vben/locales';
|
||||
|
||||
const items = computed(() => [{ title: $t('about.desc') }]);
|
||||
</script>
|
||||
<template>
|
||||
<div>{{ $t('about.desc') }}</div>
|
||||
<template v-for="item in items.value">
|
||||
<div>{{ item.title }}</div>
|
||||
</template>
|
||||
</template>
|
||||
```
|
||||
|
||||
## 新增语言包
|
||||
|
||||
如果你需要新增语言包,需要按照以下步骤进行:
|
||||
|
||||
- 在 `packages/locales/langs` 目录下新增对应的语言包文件,例:`zh-TW.json`,并翻译对应的文本。
|
||||
- 在对应的应用内,找到 `src/locales/langs` 文件,新增对应的语言包 `zh-TW.json`
|
||||
- 在 `packages/constants/src/core.ts`内,新增对应的语言:
|
||||
|
||||
```ts
|
||||
export interface LanguageOption {
|
||||
label: string;
|
||||
value: 'en-US' | 'zh-CN'; // [!code --]
|
||||
value: 'en-US' | 'zh-CN' | 'zh-TW'; // [!code ++]
|
||||
}
|
||||
export const SUPPORT_LANGUAGES: LanguageOption[] = [
|
||||
{
|
||||
label: '简体中文',
|
||||
value: 'zh-CN',
|
||||
},
|
||||
{
|
||||
label: 'English',
|
||||
value: 'en-US',
|
||||
},
|
||||
{
|
||||
label: '繁体中文', // [!code ++]
|
||||
value: 'zh-TW', // [!code ++]
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
- 在 `packages/locales/typing.ts`内,新增 Typescript 类型:
|
||||
|
||||
```ts
|
||||
export type SupportedLanguagesType = 'en-US' | 'zh-CN'; // [!code --]
|
||||
export type SupportedLanguagesType = 'en-US' | 'zh-CN' | 'zh-TW'; // [!code ++]
|
||||
```
|
||||
|
||||
到这里,你就可以在项目内使用新增的语言包了。
|
||||
|
||||
## 界面切换语言功能
|
||||
|
||||
如果你想关闭界面上的语言切换显示按钮,在对应的应用内,找到 `src/preferences.ts` 文件,修改 `locale` 的值即可:
|
||||
|
||||
```ts {3}
|
||||
export const overridesPreferences = defineOverridesPreferences({
|
||||
widget: {
|
||||
languageToggle: false,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 远程加载语言包
|
||||
|
||||
::: tip 提示
|
||||
|
||||
通过项目自带的`request`工具进行接口请求时,默认请求头里会带上 [Accept-Language](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Accept-Language) ,服务端可根据请求头进行动态数据国际化处理。
|
||||
|
||||
:::
|
||||
|
||||
每个应用都有一个独立的语言包,它可以覆盖通用的语言配置,你可以通过远程加载的方式来获取对应的语言包,只需要在对应的应用内,找到 `src/locales/index.ts` 文件,修改 `loadMessages` 方法即可:
|
||||
|
||||
```ts {3-4}
|
||||
async function loadMessages(lang: SupportedLanguagesType) {
|
||||
const [appLocaleMessages] = await Promise.all([
|
||||
// 这里修改为远程接口加载数据即可
|
||||
localesMap[lang](),
|
||||
loadThirdPartyMessage(lang),
|
||||
]);
|
||||
return appLocaleMessages.default;
|
||||
}
|
||||
```
|
||||
|
||||
## 第三方语言包
|
||||
|
||||
不同应用内使用的第三方组件库或者插件国际化方式可能不一致,所以需要差别处理。 如果你需要引入第三方的语言包,你可以在对应的应用内,找到 `src/locales/index.ts` 文件,修改 `loadThirdPartyMessage` 方法即可:
|
||||
|
||||
```ts
|
||||
/**
|
||||
* 加载dayjs的语言包
|
||||
* @param lang
|
||||
*/
|
||||
async function loadDayjsLocale(lang: SupportedLanguagesType) {
|
||||
let locale;
|
||||
switch (lang) {
|
||||
case 'zh-CN': {
|
||||
locale = await import('dayjs/locale/zh-cn');
|
||||
break;
|
||||
}
|
||||
case 'en-US': {
|
||||
locale = await import('dayjs/locale/en');
|
||||
break;
|
||||
}
|
||||
// 默认使用英语
|
||||
default: {
|
||||
locale = await import('dayjs/locale/en');
|
||||
}
|
||||
}
|
||||
dayjs.locale(locale);
|
||||
}
|
||||
```
|
||||
|
||||
## 移除国际化
|
||||
|
||||
首先,不是很建议移除国际化,因为国际化是一个很好的开发习惯,但是如果你真的需要移除国际化,你可以直接使用中文文案,然后保留项目自带的语言包即可,整体开发体验不会影响。移除国际化的步骤如下:
|
||||
|
||||
- 隐藏界面上的语言切换按钮,见:[界面切换语言功能](#界面切换语言功能)
|
||||
- 修改默认语言,见:[配置默认语言](#配置默认语言)
|
||||
- 关闭 `vue-i18n`的警告提示,在`src/locales/index.ts`文件内,修改`missingWarn`为`false`即可:
|
||||
|
||||
```ts
|
||||
async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
|
||||
await coreSetup(app, {
|
||||
defaultLocale: preferences.app.locale,
|
||||
loadMessages,
|
||||
missingWarn: !import.meta.env.PROD, // [!code --]
|
||||
missingWarn: false, // [!code ++]
|
||||
...options,
|
||||
});
|
||||
}
|
||||
```
|
1241
docs/src/guide/in-depth/theme.md
Normal file
1241
docs/src/guide/in-depth/theme.md
Normal file
File diff suppressed because it is too large
Load Diff
16
docs/src/guide/in-depth/ui-framework.md
Normal file
16
docs/src/guide/in-depth/ui-framework.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# 组件库切换
|
||||
|
||||
`Vue Admin` 支持你自由选择组件库,目前演示站点的默认组件库是 `Ant Design Vue`,与旧版本保持一致。同时框架还内置了 `Element Plus` 版本和 `Naive UI` 版本,你可以根据自己的喜好选择。
|
||||
|
||||
## 新增组件库应用
|
||||
|
||||
如果你想用其他别的组件库,你只需要按一下步骤进行操作:
|
||||
|
||||
1. 在`apps`内创建一个新的文件夹,例如`apps/web-xxx`。
|
||||
2. 更改`apps/web-xxx/package.json`的`name`字段为`web-xxx`。
|
||||
3. 移除其他组件库依赖及代码,并用你的组件库进行替换相应逻辑,需要改动的地方不多。
|
||||
4. 调整`locales`内的语言文件。
|
||||
5. 调整 `app.vue` 内的组件。
|
||||
6. 自行适配组件库的主题,与 `Vben Admin` 契合。
|
||||
7. 调整 `.env` 内的应用名
|
||||
8. 在大仓根目录增加 `dev:xxx` 脚本
|
Reference in New Issue
Block a user