feat: i18n next

This commit is contained in:
chenjiahan 2020-07-05 08:26:58 +08:00
parent 3bc6495b04
commit 0a4c6676ba
16 changed files with 885 additions and 119 deletions

View File

@ -1,130 +1,129 @@
// import Vue from 'vue';
// import Locale from '../../src/locale';
import Locale from '../../src-next/locale';
import enUS from '../../src-next/locale/lang/en-US';
import { get } from '../../src/utils';
import { camelize } from '../../src/utils/format/string';
// import Lazyload from '../../src/lazyload';
// import { get } from '../../src/utils';
// import { camelize } from '../../src/utils/format/string';
// import enUS from '../../src/locale/lang/en-US';
const { app } = window;
// TODO
// Vue.use(Lazyload, {
// lazyComponent: true,
// });
// Locale.add({
// 'en-US': enUS,
// });
Locale.add({
'en-US': enUS,
});
// // flag for vant-weapp demos
// const isWeapp = location.search.indexOf('weapp=1') !== -1;
let demoUid = 0;
// let demoUid = 0;
// helper for demo locales
app.mixin({
computed: {
t() {
const { name } = this.$options;
const prefix = name ? camelize(name) + '.' : '';
const messages = Locale.messages();
// // helper for demo locales
// Vue.mixin({
// computed: {
// t() {
// const { name } = this.$options;
// const { lang = 'zh-CN' } = (this.$route && this.$route.meta) || {};
// const prefix = name ? camelize(name) + '.' : '';
// const messages = this.$vantMessages[lang];
return (path, ...args) => {
const message = get(messages, prefix + path) || get(messages, path);
return typeof message === 'function' ? message(...args) : message;
};
},
// return (path, ...args) => {
// const message = get(messages, prefix + path) || get(messages, path);
// return typeof message === 'function' ? message(...args) : message;
// };
// },
// flag for vant-weapp demos
isWeapp() {
return location.search.indexOf('weapp=1') !== -1;
},
},
// isWeapp() {
// return isWeapp;
// },
// },
beforeCreate() {
if (!this.$options.name) {
this.$options.name = `demo-${demoUid++}`;
}
// beforeCreate() {
// if (!this.$options.name) {
// this.$options.name = `demo-${demoUid++}`;
// }
const { i18n, name } = this.$options;
// const { i18n, name } = this.$options;
if (i18n && name) {
const locales = {};
const camelizedName = camelize(name);
// if (i18n && name) {
// const locales = {};
// const camelizedName = camelize(name);
Object.keys(i18n).forEach((key) => {
locales[key] = { [camelizedName]: i18n[key] };
});
// Object.keys(i18n).forEach((key) => {
// locales[key] = { [camelizedName]: i18n[key] };
// });
Locale.add(locales);
}
},
});
// Locale.add(locales);
// }
// },
// });
// switch lang after routing
if (window.vueRouter) {
window.vueRouter.afterEach((to) => {
const { lang } = to.meta || {};
// // switch lang after routing
// if (window.vueRouter) {
// window.vueRouter.afterEach((to) => {
// const { lang } = to.meta || {};
if (lang) {
Locale.use(lang);
}
});
}
// if (lang) {
// Locale.use(lang);
// }
// });
// }
// // add some basic locale messages
// Locale.add({
// 'zh-CN': {
// add: '增加',
// decrease: '减少',
// red: '红色',
// orange: '橙色',
// yellow: '黄色',
// purple: '紫色',
// tab: '标签',
// tag: '标签',
// desc: '描述信息',
// back: '返回',
// title: '标题',
// status: '状态',
// button: '按钮',
// option: '选项',
// search: '搜索',
// content: '内容',
// custom: '自定义',
// username: '用户名',
// password: '密码',
// disabled: '禁用状态',
// uneditable: '不可编辑',
// basicUsage: '基础用法',
// advancedUsage: '高级用法',
// loadingStatus: '加载状态',
// usernamePlaceholder: '请输入用户名',
// passwordPlaceholder: '请输入密码',
// },
// 'en-US': {
// add: 'Add',
// decrease: 'Decrease',
// red: 'Red',
// orange: 'Orange',
// yellow: 'Yellow',
// purple: 'Purple',
// tab: 'Tab',
// tag: 'Tag',
// desc: 'Description',
// back: 'Back',
// title: 'Title',
// status: 'Status',
// button: 'Button',
// option: 'Option',
// search: 'Search',
// content: 'Content',
// custom: 'Custom',
// username: 'Username',
// password: 'Password',
// loadingStatus: 'Loading',
// disabled: 'Disabled',
// uneditable: 'Uneditable',
// basicUsage: 'Basic Usage',
// advancedUsage: 'Advanced Usage',
// usernamePlaceholder: 'Username',
// passwordPlaceholder: 'Password',
// },
// });
// add some basic locale messages
Locale.add({
'zh-CN': {
add: '增加',
decrease: '减少',
red: '红色',
orange: '橙色',
yellow: '黄色',
purple: '紫色',
tab: '标签',
tag: '标签',
desc: '描述信息',
back: '返回',
title: '标题',
status: '状态',
button: '按钮',
option: '选项',
search: '搜索',
content: '内容',
custom: '自定义',
username: '用户名',
password: '密码',
disabled: '禁用状态',
uneditable: '不可编辑',
basicUsage: '基础用法',
advancedUsage: '高级用法',
loadingStatus: '加载状态',
usernamePlaceholder: '请输入用户名',
passwordPlaceholder: '请输入密码',
},
'en-US': {
add: 'Add',
decrease: 'Decrease',
red: 'Red',
orange: 'Orange',
yellow: 'Yellow',
purple: 'Purple',
tab: 'Tab',
tag: 'Tag',
desc: 'Description',
back: 'Back',
title: 'Title',
status: 'Status',
button: 'Button',
option: 'Option',
search: 'Search',
content: 'Content',
custom: 'Custom',
username: 'Username',
password: 'Password',
loadingStatus: 'Loading',
disabled: 'Disabled',
uneditable: 'Uneditable',
basicUsage: 'Basic Usage',
advancedUsage: 'Advanced Usage',
usernamePlaceholder: 'Username',
passwordPlaceholder: 'Password',
},
});

View File

@ -1,5 +1,5 @@
// Utils
import { addUnit, isDef } from '../../src/utils';
import { addUnit } from '../../src/utils';
import { createNamespace } from '../utils/create';
// Components

51
src-next/locale/README.md Normal file
View File

@ -0,0 +1,51 @@
# Internationalization
### Intro
The default language of Vant is Chinese. If you want to use other languages, you can follow the instructions below.
### Switch languages
Vant supports multiple languages with the Locale component, and the `Locale.use` method allows you to switch to different languages.
```js
import { Locale } from 'vant';
import enUS from 'vant/lib/locale/lang/en-US';
Locale.use('en-US', enUS);
```
### Modify default configs
Use `Locale.add` method to modify the default configs.
```js
import { Locale } from 'vant';
const messages = {
'en-US': {
vanPicker: {
confirm: 'Close',
},
},
};
Locale.add(messages);
```
### Config files
Current supported languages:
| Language | Filename |
| ------------------------ | -------- |
| Chinese | zh-CN |
| Traditional Chinese (HK) | zh-HK |
| Traditional Chinese (TW) | zh-TW |
| English | en-US |
| Turkish | tr-TR |
| Spanish (Spain) | es-ES |
| Japanese | ja-JP |
| Romanian | ro-RO |
> View all language configs [Here](https://github.com/youzan/vant/tree/dev/src/locale/lang).

View File

@ -0,0 +1,55 @@
# 国际化
### 介绍
Vant 默认采用中文作为语言,如果需要使用其他语言,可以参考下面的方案。
### 多语言切换
Vant 通过 Locale 组件实现多语言支持,使用 `Locale.use` 方法可以切换当前使用的语言。
```js
import { Locale } from 'vant';
import enUS from 'vant/lib/locale/lang/en-US';
Locale.use('en-US', enUS);
```
### 修改默认文案
通过 `Locale.add` 方法可以实现文案的修改和扩展,示例如下:
```js
import { Locale } from 'vant';
const messages = {
'zh-CN': {
vanPicker: {
confirm: '关闭', // 将'确认'修改为'关闭'
},
},
};
Locale.add(messages);
```
### 配置文件
目前支持的语言:
| 语言 | 文件名 |
| -------------- | ------ |
| 简体中文 | zh-CN |
| 繁體中文(港) | zh-HK |
| 繁體中文(台) | zh-TW |
| 英语 | en-US |
| 土耳其语 | tr-TR |
| 西班牙语 | es-ES |
| 日语 | ja-JP |
| 罗马尼亚语 | ro-RO |
> 在 [这里](https://github.com/youzan/vant/tree/dev/src/locale/lang) 查看所有的 i18n 配置文件。
### Sku 组件
语言包中默认不包含 Sku 业务组件的语言配置,因此如果有 Sku 组件的国际化需求,请自行配置国际化文案。

25
src-next/locale/index.ts Normal file
View File

@ -0,0 +1,25 @@
import { ref } from 'vue';
import { deepAssign } from '../../src/utils/deep-assign';
import defaultMessages from './lang/zh-CN';
type Messages = Record<string, Record<string, any>>;
const lang = ref('zh-CN');
const messages = ref<Messages>({
'zh-CN': defaultMessages,
});
export default {
messages() {
return messages.value[lang.value];
},
use(newLang: string, newMessages?: object) {
lang.value = newLang;
this.add({ [newLang]: newMessages });
},
add(newMessages = {}) {
deepAssign(messages.value, newMessages);
},
};

View File

@ -0,0 +1,77 @@
export default {
name: 'Name',
tel: 'Phone',
save: 'Save',
confirm: 'Confirm',
cancel: 'Cancel',
delete: 'Delete',
complete: 'Complete',
loading: 'Loading...',
telEmpty: 'Please fill in the tel',
nameEmpty: 'Please fill in the name',
nameInvalid: 'Malformed name',
confirmDelete: 'Are you sure you want to delete?',
telInvalid: 'Malformed phone number',
vanCalendar: {
end: 'End',
start: 'Start',
title: 'Calendar',
startEnd: 'Start/End',
weekdays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
monthTitle: (year: number, month: number) => `${year}/${month}`,
rangePrompt: (maxRange: number) => `Choose no more than ${maxRange} days`,
},
vanContactCard: {
addText: 'Add contact info',
},
vanContactList: {
addText: 'Add new contact',
},
vanPagination: {
prev: 'Previous',
next: 'Next',
},
vanPullRefresh: {
pulling: 'Pull to refresh...',
loosing: 'Loose to refresh...',
},
vanSubmitBar: {
label: 'Total',
},
vanCoupon: {
unlimited: 'Unlimited',
discount: (discount: number) => `${discount * 10}% off`,
condition: (condition: number) => `At least ${condition}`,
},
vanCouponCell: {
title: 'Coupon',
tips: 'No coupons',
count: (count: number) => `You have ${count} coupons`,
},
vanCouponList: {
empty: 'No coupons',
exchange: 'Exchange',
close: 'Close',
enable: 'Available',
disabled: 'Unavailable',
placeholder: 'Coupon code',
},
vanAddressEdit: {
area: 'Area',
postal: 'Postal',
areaEmpty: 'Please select a receiving area',
addressEmpty: 'Address can not be empty',
postalEmpty: 'Wrong postal code',
defaultAddress: 'Set as the default address',
telPlaceholder: 'Phone',
namePlaceholder: 'Name',
areaPlaceholder: 'Area',
},
vanAddressEditDetail: {
label: 'Address',
placeholder: 'Address',
},
vanAddressList: {
add: 'Add new address',
},
};

View File

@ -0,0 +1,77 @@
export default {
name: 'Nombre',
tel: 'Teléfono',
save: 'Guardar',
confirm: 'Confirmar',
cancel: 'Cancelar',
delete: 'Eliminar',
complete: 'Completado',
loading: 'Cargando...',
telEmpty: 'Por favor rellena el teléfono',
nameEmpty: 'Por favor rellena el nombre',
nameInvalid: 'nombre inválido',
confirmDelete: 'Estás seguro de eliminarlo?',
telInvalid: 'Teléfono inválido',
vanCalendar: {
end: 'Fin',
start: 'Inicio',
title: 'Calendario',
startEnd: 'Inicio/Fin',
weekdays: ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'],
monthTitle: (year: number, month: number) => `${year}/${month}`,
rangePrompt: (maxRange: number) => `Elija no más de ${maxRange} días`,
},
vanContactCard: {
addText: 'Añadir información de contacto',
},
vanContactList: {
addText: 'Añadir nuevo contacto',
},
vanPagination: {
prev: 'Anterior',
next: 'Siguiente',
},
vanPullRefresh: {
pulling: 'Tira para recargar...',
loosing: 'Suelta para recargar...',
},
vanSubmitBar: {
label: 'Total',
},
vanCoupon: {
unlimited: 'Ilimitado',
discount: (discount: number) => `${discount * 10}% de descuento`,
condition: (condition: number) => `Al menos ${condition}`,
},
vanCouponCell: {
title: 'Cupón',
tips: 'Sin cupones',
count: (count: number) => `You have ${count} coupons`,
},
vanCouponList: {
empty: 'Sin cupones',
exchange: 'Intercambio',
close: 'Cerrar',
enable: 'Disponible',
disabled: 'No disponible',
placeholder: 'Código del cupón',
},
vanAddressEdit: {
area: 'Área',
postal: 'Código Postal',
areaEmpty: 'Por favor selecciona una área de recogida',
addressEmpty: 'La dirección no puede estar vacia',
postalEmpty: 'Código postal inválido',
defaultAddress: 'Establecer como dirección por defecto',
telPlaceholder: 'Teléfono',
namePlaceholder: 'Nombre',
areaPlaceholder: 'Área',
},
vanAddressEditDetail: {
label: 'Dirección',
placeholder: 'Dirección',
},
vanAddressList: {
add: 'Anadir dirección',
},
};

View File

@ -0,0 +1,78 @@
export default {
name: 'お名前',
tel: '電話番号',
save: 'セーブ',
confirm: '確認',
cancel: 'キャンセル',
delete: '削除',
complete: '完了',
loading: '読み込み中...',
telEmpty: '電話番号を入力してください',
nameEmpty: '名前を入力してください',
nameInvalid: '正しい名前を入力してください',
confirmDelete: '本当に削除しますか',
telInvalid: '正しい電話番号を入力してください',
vanCalendar: {
end: '終了',
start: '開始',
title: '日付選択',
confirm: '確認',
startEnd: '開始/終了',
weekdays: ['日', '月', '火', '水', '木', '金', '土'],
monthTitle: (year: number, month: number) => `${year}${month}`,
rangePrompt: (maxRange: number) => `${maxRange}日以内を選択してください`,
},
vanContactCard: {
addText: '連絡先を追加',
},
vanContactList: {
addText: '新しい連絡先を追加',
},
vanPagination: {
prev: '前のページ',
next: '次のページ',
},
vanPullRefresh: {
pulling: 'プルダウンして更新...',
loosing: 'リリース時に更新...',
},
vanSubmitBar: {
label: '合計:',
},
vanCoupon: {
unlimited: '入場ありません',
discount: (discount: number) => `${10 - discount}割引`,
condition: (condition: number) => `${condition}円以上で利用可能`,
},
vanCouponCell: {
title: 'クーポン',
tips: '利用可能なクーポンがありません',
count: (count: number) => `${count}枚が利用可能`,
},
vanCouponList: {
empty: 'クーポンはありません',
exchange: '両替',
close: 'クーポンを使用しません',
enable: '利用可能',
disabled: '利用できません',
placeholder: '割引コードを入力してください',
},
vanAddressEdit: {
area: '地域',
postal: '郵便番号',
areaEmpty: '地域を選択してください',
addressEmpty: '詳しい住所を入力してください',
postalEmpty: '邮政编码格式不正确',
defaultAddress: 'デフォルトの住所に設定',
telPlaceholder: '荷受人の携帯番号',
namePlaceholder: '荷受人の名前',
areaPlaceholder: '县 / 市 / 町を選択',
},
vanAddressEditDetail: {
label: '詳しい住所',
placeholder: '番地、階の部屋番号など',
},
vanAddressList: {
add: '住所を追加',
},
};

View File

@ -0,0 +1,77 @@
export default {
name: 'Nume',
tel: 'Telefon',
save: 'Salvează',
confirm: 'Confirmă',
cancel: 'Anulează',
delete: 'Șterge',
complete: 'Finalizează',
loading: 'Încărcare...',
telEmpty: 'Te rugăm să completezi telefonul',
nameEmpty: 'Te rugăm să completezi numele',
nameInvalid: 'Nume incorect',
confirmDelete: 'Ești sigur ca vrei sa stergi?',
telInvalid: 'Număr de telefon invalid',
vanCalendar: {
end: 'Sfârșit',
start: 'Început',
title: 'Calendar',
startEnd: 'Început/Sfârsit',
weekdays: ['Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sâm'],
monthTitle: (year: number, month: number) => `${year}/${month}`,
rangePrompt: (maxRange: number) => `Alege maxim ${maxRange} zile`,
},
vanContactCard: {
addText: 'Adaugă informațiile de contact',
},
vanContactList: {
addText: 'Adaugă contact nou',
},
vanPagination: {
prev: 'Precedenta',
next: 'Urmatoarea',
},
vanPullRefresh: {
pulling: 'Trage pentru a da împrospăta...',
loosing: 'Eliberează pentru a împrospăta...',
},
vanSubmitBar: {
label: 'Total',
},
vanCoupon: {
unlimited: 'Nelimitat',
discount: (discount: number) => `${discount * 10}% discount`,
condition: (condition: number) => `Cel puțin ${condition}`,
},
vanCouponCell: {
title: 'Cupon',
tips: 'Fără cupoane',
count: (count: number) => `Ai ${count} cupoane`,
},
vanCouponList: {
empty: 'Fără cupoane',
exchange: 'Schimbă',
close: 'Închide',
enable: 'Disponibil',
disabled: 'Indisponibil',
placeholder: 'Cod cupon',
},
vanAddressEdit: {
area: 'Zonă',
postal: 'Cod postal',
areaEmpty: 'Te rugăm sa selectezi o zona de primire',
addressEmpty: 'Adresa nu poate fi goală',
postalEmpty: 'Cod postal invalid',
defaultAddress: 'Setează ca adresă de pornire',
telPlaceholder: 'Telefon',
namePlaceholder: 'Nume',
areaPlaceholder: 'Zonă',
},
vanAddressEditDetail: {
label: 'Adresă',
placeholder: 'Adresă',
},
vanAddressList: {
add: 'Adaugă adresă nouă',
},
};

View File

@ -0,0 +1,77 @@
export default {
name: 'İsim',
tel: 'Telefon',
save: 'Kaydet',
confirm: 'Onayla',
cancel: 'İptal',
delete: 'Sil',
complete: 'Tamamla',
loading: 'Yükleniyor...',
telEmpty: 'Lütfen tel. no giriniz',
nameEmpty: 'Lütfen isim giriniz',
nameInvalid: 'Geçersiz isim',
confirmDelete: 'Silmek istediğinize emin misiniz?',
telInvalid: 'Geçersiz tel. numarası',
vanCalendar: {
end: 'Son',
start: 'Başlat',
title: 'Takvim',
startEnd: 'Başlat/Son',
weekdays: ['Paz', 'Pzt', 'Sal', 'Çar', 'Per', 'Cum', 'Cmt'],
monthTitle: (year: number, month: number) => `${year}/${month}`,
rangePrompt: (maxRange: number) => `En fazla ${maxRange} gün seçin`,
},
vanContactCard: {
addText: 'Kişi bilgisi ekle',
},
vanContactList: {
addText: 'Yeni kişi ekle',
},
vanPagination: {
prev: 'Önceki',
next: 'Sonraki',
},
vanPullRefresh: {
pulling: 'Yenilemek için çekin...',
loosing: 'Yenilemek için bırakın...',
},
vanSubmitBar: {
label: 'Toplam:',
},
vanCoupon: {
unlimited: 'Sınırsız',
discount: (discount: number) => `%${discount * 10} indirim`,
condition: (condition: number) => `En az ${condition}`,
},
vanCouponCell: {
title: 'Kupon',
tips: 'Kupon yok',
count: (count: number) => `${count} adet teklif var`,
},
vanCouponList: {
empty: 'Kupon yok',
exchange: 'Takas',
close: 'Kapat',
enable: 'Mevcut',
disabled: 'Mevcut değil',
placeholder: 'Kupon kodu',
},
vanAddressEdit: {
area: 'Alan',
postal: 'Posta',
areaEmpty: 'Lütfen alıcı alanını seçin',
addressEmpty: 'Adres boş olamaz!',
postalEmpty: 'Yanlış posta kodu',
defaultAddress: 'Varsayılan adres olarak ayarla',
telPlaceholder: 'Telefone',
namePlaceholder: 'İsim',
areaPlaceholder: 'Alan',
},
vanAddressEditDetail: {
label: 'Adres',
placeholder: 'Adres',
},
vanAddressList: {
add: 'Yeni adres ekle',
},
};

View File

@ -0,0 +1,78 @@
export default {
name: '姓名',
tel: '电话',
save: '保存',
confirm: '确认',
cancel: '取消',
delete: '删除',
complete: '完成',
loading: '加载中...',
telEmpty: '请填写电话',
nameEmpty: '请填写姓名',
nameInvalid: '请输入正确的姓名',
confirmDelete: '确定要删除吗',
telInvalid: '请输入正确的手机号',
vanCalendar: {
end: '结束',
start: '开始',
title: '日期选择',
confirm: '确定',
startEnd: '开始/结束',
weekdays: ['日', '一', '二', '三', '四', '五', '六'],
monthTitle: (year: number, month: number) => `${year}${month}`,
rangePrompt: (maxRange: number) => `选择天数不能超过 ${maxRange}`,
},
vanContactCard: {
addText: '添加联系人',
},
vanContactList: {
addText: '新建联系人',
},
vanPagination: {
prev: '上一页',
next: '下一页',
},
vanPullRefresh: {
pulling: '下拉即可刷新...',
loosing: '释放即可刷新...',
},
vanSubmitBar: {
label: '合计:',
},
vanCoupon: {
unlimited: '无使用门槛',
discount: (discount: number) => `${discount}`,
condition: (condition: number) => `${condition}元可用`,
},
vanCouponCell: {
title: '优惠券',
tips: '暂无可用',
count: (count: number) => `${count}张可用`,
},
vanCouponList: {
empty: '暂无优惠券',
exchange: '兑换',
close: '不使用优惠券',
enable: '可用',
disabled: '不可用',
placeholder: '请输入优惠码',
},
vanAddressEdit: {
area: '地区',
postal: '邮政编码',
areaEmpty: '请选择地区',
addressEmpty: '请填写详细地址',
postalEmpty: '邮政编码格式不正确',
defaultAddress: '设为默认收货地址',
telPlaceholder: '收货人手机号',
namePlaceholder: '收货人姓名',
areaPlaceholder: '选择省 / 市 / 区',
},
vanAddressEditDetail: {
label: '详细地址',
placeholder: '街道门牌、楼层房间号等信息',
},
vanAddressList: {
add: '新增地址',
},
};

View File

@ -0,0 +1,78 @@
export default {
name: '姓名',
tel: '電話',
save: '保存',
confirm: '確認',
cancel: '取消',
delete: '刪除',
complete: '完成',
loading: '加載中...',
telEmpty: '請填寫電話',
nameEmpty: '請填寫姓名',
nameInvalid: '請輸入正確的姓名',
confirmDelete: '確定要刪除嗎',
telInvalid: '請填寫正確的電話',
vanCalendar: {
end: '結束',
start: '開始',
title: '日期選擇',
confirm: '確定',
startEnd: '開始/結束',
weekdays: ['日', '壹', '二', '三', '四', '五', '六'],
monthTitle: (year: number, month: number) => `${year}${month}`,
rangePrompt: (maxRange: number) => `選擇天數不能超過 ${maxRange}`,
},
vanContactCard: {
addText: '添加聯系人',
},
vanContactList: {
addText: '新建聯系人',
},
vanPagination: {
prev: '上一頁',
next: '下一頁',
},
vanPullRefresh: {
pulling: '下拉即可刷新...',
loosing: '釋放即可刷新...',
},
vanSubmitBar: {
label: '合計:',
},
vanCoupon: {
unlimited: '無使用門檻',
discount: (discount: number) => `${discount}`,
condition: (condition: number) => `滿${condition}元可用`,
},
vanCouponCell: {
title: '優惠券',
tips: '暫無可用',
count: (count: number) => `${count}張可用`,
},
vanCouponList: {
empty: '暫無優惠券',
exchange: '兌換',
close: '不使用優惠',
enable: '可使用優惠券',
disabled: '不可使用優惠券',
placeholder: '請輸入優惠碼',
},
vanAddressEdit: {
area: '地區',
postal: '郵政編碼',
areaEmpty: '請選擇地區',
addressEmpty: '請填寫詳細地址',
postalEmpty: '郵政編碼格式不正確',
defaultAddress: '設為默認收貨地址',
telPlaceholder: '收貨人手機號',
namePlaceholder: '收貨人姓名',
areaPlaceholder: '選擇省 / 市 / 區',
},
vanAddressEditDetail: {
label: '詳細地址',
placeholder: '街道門牌、樓層房間號等信息',
},
vanAddressList: {
add: '新增地址',
},
};

View File

@ -0,0 +1,78 @@
export default {
name: '姓名',
tel: '電話',
save: '儲存',
confirm: '確認',
cancel: '取消',
delete: '刪除',
complete: '完成',
loading: '載入中...',
telEmpty: '請填寫電話',
nameEmpty: '請填寫姓名',
nameInvalid: '請輸入正確的姓名',
confirmDelete: '確定要刪除嗎',
telInvalid: '請填寫正確的電話',
vanCalendar: {
end: '結束',
start: '開始',
title: '日期選擇',
confirm: '確定',
startEnd: '開始/結束',
weekdays: ['日', '壹', '二', '三', '四', '五', '六'],
monthTitle: (year: number, month: number) => `${year}${month}`,
rangePrompt: (maxRange: number) => `選擇天數不能超過 ${maxRange}`,
},
vanContactCard: {
addText: '新增聯絡人',
},
vanContactList: {
addText: '建立聯絡人',
},
vanPagination: {
prev: '上一頁',
next: '下一頁',
},
vanPullRefresh: {
pulling: '下拉即可刷新...',
loosing: '釋放即可刷新...',
},
vanSubmitBar: {
label: '合計:',
},
vanCoupon: {
unlimited: '無使用門檻',
discount: (discount: number) => `${discount}`,
condition: (condition: number) => `滿${condition}元可用`,
},
vanCouponCell: {
title: '優惠券',
tips: '暫無可用',
count: (count: number) => `${count}張可用`,
},
vanCouponList: {
empty: '暫無優惠券',
exchange: '兌換',
close: '不使用優惠',
enable: '可使用優惠券',
disabled: '不可使用優惠券',
placeholder: '請輸入優惠代碼',
},
vanAddressEdit: {
area: '地區',
postal: '郵遞區號',
areaEmpty: '請選擇地區',
addressEmpty: '請填寫詳細地址',
postalEmpty: '郵遞區號格式不正確',
defaultAddress: '設為預設收貨地址',
telPlaceholder: '收貨人手機號碼',
namePlaceholder: '收貨人姓名',
areaPlaceholder: '選擇縣 / 市',
},
vanAddressEditDetail: {
label: '詳細地址',
placeholder: '街道門牌、樓層房號等資訊',
},
vanAddressList: {
add: '新增地址',
},
};

View File

@ -0,0 +1,16 @@
import { get, isFunction } from '../../../src/utils';
import { camelize } from '../../../src/utils/format/string';
import locale from '../../locale';
export function createI18N(name: string) {
const prefix = camelize(name) + '.';
return function (path: string, ...args: any[]): string {
const messages = locale.messages();
const message = get(messages, prefix + path) || get(messages, path);
return isFunction(message) ? message(...args) : message;
};
}
export type Translate = ReturnType<typeof createI18N>;

View File

@ -1,11 +1,11 @@
import { createBEM, BEM } from './bem';
import { createComponent } from './component';
// import { createI18N, Translate } from './i18n';
import { createI18N, Translate } from './i18n';
type CreateNamespaceReturn = [
ReturnType<typeof createComponent>,
BEM,
// Translate
Translate
];
export function createNamespace(name: string): CreateNamespaceReturn {
@ -13,6 +13,6 @@ export function createNamespace(name: string): CreateNamespaceReturn {
return [
createComponent(name),
createBEM(name),
// createI18N(name)
createI18N(name)
];
}

View File

@ -1,9 +1,9 @@
import Vue from 'vue';
// import Vue from 'vue';
export { createNamespace } from './create';
// export { createNamespace } from './create';
export { addUnit } from './format/unit';
export const isServer: boolean = Vue.prototype.$isServer;
// export const isServer: boolean = Vue.prototype.$isServer;
// eslint-disable-next-line @typescript-eslint/no-empty-function
export function noop() {}