PRIMEVUE4 UI组件库国际化配置
前言
简单记录primevue ui组件库的基本使用,以及primevue组件与本地项目国际化配置的支持。
使用vite构建的vue3 + typescript + pinia前端项目,使用的是pnpm包管理器
primevue安装
# 安装primevue(vue支持)、primeicons(图标)、primeflex(flex布局样式)
pnpm i primevue primeicons primeflex
pnpm i unplugin-vue-components -D
pnpm i @primevue/auto-import-resolver -D
# 安装 社区国际化 vue国际化配置
pnpm i primelocations vue-i18n
自动导入配置:Auto Import - PrimeVue
primevue.config.js:primevue配置
import PrimeVue from "primevue/config";
import { usePrimeVue } from "primevue/config";
// 使用Aura主题
import Aura from "@primevue/themes/aura";
// PrimeVue本身仅支持英语,这里我们使用PrimeVue社区语言来进行国际化配置
import zhCN from "primelocale/zh-CN.json";
import en from "primelocale/en.json";
// 获取当前语言,默认中文
const locale = sessionStorage.getItem("language") || "zh-CN";
// 定义支持的语言包
export const primeVueLocalesMessages: any = {
"zh-CN": zhCN["zh-CN"],
zh: zhCN["zh-CN"],
en: en["en"],
};
// 获取语言包
export const getLocale = (lang: string) => {
return primeVueLocalesMessages[lang] ?? (zhCN["zh-CN"] as any);
};
// 定义PrimeVue预设配置
export const primeVuePresetConfig = {
// 主题
theme: {
preset: Aura,
},
// 语言
locale: getLocale(locale),
};
// 注册PrimeVue方法
export const setupPrimeVue = (app: any) => {
app.use(PrimeVue, primeVuePresetConfig);
};
i18n.config.js:I18n配置
import { createI18n } from "vue-i18n";
// primevue 国际化支持
import { primeVueLocalesMessages } from "./primevue.config";
// 本地项目国际化支持
import zhCN from "./locales/zh-CN.json";
import en from "./locales/en.json";
// 创建VueI18n实例并配置
const i18n = createI18n({
legacy: false, // 设置为 false,启用 composition API 模式
locale: sessionStorage.getItem("language") || navigator.language || "zh-CN", // 设置默认语言
fallbackLocale: "zh-CN", // 设置后备语言
messages: {
primevue: primeVueLocalesMessages,
"zh-CN": {
...zhCN,
},
en: {
...en,
},
}, // 设置翻译消息
});
export default i18n;
本地国际化:
zh-CN.json
{
"selectColumns": "选择列",
"export": "导出",
"upload": "上传"
}
en.json
{
"selectColumns": "Select Columns",
"export": "Export",
"upload": "Upload"
}
main.ts:入口
import "./assets/main.css";
import { createApp } from "vue";
import { createPinia } from "pinia";
import { setupPrimeVue } from "./primevue.config";
import i18n from "./i18n.config";
import "hover.css/css/hover-min.css";
import "@/assets/main.css";
import "@/assets/el.css";
import App from "./App.vue";
import router from "./router";
async function init() {
const app = createApp(App);
app.use(createPinia());
app.use(router);
app.use(i18n);
setupPrimeVue(app);
// // 路由准备就绪后挂载APP实例
// await router.isReady();
app.mount("#app");
// // 挂载到 window
// window["$vue"] = app;
}
init();
lang.ts:lang状态管理
import { defineStore } from "pinia";
export const useLangStore = defineStore("lang", {
state: () => ({
language: sessionStorage.getItem("language") || "zh-CN",
}),
actions: {
changeLang(lang: string) {
this.language = lang;
sessionStorage.setItem("language", lang);
},
},
});
LangSwitcher.vue:语言切换组件
<script setup lang="ts" name="LangSwitcher">
import { useLangStore } from "@/store/lang";
import { useI18n } from "vue-i18n";
import { usePrimeVue } from "primevue/config";
import { getLocale } from "@/primevue.config";
const store = useLangStore();
const { locale } = useI18n();
const primevue = usePrimeVue();
const switchLanguage = (value: string) => {
if (store.language === value) return;
locale.value = value;
store.changeLang(value);
primevue.config.locale = getLocale(value);
};
const langOptions: Record<string, string> = {
"zh-CN": "简体中文",
en: "English",
};
</script>
<template>
<el-dropdown @command="switchLanguage" class="lang-warp">
<span class="el-dropdown-link">
{{ langOptions[store.language] }}
<el-icon>
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="zh-CN">{{
langOptions["zh-CN"]
}}</el-dropdown-item>
<el-dropdown-item command="en">{{
langOptions["en"]
}}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<style scoped lang="scss">
.lang-warp {
margin: 0 20px;
}
</style>
useI18nLabel.ts:自定义hooks
import { useI18n } from "vue-i18n";
// 定义hooks
export default function useI18nLabel() {
const { t } = useI18n();
return {
upload: computed(() => t("upload")),
export: computed(() => t("export")),
selectColumns: computed(() => t("selectColumns")),
};
}
PrimevueDemo.vue:测试页面
<!-- 组件描述 -->
<!-- 模板代码 -->
<template>
<FileUpload
ref="fileupload"
mode="basic"
name="demo[]"
url="/api/upload"
accept="image/*"
:maxFileSize="1000000"
@upload="onUpload"
/>
<Button
:label="i18nLabel.upload.value"
@click="upload"
severity="secondary"
/>
<DataTable :value="products" tableStyle="min-width: 50rem">
<template #header>
<div style="text-align: left">
<MultiSelect
:modelValue="selectedColumns"
:options="columns"
:placeholder="i18nLabel.selectColumns.value"
optionLabel="header"
@update:modelValue="onToggle"
display="chip"
/>
</div>
<div style="text-align: left">
<Button
icon="pi pi-external-link"
:label="i18nLabel.export.value"
@click="exportCSV($event)"
/>
</div>
</template>
<Column
v-for="(col, index) of selectedColumns"
:field="col.field"
:header="col.header"
:key="col.field + '_' + index"
></Column>
</DataTable>
</template>
<!-- ts脚本代码 -->
<script setup lang="ts" name="PrimevueDemo">
import data from "@/utils/data";
import { useI18n } from "vue-i18n";
import useI18nLabel from "@/hooks/useI18nLabel";
const i18nLabel = useI18nLabel();
const products = data.data;
const columns = [
{ field: "id", header: "编号" },
{ field: "name", header: "姓名" },
{ field: "country", header: "国家" },
{ field: "company", header: "公司" },
{ field: "date", header: "日期" },
{ field: "status", header: "状态" },
];
const selectedColumns = ref([
{ field: "id", header: "编号" },
// { field: "name", header: "姓名" },
// { field: "country", header: "国家" },
// { field: "company", header: "公司" },
// { field: "date", header: "日期" },
// { field: "status", header: "状态" },
]);
const onToggle = (value: any) => {
selectedColumns.value = value;
};
const upload = () => {
console.log("primevue.upload");
};
const onUpload = (event: any) => {
console.log(event);
};
const exportCSV = (event: any) => {
console.log(event);
};
</script>
<!-- 样式代码 -->
<style lang="scss" scoped></style>
评论区