refactor: i18n

* refactor: i18n
This commit is contained in:
啝裳
2022-03-11 21:28:43 +08:00
committed by GitHub
parent 8b3f642cf2
commit 494ce8f41b
31 changed files with 608 additions and 479 deletions

View File

@@ -14,7 +14,7 @@ import screenfull from "../components/screenfull/index.vue";
import globalization from "/@/assets/svg/globalization.svg?component";
const route = useRoute();
const { locale } = useI18n();
const { locale, t } = useI18n();
const instance =
getCurrentInstance().appContext.config.globalProperties.$storage;
const {
@@ -101,14 +101,14 @@ function translationEn() {
<IconifyIconOffline
icon="logout-circle-r-line"
style="margin: 5px"
/>{{ $t("buttons.hsLoginOut") }}</el-dropdown-item
/>{{ t("buttons.hsLoginOut") }}</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-icon
class="el-icon-setting"
:title="$t('buttons.hssystemSet')"
:title="t('buttons.hssystemSet')"
@click="onPanel"
>
<IconifyIconOffline icon="setting" />

View File

@@ -1,5 +1,8 @@
<script setup lang="ts">
import { useFullscreen } from "@vueuse/core";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const { isFullscreen, toggle } = useFullscreen();
</script>
@@ -7,9 +10,7 @@ const { isFullscreen, toggle } = useFullscreen();
<div class="screen-full" @click="toggle">
<FontIcon
:title="
isFullscreen
? $t('buttons.hsexitfullscreen')
: $t('buttons.hsfullscreen')
isFullscreen ? t('buttons.hsexitfullscreen') : t('buttons.hsfullscreen')
"
:icon="isFullscreen ? 'team-iconexit-fullscreen' : 'team-iconfullscreen'"
/>

View File

@@ -14,7 +14,7 @@
<component
:is="useRenderIcon(item.meta?.icon ?? 'bookmark-2-line')"
></component>
<span class="result-item-title">{{ $t(item.meta?.title) }}</span>
<span class="result-item-title">{{ t(item.meta?.title) }}</span>
<enterOutlined />
</div>
</template>
@@ -23,10 +23,13 @@
<script lang="ts" setup>
import { computed } from "vue";
import { useI18n } from "vue-i18n";
import { useEpThemeStoreHook } from "/@/store/modules/epTheme";
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
import enterOutlined from "/@/assets/svg/enter_outlined.svg?component";
const { t } = useI18n();
interface optionsItem {
path: string;
meta?: {

View File

@@ -14,7 +14,7 @@ import { usePermissionStoreHook } from "/@/store/modules/permission";
import globalization from "/@/assets/svg/globalization.svg?component";
const route = useRoute();
const { locale } = useI18n();
const { locale, t } = useI18n();
const routers = useRouter().options.routes;
const menuRef = templateRef<ElRef | null>("menu", null);
const instance =
@@ -133,14 +133,14 @@ function translationEn() {
icon="logout-circle-r-line"
style="margin: 5px"
/>
{{ $t("buttons.hsLoginOut") }}</el-dropdown-item
{{ t("buttons.hsLoginOut") }}</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-icon
class="el-icon-setting"
:title="$t('buttons.hssystemSet')"
:title="t('buttons.hssystemSet')"
@click="onPanel"
>
<IconifyIconOffline icon="setting" />

View File

@@ -17,7 +17,7 @@ import globalization from "/@/assets/svg/globalization.svg?component";
import { ref, watch, nextTick, onMounted, getCurrentInstance } from "vue";
const route = useRoute();
const { locale } = useI18n();
const { locale, t } = useI18n();
const routers = useRouter().options.routes;
const menuRef = templateRef<ElRef | null>("menu", null);
const instance =
@@ -178,14 +178,14 @@ function translationEn() {
icon="logout-circle-r-line"
style="margin: 5px"
/>
{{ $t("buttons.hsLoginOut") }}</el-dropdown-item
{{ t("buttons.hsLoginOut") }}</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-icon
class="el-icon-setting"
:title="$t('buttons.hssystemSet')"
:title="t('buttons.hssystemSet')"
@click="onPanel"
>
<IconifyIconOffline icon="setting" />

View File

@@ -19,12 +19,12 @@ import closeLeft from "/@/assets/svg/close_left.svg?component";
import closeOther from "/@/assets/svg/close_other.svg?component";
import closeRight from "/@/assets/svg/close_right.svg?component";
import { useI18n } from "vue-i18n";
import { emitter } from "/@/utils/mitt";
import { $t as t } from "/@/plugins/i18n";
import { transformI18n } from "/@/plugins/i18n";
import { storageLocal } from "/@/utils/storage";
import { useRoute, useRouter } from "vue-router";
import { isEqual, isEmpty } from "lodash-unified";
import { transformI18n, $t } from "/@/plugins/i18n";
import { RouteConfigs, tagsViewsType } from "../../types";
import { useSettingStoreHook } from "/@/store/modules/settings";
import { handleAliveRoute, delAliveRoutes } from "/@/router/utils";
@@ -33,6 +33,7 @@ import { usePermissionStoreHook } from "/@/store/modules/permission";
import { toggleClass, removeClass, hasClass } from "/@/utils/operate";
import { templateRef, useResizeObserver, useDebounceFn } from "@vueuse/core";
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const translateX = ref<number>(0);
@@ -193,42 +194,42 @@ const handleScroll = (offset: number): void => {
const tagsViews = reactive<Array<tagsViewsType>>([
{
icon: refresh,
text: t("buttons.hsreload"),
text: $t("buttons.hsreload"),
divided: false,
disabled: false,
show: true
},
{
icon: close,
text: t("buttons.hscloseCurrentTab"),
text: $t("buttons.hscloseCurrentTab"),
divided: false,
disabled: multiTags.value.length > 1 ? false : true,
show: true
},
{
icon: closeLeft,
text: t("buttons.hscloseLeftTabs"),
text: $t("buttons.hscloseLeftTabs"),
divided: true,
disabled: multiTags.value.length > 1 ? false : true,
show: true
},
{
icon: closeRight,
text: t("buttons.hscloseRightTabs"),
text: $t("buttons.hscloseRightTabs"),
divided: false,
disabled: multiTags.value.length > 1 ? false : true,
show: true
},
{
icon: closeOther,
text: t("buttons.hscloseOtherTabs"),
text: $t("buttons.hscloseOtherTabs"),
divided: true,
disabled: multiTags.value.length > 2 ? false : true,
show: true
},
{
icon: closeAll,
text: t("buttons.hscloseAllTabs"),
text: $t("buttons.hscloseAllTabs"),
divided: false,
disabled: multiTags.value.length > 1 ? false : true,
show: true
@@ -701,7 +702,7 @@ const getContextMenuStyle = computed((): CSSProperties => {
>
<li v-if="item.show" @click="selectTag(key, item)">
<component :is="item.icon" :key="key" />
{{ $t(item.text) }}
{{ t(item.text) }}
</li>
</div>
</ul>
@@ -710,7 +711,7 @@ const getContextMenuStyle = computed((): CSSProperties => {
<ul class="right-button">
<li>
<el-icon
:title="$t('buttons.hsrefreshRoute')"
:title="t('buttons.hsrefreshRoute')"
class="el-icon-refresh-right rotate"
@click="onFresh"
>
@@ -740,7 +741,7 @@ const getContextMenuStyle = computed((): CSSProperties => {
:key="key"
style="margin-right: 6px"
/>
{{ $t(item.text) }}
{{ t(item.text) }}
</el-dropdown-item>
</el-dropdown-menu>
</template>

78
src/plugins/i18n.ts Normal file
View File

@@ -0,0 +1,78 @@
// 多组件库的国际化和本地项目国际化兼容
import { App, WritableComputedRef } from "vue";
import { storageLocal } from "/@/utils/storage";
import { type I18n, createI18n } from "vue-i18n";
// vxe-table组件国际化
import zhVxeTable from "vxe-table/lib/locale/lang/zh-CN";
import enVxeTable from "vxe-table/lib/locale/lang/en-US";
// element-plus国际化
import enLocale from "element-plus/lib/locale/lang/en";
import zhLocale from "element-plus/lib/locale/lang/zh-cn";
function siphonI18n(prefix = "zh-CN") {
return Object.fromEntries(
Object.entries(import.meta.globEager("../../locales/*.y(a)?ml")).map(
([key, value]) => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i)[1];
return [matched, value.default];
}
)
)[prefix];
}
export const localesConfigs = {
zh: {
...siphonI18n("zh-CN"),
...zhVxeTable,
...zhLocale
},
en: {
...siphonI18n("en"),
...enVxeTable,
...enLocale
}
};
/**
* 国际化转换工具函数
* @param message message
* @param isI18n 如果true,获取对应的消息,否则返回本身
* @returns message
*/
export function transformI18n(
message: string | unknown | object = "",
isI18n: boolean | unknown = false
) {
if (!message) {
return "";
}
// 处理存储动态路由的title,格式 {zh:"",en:""}
if (typeof message === "object") {
debugger;
const locale: string | WritableComputedRef<string> | any =
i18n.global.locale;
return message[locale];
}
if (isI18n) {
return i18n.global.t.call(i18n.global.locale, message);
} else {
return message;
}
}
// 此函数只是配合i18n Ally插件来进行国际化智能提示并无实际意义只对提示起作用如果不需要国际化可删除
export const $t = (key: string) => key;
export const i18n: I18n = createI18n({
legacy: false,
locale: storageLocal.getItem("responsive-locale")?.locale ?? "zh",
fallbackLocale: "en",
messages: localesConfigs
});
export function usI18n(app: App) {
app.use(i18n);
}

View File

@@ -1,25 +0,0 @@
import { siphonI18n } from "./index";
// vxe-table组件国际化
import zhVxeTable from "vxe-table/lib/locale/lang/zh-CN";
import enVxeTable from "vxe-table/lib/locale/lang/en-US";
// element-plus国际化
import enLocale from "element-plus/lib/locale/lang/en";
import zhLocale from "element-plus/lib/locale/lang/zh-cn";
// 项目内自定义国际化
const zhModules = import.meta.globEager("./zh-CN/**/*.ts");
const enModules = import.meta.globEager("./en/**/*.ts");
export const localesConfigs = {
zh: {
...siphonI18n(zhModules, "zh-CN"),
...zhVxeTable,
...zhLocale
},
en: {
...siphonI18n(enModules, "en"),
...enVxeTable,
...enLocale
}
};

View File

@@ -1,21 +0,0 @@
export default {
hsLoginOut: "LoginOut",
hsfullscreen: "FullScreen",
hsexitfullscreen: "ExitFullscreen",
hsrefreshRoute: "RefreshRoute",
hslogin: "Login",
hsadd: "Add",
hsmark: "Mark/Cancel",
hssave: "Save",
hssearch: "Search",
hsexpendAll: "Expand All",
hscollapseAll: "Collapse All",
hssystemSet: "Open ProjectConfig",
hsdelete: "Delete",
hsreload: "Reload",
hscloseCurrentTab: "Close CurrentTab",
hscloseLeftTabs: "Close LeftTabs",
hscloseRightTabs: "Close RightTabs",
hscloseOtherTabs: "Close OtherTabs",
hscloseAllTabs: "Close AllTabs"
};

View File

@@ -1,55 +0,0 @@
export default {
hshome: "Home",
hslogin: "Login",
hssysManagement: "System Manage",
hsBaseinfo: "Base Info",
hsDict: "Dict Manage",
hseditor: "Editor",
hserror: "Error Page",
hsfourZeroFour: "404",
hsfourZeroOne: "403",
hsFive: "500",
hscomponents: "Components",
hsvideo: "Video Components",
hsmap: "Map Components",
hsdraggable: "Draggable Components",
hssplitPane: "Split Pane",
hsbutton: "Button Components",
hscropping: "Picture Cropping",
hscountTo: "Digital Animation",
hsselector: "Selector Components",
hsflowChart: "Flow Chart",
hsseamless: "Seamless Scroll",
hscontextmenu: "Context Menu",
hsmenus: "MultiLevel Menu",
hsmenu1: "Menu1",
"hsmenu1-1": "Menu1-1",
"hsmenu1-2": "Menu1-2",
"hsmenu1-2-1": "Menu1-2-1",
"hsmenu1-2-2": "Menu1-2-2",
"hsmenu1-3": "Menu1-3",
hsmenu2: "Menu2",
permission: "Permission Manage",
permissionPage: "Page Permission",
permissionButton: "Button Permission",
hstabs: "Tabs Operate",
hsguide: "Guide",
hsAble: "Able",
hsMenuTree: "Menu Tree",
hsWatermark: "Water Mark",
hsPrint: "Print",
hsExternalPage: "External Page",
hsPureDocument: "Pure Doc(Embedded)",
externalLink: "Pure Doc(External)",
hsEpDocument: "Element Plus Doc(Embedded)",
hsAbout: "About",
hsResult: "Result Page",
hsSuccess: "Success Page",
hsFail: "Fail Page",
hsIconSelect: "Icon Select",
hsTimeline: "Time Line",
hsLineTree: "LineTree",
hsAntTabs: "Imitate Antdv Tabs",
hsAntAnchor: "Imitate Antdv Anchor",
hsAntTreeSelect: "Imitate Antdv TreeSelector"
};

View File

@@ -1,77 +0,0 @@
// 多组件库的国际化和本地项目国际化兼容
import { App } from "vue";
import { set } from "lodash-unified";
import { createI18n } from "vue-i18n";
import { localesConfigs } from "./config";
import { storageLocal } from "/@/utils/storage";
/**
* 国际化转换工具函数
* @param message message
* @param isI18n 如果true,获取对应的消息,否则返回本身
* @returns message
*/
export function transformI18n(
message: string | unknown | object = "",
isI18n: boolean | unknown = false
) {
if (!message) {
return "";
}
// 处理存储动态路由的title,格式 {zh:"",en:""}
if (typeof message === "object") {
return message[i18n.global?.locale];
}
if (isI18n) {
//@ts-ignore
return i18n.global.tc.call(i18n.global, message);
} else {
return message;
}
}
/**
* 从模块中抽取国际化
* @param langs 存放国际化模块
* @param prefix 语言 默认 zh-CN
* @returns obj 格式:{模块名.**}
*/
export function siphonI18n(
langs: Record<string, Record<string, any>>,
prefix = "zh-CN"
) {
const langsObj: Recordable = {};
Object.keys(langs).forEach((key: string) => {
let fileName = key.replace(`./${prefix}/`, "").replace(/^\.\//, "");
fileName = fileName.substring(0, fileName.lastIndexOf("."));
const keyList = fileName.split("/");
const moduleName = keyList.shift();
const objKey = keyList.join(".");
const langFileModule = langs[key].default;
if (moduleName) {
if (objKey) {
set(langsObj, moduleName, langsObj[moduleName] || {});
set(langsObj[moduleName], objKey, langFileModule);
} else {
set(langsObj, moduleName, langFileModule || {});
}
}
});
return langsObj;
}
// 此函数只是配合i18n Ally插件来进行国际化智能提示并无实际意义只对提示起作用如果不需要国际化可删除
export const $t = (key: string) => key;
export const i18n = createI18n({
locale: storageLocal.getItem("responsive-locale")?.locale ?? "zh",
fallbackLocale: "en",
messages: localesConfigs
});
export function usI18n(app: App) {
app.use(i18n);
}

View File

@@ -1,21 +0,0 @@
export default {
hsLoginOut: "退出系统",
hsfullscreen: "全屏",
hsexitfullscreen: "退出全屏",
hsrefreshRoute: "刷新路由",
hslogin: "登陆",
hsadd: "新增",
hsmark: "标记/取消",
hssave: "保存",
hssearch: "搜索",
hsexpendAll: "全部展开",
hscollapseAll: "全部折叠",
hssystemSet: "打开项目配置",
hsdelete: "删除",
hsreload: "重新加载",
hscloseCurrentTab: "关闭当前标签页",
hscloseLeftTabs: "关闭左侧标签页",
hscloseRightTabs: "关闭右侧标签页",
hscloseOtherTabs: "关闭其他标签页",
hscloseAllTabs: "关闭全部标签页"
};

View File

@@ -1,55 +0,0 @@
export default {
hshome: "首页",
hslogin: "登陆",
hssysManagement: "系统管理",
hsBaseinfo: "基础信息",
hsDict: "字典管理",
hseditor: "编辑器",
hserror: "错误页面",
hsfourZeroFour: "404",
hsfourZeroOne: "403",
hsFive: "500",
hscomponents: "组件",
hsvideo: "视频组件",
hsmap: "地图组件",
hsdraggable: "拖拽组件",
hssplitPane: "切割面板",
hsbutton: "按钮组件",
hscropping: "图片裁剪",
hscountTo: "数字动画",
hsselector: "选择器组件",
hsflowChart: "流程图",
hsseamless: "无缝滚动",
hscontextmenu: "右键菜单",
hsmenus: "多级菜单",
hsmenu1: "菜单1",
"hsmenu1-1": "菜单1-1",
"hsmenu1-2": "菜单1-2",
"hsmenu1-2-1": "菜单1-2-1",
"hsmenu1-2-2": "菜单1-2-2",
"hsmenu1-3": "菜单1-3",
hsmenu2: "菜单2",
permission: "权限管理",
permissionPage: "页面权限",
permissionButton: "按钮权限",
hstabs: "标签页操作",
hsguide: "引导页",
hsAble: "功能",
hsMenuTree: "菜单树结构",
hsWatermark: "水印",
hsPrint: "打印",
hsExternalPage: "外部页面",
hsPureDocument: "平台文档(内嵌)",
externalLink: "平台文档(外链)",
hsEpDocument: "Element Plus文档(内嵌)",
hsAbout: "关于",
hsResult: "结果页面",
hsSuccess: "成功页面",
hsFail: "失败页面",
hsIconSelect: "图标选择器",
hsTimeline: "时间线",
hsLineTree: "树形连接线",
hsAntTabs: "仿antdv标签页",
hsAntAnchor: "仿antdv锚点",
hsAntTreeSelect: "仿antdv树型选择器"
};

View File

@@ -1,6 +1,6 @@
import "xe-utils";
import { App } from "vue";
import { i18n } from "../i18n/index";
import { i18n } from "/@/plugins/i18n";
import "font-awesome/css/font-awesome.min.css";
import {
// 核心

View File

@@ -1,8 +1,10 @@
<script setup lang="ts">
import { computed } from "vue";
import { useI18n } from "vue-i18n";
import ElTreeLine from "/@/components/ReTreeLine";
import { extractPathList, deleteChildren } from "/@/utils/tree";
import { usePermissionStoreHook } from "/@/store/modules/permission";
const { t } = useI18n();
let menusData = computed(() => {
return deleteChildren(usePermissionStoreHook().menusTree);
@@ -43,7 +45,7 @@ let dataProps = {
><template v-slot:default="{ node }">
<el-tree-line :node="node" :showLabelLine="true">
<template v-slot:node-label>
<span class="text-sm">{{ $t(node.data.meta.title) }}</span>
<span class="text-sm">{{ t(node.data.meta.title) }}</span>
</template>
</el-tree-line>
</template>
@@ -75,7 +77,7 @@ let dataProps = {
:indent="30"
>
<template v-slot:node-label>
<span class="text-sm">{{ $t(node.data.meta.title) }}</span>
<span class="text-sm">{{ t(node.data.meta.title) }}</span>
</template>
</el-tree-line>
</template>

View File

@@ -5,6 +5,7 @@ export default {
</script>
<script setup lang="ts">
import { useI18n } from "vue-i18n";
import { ref, computed } from "vue";
import type { ElTreeV2 } from "element-plus";
import { transformI18n } from "/@/plugins/i18n";
@@ -12,6 +13,7 @@ import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
import { extractPathList, deleteChildren } from "/@/utils/tree";
import { usePermissionStoreHook } from "/@/store/modules/permission";
import type { TreeNode } from "element-plus/es/components/tree-v2/src/types";
const { t } = useI18n();
interface treeNode extends TreeNode {
meta: {
@@ -76,7 +78,7 @@ const filterMethod = (query: string, node: treeNode) => {
:default-expanded-keys="expandedKeys"
>
<template #default="{ data }">
<span>{{ $t(data.meta.title) }}</span>
<span>{{ t(data.meta.title) }}</span>
</template>
</el-tree-v2>
</el-card>

View File

@@ -1,18 +1,21 @@
<template>
<div>
<p>{{ $t("menus.hsmenu1") }}</p>
<p style="text-indent: 2em">{{ $t("menus.hsmenu1-1") }}</p>
<p>{{ t("menus.hsmenu1") }}</p>
<p style="text-indent: 2em">{{ t("menus.hsmenu1-1") }}</p>
<el-input v-model="input" />
</div>
</template>
<script lang="ts">
import { useI18n } from "vue-i18n";
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Menu1-1",
setup() {
const { t } = useI18n();
return {
input: ref("")
input: ref(""),
t
};
}
});

View File

@@ -1,19 +1,22 @@
<template>
<div>
<p>{{ $t("menus.hsmenu1") }}</p>
<p style="text-indent: 2em">{{ $t("menus.hsmenu1-2") }}</p>
<p style="text-indent: 4em">{{ $t("menus.hsmenu1-2-1") }}</p>
<p>{{ t("menus.hsmenu1") }}</p>
<p style="text-indent: 2em">{{ t("menus.hsmenu1-2") }}</p>
<p style="text-indent: 4em">{{ t("menus.hsmenu1-2-1") }}</p>
<el-input v-model="input" />
</div>
</template>
<script lang="ts">
import { useI18n } from "vue-i18n";
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Menu1-2-1",
setup() {
const { t } = useI18n();
return {
input: ref("")
input: ref(""),
t
};
}
});

View File

@@ -1,19 +1,22 @@
<template>
<div>
<p>{{ $t("menus.hsmenu1") }}</p>
<p style="text-indent: 2em">{{ $t("menus.hsmenu1-2") }}</p>
<p style="text-indent: 4em">{{ $t("menus.hsmenu1-2-2") }}</p>
<p>{{ t("menus.hsmenu1") }}</p>
<p style="text-indent: 2em">{{ t("menus.hsmenu1-2") }}</p>
<p style="text-indent: 4em">{{ t("menus.hsmenu1-2-2") }}</p>
<el-input v-model="input" />
</div>
</template>
<script lang="ts">
import { useI18n } from "vue-i18n";
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Menu1-2-2",
setup() {
const { t } = useI18n();
return {
input: ref("")
input: ref(""),
t
};
}
});

View File

@@ -1,18 +1,21 @@
<template>
<div>
<p>{{ $t("menus.hsmenu1") }}</p>
<p style="text-indent: 2em">{{ $t("menus.hsmenu1-3") }}</p>
<p>{{ t("menus.hsmenu1") }}</p>
<p style="text-indent: 2em">{{ t("menus.hsmenu1-3") }}</p>
<el-input v-model="input" />
</div>
</template>
<script lang="ts">
import { useI18n } from "vue-i18n";
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Menu1-3",
setup() {
const { t } = useI18n();
return {
input: ref("")
input: ref(""),
t
};
}
});

View File

@@ -1,17 +1,20 @@
<template>
<div>
<p>{{ $t("menus.hsmenu2") }}</p>
<p>{{ t("menus.hsmenu2") }}</p>
<el-input v-model="input" />
</div>
</template>
<script lang="ts">
import { useI18n } from "vue-i18n";
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "Menu2",
setup() {
const { t } = useI18n();
return {
input: ref("")
input: ref(""),
t
};
}
});

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import { reactive } from "vue";
import { useI18n } from "vue-i18n";
import { VxeTableEvents } from "vxe-table";
import { templateRef } from "@vueuse/core";
@@ -19,6 +20,8 @@ const emit = defineEmits<{
(e: "handleClose"): void;
}>();
const { t } = useI18n();
const xTable = templateRef<any>("xTable", null);
const configData = reactive({
@@ -140,7 +143,7 @@ const checkboxChangeEvent: VxeTableEvents.CheckboxChange = ({ records }) => {
<span class="select-count"
>已选中{{ configData.selectRecords.length }}</span
>
<vxe-button size="small">{{ $t("buttons.hsdelete") }}</vxe-button>
<vxe-button size="small">{{ t("buttons.hsdelete") }}</vxe-button>
</span>
</template>
</vxe-pager>

View File

@@ -7,6 +7,7 @@ export default {
<script setup lang="ts">
import XEUtils from "xe-utils";
import Config from "./config.vue";
import { useI18n } from "vue-i18n";
import { cloneDeep } from "lodash-unified";
import { templateRef } from "@vueuse/core";
import { reactive, ref, unref, nextTick } from "vue";
@@ -22,6 +23,8 @@ type onEditNRow = {
model: string;
};
const { t } = useI18n();
const dictData = reactive({
submitLoading: false,
showEdit: false,
@@ -209,7 +212,7 @@ function handleClose() {
<template #buttons>
<vxe-input
v-model="dictData.filterName"
:placeholder="$t('buttons.hssearch')"
:placeholder="t('buttons.hssearch')"
@keyup="searchEvent"
></vxe-input>
</template>
@@ -218,19 +221,19 @@ function handleClose() {
icon="fa fa-plus-square-o"
status="primary"
@click="onAdd"
>{{ $t("buttons.hsadd") }}</vxe-button
>{{ t("buttons.hsadd") }}</vxe-button
>
<vxe-button
icon="fa fa-folder-open-o"
status="primary"
@click="$refs.xTree.setAllTreeExpand(true)"
>{{ $t("buttons.hsexpendAll") }}</vxe-button
>{{ t("buttons.hsexpendAll") }}</vxe-button
>
<vxe-button
icon="fa fa-folder-o"
status="primary"
@click="$refs.xTree.clearTreeExpand()"
>{{ $t("buttons.hscollapseAll") }}</vxe-button
>{{ t("buttons.hscollapseAll") }}</vxe-button
>
</template>
</vxe-toolbar>