目 录CONTENT

文章目录

primevue UI组件库的使用

Jinty
2024-07-28 / 0 评论 / 0 点赞 / 92 阅读 / 9195 字

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>

效果

参考

0

评论区