Skip to content

ConfigProvider 全局配置

为后代组件提供全局配置,主要用于国际化(i18n)语言切换。

名称分类说明类型
locale? 行为语言配置对象,用于覆盖组件的默认语言Language
extendsI18nMsg? 行为扩展的国际化消息,与现有消息合并TranslatePair
default? 插槽默认插槽,用于包裹需要全局配置的组件{ config: ConfigProviderProps }

用法

使用 <px-config-provider> 包裹你的应用(或子组件树),传入 locale 对象即可切换内部所有组件的语言。下面的示例展示了 Select("无数据"占位文案)、Popconfirm(翻译后的确认 / 取消按钮)以及 MessageBox —— 它们共享同一个语言选择器。

注意: PxMessageBox() 是命令式 API,它会渲染到一个独立的容器中,无法继承 ConfigProvider 提供的语言包。你需要从 locale 对象中手动传入翻译后的字符串(如 confirmButtonTextcancelButtonTexttitle)。

<template>
  <div class="demo-config-provider">
    <div style="margin-bottom: 16px">
      <label for="locale-picker" style="margin-right: 8px; font-weight: bold">
        Locale:
      </label>
      <select
        id="locale-picker"
        :value="localeKey"
        @change="localeKey = ($event.target as HTMLSelectElement).value"
        style="padding: 4px 8px; font-size: 14px"
      >
        <option v-for="opt in localeOptions" :key="opt.value" :value="opt.value">
          {{ opt.label }}
        </option>
      </select>
    </div>

    <px-config-provider :locale="currentLocale">
      <div style="display: flex; align-items: flex-start; gap: 24px; flex-wrap: wrap">
        <!-- Select: shows translated placeholder and "No data" -->
        <div>
          <p style="margin: 0 0 8px; font-weight: bold">Select</p>
          <px-select
            v-model="selectVal"
            :options="emptyOptions"
            filterable
            style="width: 200px"
          />
        </div>

        <!-- Popconfirm: shows translated Yes / No -->
        <div>
          <p style="margin: 0 0 8px; font-weight: bold">Popconfirm</p>
          <px-popconfirm title="Are you sure?">
            <px-button type="danger">Delete</px-button>
          </px-popconfirm>
        </div>

        <!-- MessageBox: explicit translated text -->
        <div>
          <p style="margin: 0 0 8px; font-weight: bold">MessageBox</p>
          <px-button type="primary" @click="openMessageBox">
            Open MessageBox
          </px-button>
        </div>
      </div>

      <!-- Translation Preview -->
      <table class="translation-table">
        <thead>
          <tr>
            <th class="translation-key">Key</th>
            <th>Translation</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="row in translationPreview" :key="row.key">
            <td class="translation-key">{{ row.key }}</td>
            <td>{{ row.value }}</td>
          </tr>
        </tbody>
      </table>
    </px-config-provider>
  </div>
</template>

<script setup lang="ts">
import { en, ja, ko, PxMessageBox, zhCn, zhTw } from 'sakana-element';
import { computed, ref } from 'vue';

const localeMap: Record<string, { label: string; locale: typeof en }> = {
  en: { label: 'English', locale: en },
  zhCn: { label: '简体中文', locale: zhCn },
  zhTw: { label: '繁體中文', locale: zhTw },
  ja: { label: '日本語', locale: ja },
  ko: { label: '한국어', locale: ko },
};

const localeOptions = Object.entries(localeMap).map(([value, { label }]) => ({
  value,
  label,
}));

const localeKey = ref('en');
const currentLocale = computed(() => localeMap[localeKey.value].locale);

const selectVal = ref('');
const emptyOptions = ref([]);

const translationPreview = computed(() => {
  const el = currentLocale.value.el;
  return [
    { key: 'select.placeholder', value: el.select.placeholder },
    { key: 'select.noData', value: el.select.noData },
    { key: 'popconfirm.confirmButtonText', value: el.popconfirm.confirmButtonText },
    { key: 'popconfirm.cancelButtonText', value: el.popconfirm.cancelButtonText },
    { key: 'messagebox.confirm', value: el.messagebox.confirm },
    { key: 'messagebox.cancel', value: el.messagebox.cancel },
  ];
});

async function openMessageBox() {
  const msgLocale = currentLocale.value.el.messagebox;
  try {
    await PxMessageBox({
      title: msgLocale.title,
      message: 'This demonstrates locale-aware button text.',
      showCancelButton: true,
      cancelButtonText: msgLocale.cancel,
      confirmButtonText: msgLocale.confirm,
    });
  } catch {
    // cancelled
  }
}
</script>

<style scoped>
.translation-table {
  margin-top: 16px;
  border-collapse: collapse;
  font-size: 14px;
  text-align: left;
}

.translation-table th {
  padding: 4px 12px 4px 0;
  border-bottom: 1px solid var(--px-border-color);
}

.translation-table td {
  padding: 4px 12px 4px 0;
}

.translation-key {
  color: var(--px-text-color-secondary);
  font-family: monospace;
}
</style>

扩展国际化消息

通过 extendsI18nMsg 属性可以覆盖或新增翻译键,无需替换整个语言包。该对象会与内置消息进行深度合并,你只需指定要修改的键即可。

对象结构需与内部消息格式一致 —— 顶层以语言名称为键:

typescript
const customMessages = {
  en: {
    popconfirm: {
      confirmButtonText: 'Sure!',
      cancelButtonText: 'Nope',
    },
  },
}

下方示例展示了两个并排的 Popconfirm:一个使用默认按钮文案,另一个通过 extendsI18nMsg 覆盖了文案。

<template>
  <div style="display: flex; align-items: flex-start; gap: 48px; flex-wrap: wrap">
    <!-- Default Popconfirm -->
    <div>
      <p style="margin: 0 0 8px; font-weight: bold">Default</p>
      <px-config-provider>
        <px-popconfirm title="Are you sure?">
          <px-button>Delete</px-button>
        </px-popconfirm>
      </px-config-provider>
    </div>

    <!-- Popconfirm with extendsI18nMsg -->
    <div>
      <p style="margin: 0 0 8px; font-weight: bold">With extendsI18nMsg</p>
      <px-config-provider :extendsI18nMsg="customMessages">
        <px-popconfirm title="Are you sure?">
          <px-button type="primary">Delete</px-button>
        </px-popconfirm>
      </px-config-provider>
    </div>
  </div>
</template>

<script setup lang="ts">
const customMessages = {
  en: {
    popconfirm: {
      confirmButtonText: 'Sure!',
      cancelButtonText: 'Nope',
    },
  },
};
</script>

内置语言包

Sakana Element 内置以下语言包:

语言包导入名称语言
Englishen英语(默认)
简体中文zhCn简体中文
繁體中文zhTw繁体中文
日本語ja日语
한국어ko韩语
js
import { en, zhCn, zhTw, ja, ko } from 'sakana-element'