提交 d203c321 编写于 作者: Q qiang

feat: getLanguage, setLanguage

上级 d23d6f9f
......@@ -65,6 +65,9 @@ module.exports = {
plugins: [
alias({
entries: [{
find: '@dcloudio',
replacement: resolve('packages')
}, {
find: 'uni-core',
replacement: resolve('src/core')
}, {
......
......@@ -57,6 +57,9 @@ module.exports = {
plugins: [
alias({
entries: [{
find: '@dcloudio',
replacement: path.resolve(__dirname, '../packages')
}, {
find: 'uni-shared/query',
replacement: path.resolve(__dirname, '../src/shared/query.js')
}, {
......
......@@ -33,6 +33,9 @@ const plugins = [{
},
alias({
entries: [{
find: '@dcloudio',
replacement: resolve('packages')
}, {
find: 'uni-core',
replacement: resolve('src/core')
}, {
......
......@@ -12,6 +12,10 @@ module.exports = {
plugins: [
alias({
entries: [{
find: '@dcloudio',
replacement: path.resolve(__dirname, '../packages')
},
{
find: 'uni-core',
replacement: path.resolve(__dirname, '../src/core')
},
......
......@@ -21,6 +21,7 @@ if (process.env.UNI_VIEW !== 'true') {
}
const alias = {
'@dcloudio': resolve('packages'),
'uni-core': resolve('src/core'),
'uni-view': resolve('src/core/view'),
'uni-service': resolve('src/core/service'),
......
......@@ -16,6 +16,7 @@ const config = service.resolveWebpackConfig()
config.resolve.alias = {
'@': resolve('src'),
'@dcloudio': resolve('packages'),
'uni-core': resolve('src/core'),
'uni-view': resolve('src/core/view'),
'uni-service': resolve('src/core/service'),
......
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"uni-core/*": [
"./src/core/*"
],
"@dcloudio/*": [
"./packages/*"
]
}
}
}
......@@ -182,7 +182,9 @@ const ui = [
'getRightWindowStyle',
'setTopWindowStyle',
'setLeftWindowStyle',
'setRightWindowStyle'
'setRightWindowStyle',
'getLanguage',
'setLanguage'
]
const event = [
......
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const isObject = (val) => val !== null && typeof val === 'object';
class BaseFormatter {
constructor() {
......@@ -98,8 +98,13 @@ function compile(tokens, values) {
index++;
}
return compiled;
}
}
const LOCALE_ZH_HANS = 'zh-Hans';
const LOCALE_ZH_HANT = 'zh-Hant';
const LOCALE_EN = 'en';
const LOCALE_FR = 'fr';
const LOCALE_ES = 'es';
const hasOwnProperty = Object.prototype.hasOwnProperty;
const hasOwn = (val, key) => hasOwnProperty.call(val, key);
const defaultFormatter = new BaseFormatter();
......@@ -120,25 +125,25 @@ function normalizeLocale(locale, messages) {
locale = locale.toLowerCase();
if (locale.indexOf('zh') === 0) {
if (locale.indexOf('-hans') !== -1) {
return 'zh-Hans';
return LOCALE_ZH_HANS;
}
if (locale.indexOf('-hant') !== -1) {
return 'zh-Hant';
return LOCALE_ZH_HANT;
}
if (include(locale, ['-tw', '-hk', '-mo', '-cht'])) {
return 'zh-Hant';
return LOCALE_ZH_HANT;
}
return 'zh-Hans';
return LOCALE_ZH_HANS;
}
const lang = startsWith(locale, ['en', 'fr', 'es']);
const lang = startsWith(locale, [LOCALE_EN, LOCALE_FR, LOCALE_ES]);
if (lang) {
return lang;
}
}
class I18n {
constructor({ locale, fallbackLocale, messages, watcher, formater, }) {
this.locale = 'en';
this.fallbackLocale = 'en';
this.locale = LOCALE_EN;
this.fallbackLocale = LOCALE_EN;
this.message = {};
this.messages = {};
this.watchers = [];
......@@ -146,7 +151,7 @@ class I18n {
this.fallbackLocale = fallbackLocale;
}
this.formater = formater || defaultFormatter;
this.messages = messages;
this.messages = messages || {};
this.setLocale(locale);
if (watcher) {
this.watchLocale(watcher);
......@@ -155,6 +160,10 @@ class I18n {
setLocale(locale) {
const oldLocale = this.locale;
this.locale = normalizeLocale(locale, this.messages) || this.fallbackLocale;
if (!this.messages[this.locale]) {
// 可能初始化时不存在
this.messages[this.locale] = {};
}
this.message = this.messages[this.locale];
this.watchers.forEach((watcher) => {
watcher(this.locale, oldLocale);
......@@ -169,6 +178,14 @@ class I18n {
this.watchers.splice(index, 1);
};
}
add(locale, message) {
if (this.messages[locale]) {
Object.assign(this.messages[locale], message);
}
else {
this.messages[locale] = message;
}
}
t(key, locale, values) {
let message = this.message;
if (typeof locale === 'string') {
......@@ -184,35 +201,46 @@ class I18n {
}
return this.formater.interpolate(message[key], values).join('');
}
}
}
const ignoreVueI18n = true;
function initLocaleWatcher(appVm, i18n) {
appVm.$i18n &&
appVm.$i18n.vm.$watch('locale', (newLocale) => {
if (appVm.$i18n) {
const vm = appVm.$i18n.vm ? appVm.$i18n.vm : appVm;
vm.$watch(appVm.$i18n.vm ? 'locale' : () => appVm.$i18n.locale, (newLocale) => {
i18n.setLocale(newLocale);
}, {
immediate: true,
});
}
}
function getDefaultLocale() {
if (typeof navigator !== 'undefined') {
return navigator.userLanguage || navigator.language;
// function getDefaultLocale() {
// if (typeof navigator !== 'undefined') {
// return (navigator as any).userLanguage || navigator.language
// }
// if (typeof plus !== 'undefined') {
// // TODO 待调整为最新的获取语言代码
// return plus.os.language
// }
// return uni.getSystemInfoSync().language
// }
function initVueI18n(locale = LOCALE_EN, messages = {}, fallbackLocale = LOCALE_EN, watcher) {
// 兼容旧版本入参
if (typeof locale !== 'string') {
[locale, messages] = [messages, locale];
}
if (typeof plus !== 'undefined') {
// TODO 待调整为最新的获取语言代码
return plus.os.language;
if (typeof locale !== 'string') {
locale = fallbackLocale;
}
return uni.getSystemInfoSync().language;
}
function initVueI18n(messages, fallbackLocale = 'en', locale) {
const i18n = new I18n({
locale: locale || fallbackLocale,
fallbackLocale,
messages,
watcher,
});
let t = (key, values) => {
if (typeof getApp !== 'function') {
// app-plus view
// app view
/* eslint-disable no-func-assign */
t = function (key, values) {
return i18n.t(key, values);
......@@ -220,10 +248,10 @@ function initVueI18n(messages, fallbackLocale = 'en', locale) {
}
else {
const appVm = getApp().$vm;
if (!appVm.$t || !appVm.$i18n) {
if (!locale) {
i18n.setLocale(getDefaultLocale());
}
if (!appVm.$t || !appVm.$i18n || ignoreVueI18n) {
// if (!locale) {
// i18n.setLocale(getDefaultLocale())
// }
/* eslint-disable no-func-assign */
t = function (key, values) {
return i18n.t(key, values);
......@@ -248,32 +276,26 @@ function initVueI18n(messages, fallbackLocale = 'en', locale) {
return t(key, values);
};
return {
i18n,
t(key, values) {
return t(key, values);
},
add(locale, message) {
return i18n.add(locale, message);
},
getLocale() {
return i18n.getLocale();
},
setLocale(newLocale) {
return i18n.setLocale(newLocale);
},
mixin: {
beforeCreate() {
const unwatch = i18n.watchLocale(() => {
this.$forceUpdate();
});
this.$once('hook:beforeDestroy', function () {
unwatch();
});
},
methods: {
$$t(key, values) {
return t(key, values);
},
},
},
};
}
exports.I18n = I18n;
exports.initVueI18n = initVueI18n;
}
exports.I18n = I18n;
exports.LOCALE_EN = LOCALE_EN;
exports.LOCALE_ES = LOCALE_ES;
exports.LOCALE_FR = LOCALE_FR;
exports.LOCALE_ZH_HANS = LOCALE_ZH_HANS;
exports.LOCALE_ZH_HANT = LOCALE_ZH_HANT;
exports.initVueI18n = initVueI18n;
export declare type BuiltInLocale = 'zh-Hans' | 'zh-Hant' | 'en' | 'fr' | 'es';
export declare type BuiltInLocale = typeof LOCALE_ZH_HANS | typeof LOCALE_ZH_HANT | typeof LOCALE_EN | typeof LOCALE_FR | typeof LOCALE_ES;
export declare interface Formatter {
interpolate: (message: string, values?: Record<string, unknown> | Array<unknown>) => Array<unknown>;
......@@ -16,6 +15,7 @@ export declare class I18n {
setLocale(locale: string): void;
getLocale(): BuiltInLocale;
watchLocale(fn: LocaleWatcher): () => void;
add(locale: BuiltInLocale, message: Record<string, string>): void;
t(key: string, values?: Record<string, unknown> | Array<unknown> | BuiltInLocale): string;
t(key: string, locale?: BuiltInLocale, values?: Record<string, unknown> | Array<unknown>): string;
}
......@@ -23,23 +23,29 @@ export declare class I18n {
export declare interface I18nOptions {
locale: BuiltInLocale;
fallbackLocale?: BuiltInLocale;
messages: LocaleMessages;
messages?: LocaleMessages;
formater?: Formatter;
watcher?: LocaleWatcher;
}
export declare function initVueI18n(messages: LocaleMessages, fallbackLocale?: BuiltInLocale, locale?: BuiltInLocale): {
export declare function initVueI18n(locale?: BuiltInLocale, messages?: LocaleMessages, fallbackLocale?: BuiltInLocale, watcher?: (locale: BuiltInLocale) => void): {
i18n: I18n;
t(key: string, values?: Record<string, unknown> | unknown[] | undefined): string;
add(locale: BuiltInLocale, message: Record<string, string>): void;
getLocale(): BuiltInLocale;
setLocale(newLocale: BuiltInLocale): void;
mixin: {
beforeCreate(): void;
methods: {
$$t(key: string, values?: any): string;
};
};
};
export declare const LOCALE_EN = "en";
export declare const LOCALE_ES = "es";
export declare const LOCALE_FR = "fr";
export declare const LOCALE_ZH_HANS = "zh-Hans";
export declare const LOCALE_ZH_HANT = "zh-Hant";
export declare type LocaleMessages = {
[name in BuiltInLocale]?: Record<string, string>;
};
......
......@@ -96,6 +96,11 @@ function compile(tokens, values) {
return compiled;
}
const LOCALE_ZH_HANS = 'zh-Hans';
const LOCALE_ZH_HANT = 'zh-Hant';
const LOCALE_EN = 'en';
const LOCALE_FR = 'fr';
const LOCALE_ES = 'es';
const hasOwnProperty = Object.prototype.hasOwnProperty;
const hasOwn = (val, key) => hasOwnProperty.call(val, key);
const defaultFormatter = new BaseFormatter();
......@@ -116,25 +121,25 @@ function normalizeLocale(locale, messages) {
locale = locale.toLowerCase();
if (locale.indexOf('zh') === 0) {
if (locale.indexOf('-hans') !== -1) {
return 'zh-Hans';
return LOCALE_ZH_HANS;
}
if (locale.indexOf('-hant') !== -1) {
return 'zh-Hant';
return LOCALE_ZH_HANT;
}
if (include(locale, ['-tw', '-hk', '-mo', '-cht'])) {
return 'zh-Hant';
return LOCALE_ZH_HANT;
}
return 'zh-Hans';
return LOCALE_ZH_HANS;
}
const lang = startsWith(locale, ['en', 'fr', 'es']);
const lang = startsWith(locale, [LOCALE_EN, LOCALE_FR, LOCALE_ES]);
if (lang) {
return lang;
}
}
class I18n {
constructor({ locale, fallbackLocale, messages, watcher, formater, }) {
this.locale = 'en';
this.fallbackLocale = 'en';
this.locale = LOCALE_EN;
this.fallbackLocale = LOCALE_EN;
this.message = {};
this.messages = {};
this.watchers = [];
......@@ -142,7 +147,7 @@ class I18n {
this.fallbackLocale = fallbackLocale;
}
this.formater = formater || defaultFormatter;
this.messages = messages;
this.messages = messages || {};
this.setLocale(locale);
if (watcher) {
this.watchLocale(watcher);
......@@ -151,6 +156,10 @@ class I18n {
setLocale(locale) {
const oldLocale = this.locale;
this.locale = normalizeLocale(locale, this.messages) || this.fallbackLocale;
if (!this.messages[this.locale]) {
// 可能初始化时不存在
this.messages[this.locale] = {};
}
this.message = this.messages[this.locale];
this.watchers.forEach((watcher) => {
watcher(this.locale, oldLocale);
......@@ -165,6 +174,14 @@ class I18n {
this.watchers.splice(index, 1);
};
}
add(locale, message) {
if (this.messages[locale]) {
Object.assign(this.messages[locale], message);
}
else {
this.messages[locale] = message;
}
}
t(key, locale, values) {
let message = this.message;
if (typeof locale === 'string') {
......@@ -182,33 +199,44 @@ class I18n {
}
}
const ignoreVueI18n = true;
function initLocaleWatcher(appVm, i18n) {
appVm.$i18n &&
appVm.$i18n.vm.$watch('locale', (newLocale) => {
if (appVm.$i18n) {
const vm = appVm.$i18n.vm ? appVm.$i18n.vm : appVm;
vm.$watch(appVm.$i18n.vm ? 'locale' : () => appVm.$i18n.locale, (newLocale) => {
i18n.setLocale(newLocale);
}, {
immediate: true,
});
}
}
function getDefaultLocale() {
if (typeof navigator !== 'undefined') {
return navigator.userLanguage || navigator.language;
// function getDefaultLocale() {
// if (typeof navigator !== 'undefined') {
// return (navigator as any).userLanguage || navigator.language
// }
// if (typeof plus !== 'undefined') {
// // TODO 待调整为最新的获取语言代码
// return plus.os.language
// }
// return uni.getSystemInfoSync().language
// }
function initVueI18n(locale = LOCALE_EN, messages = {}, fallbackLocale = LOCALE_EN, watcher) {
// 兼容旧版本入参
if (typeof locale !== 'string') {
[locale, messages] = [messages, locale];
}
if (typeof plus !== 'undefined') {
// TODO 待调整为最新的获取语言代码
return plus.os.language;
if (typeof locale !== 'string') {
locale = fallbackLocale;
}
return uni.getSystemInfoSync().language;
}
function initVueI18n(messages, fallbackLocale = 'en', locale) {
const i18n = new I18n({
locale: locale || fallbackLocale,
fallbackLocale,
messages,
watcher,
});
let t = (key, values) => {
if (typeof getApp !== 'function') {
// app-plus view
// app view
/* eslint-disable no-func-assign */
t = function (key, values) {
return i18n.t(key, values);
......@@ -216,10 +244,10 @@ function initVueI18n(messages, fallbackLocale = 'en', locale) {
}
else {
const appVm = getApp().$vm;
if (!appVm.$t || !appVm.$i18n) {
if (!locale) {
i18n.setLocale(getDefaultLocale());
}
if (!appVm.$t || !appVm.$i18n || ignoreVueI18n) {
// if (!locale) {
// i18n.setLocale(getDefaultLocale())
// }
/* eslint-disable no-func-assign */
t = function (key, values) {
return i18n.t(key, values);
......@@ -244,31 +272,20 @@ function initVueI18n(messages, fallbackLocale = 'en', locale) {
return t(key, values);
};
return {
i18n,
t(key, values) {
return t(key, values);
},
add(locale, message) {
return i18n.add(locale, message);
},
getLocale() {
return i18n.getLocale();
},
setLocale(newLocale) {
return i18n.setLocale(newLocale);
},
mixin: {
beforeCreate() {
const unwatch = i18n.watchLocale(() => {
this.$forceUpdate();
});
this.$once('hook:beforeDestroy', function () {
unwatch();
});
},
methods: {
$$t(key, values) {
return t(key, values);
},
},
},
};
}
export { I18n, initVueI18n };
export { I18n, LOCALE_EN, LOCALE_ES, LOCALE_FR, LOCALE_ZH_HANS, LOCALE_ZH_HANT, initVueI18n };
......@@ -127,7 +127,8 @@ module.exports = function (pagesJson, userManifestJson, isAppView) {
version: {
name: userManifestJson.versionName,
code: userManifestJson.versionCode
}
},
language: userManifestJson.language
}, {
plus: userManifestJson['app-plus']
}
......
......@@ -438,6 +438,9 @@ module.exports = function (pagesJson, manifestJson, loader) {
qqMapKey = sdkConfigs.maps.qqmap.key
}
let language = manifestJson.language
language = language && language.toUpperCase() !== 'AUTO' ? language : ''
return `
import Vue from 'vue'
${genLayoutComponentsCode(pagesJson)}
......@@ -452,6 +455,7 @@ global.__uniConfig.debug = ${manifestJson.debug === true};
global.__uniConfig.networkTimeout = ${JSON.stringify(networkTimeoutConfig)};
global.__uniConfig.sdkConfigs = ${JSON.stringify(sdkConfigs)};
global.__uniConfig.qqMapKey = ${JSON.stringify(qqMapKey)};
global.__uniConfig.language = ${JSON.stringify(language)};
global.__uniConfig.nvue = ${JSON.stringify({ 'flex-direction': getFlexDirection(manifestJson['app-plus']) })}
global.__uniConfig.__webpack_chunk_load__ = __webpack_chunk_load__
${genRegisterPageVueComponentsCode(pageComponents)}
......
......@@ -16,10 +16,34 @@ const messages = {
'zh-Hant': zhHant
}
const fallbackLocale = 'en'
let language
const i18n = initVueI18n(__PLATFORM__ === 'app-plus' || __PLATFORM__ === 'h5' ? messages : {}, fallbackLocale)
if (__PLATFORM__ === 'h5') {
language = (__uniConfig.language || navigator.language)
} else if (__PLATFORM__ === 'app-plus') {
if (typeof weex === 'object') {
language = weex.requireModule('plus').getLanguage()
}
} else {
language = uni.getSystemInfoSync().language
}
export const i18n = initVueI18n(language, __PLATFORM__ === 'app-plus' || __PLATFORM__ === 'h5' ? messages : {})
export const t = i18n.t
export const i18nMixin = i18n.mixin
export const i18nMixin = i18n.mixin = {
beforeCreate () {
const unwatch = i18n.i18n.watchLocale(() => {
this.$forceUpdate()
})
this.$once('hook:beforeDestroy', function () {
unwatch()
})
},
methods: {
$$t (key, values) {
return t(key, values)
}
}
}
export const setLocale = i18n.setLocale
export const getLocale = i18n.getLocale
......@@ -8,7 +8,7 @@ import {
} from './interceptor'
const SYNC_API_RE =
/^\$|Window$|WindowStyle$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/
/^\$|Window$|WindowStyle$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64|getLanguage|setLanguage/
const CONTEXT_API_RE = /^create|Manager$/
......
import {
getLocale,
setLocale
} from 'uni-core/helpers/i18n'
export function getLanguage () {
return getLocale()
}
export function setLanguage (locale) {
return setLocale(locale)
}
......@@ -21,3 +21,4 @@ export const WEB_INVOKE_APPSERVICE = 'WEB_INVOKE_APPSERVICE'
export const WEBVIEW_INSERTED = 'webviewInserted'
export const WEBVIEW_REMOVED = 'webviewRemoved'
export const WEBVIEW_ID_PREFIX = 'webviewId'
export const SET_LOCALE = 'i18n.setLocale'
......@@ -55,7 +55,7 @@ function parsePageCreateOptions (vm, route) {
return {
version: VD_SYNC_VERSION,
locale: plus.os.language, // TODO
locale: weex.requireModule('plus').getLanguage(),
disableScroll,
onPageScroll,
onPageReachBottom,
......@@ -121,4 +121,4 @@ export function initLifecycle (Vue) {
}
}
})
}
}
......@@ -7,7 +7,8 @@ import {
WEBVIEW_READY,
WEB_INVOKE_APPSERVICE,
WEBVIEW_INSERTED,
WEBVIEW_REMOVED
WEBVIEW_REMOVED,
SET_LOCALE
} from '../../../constants'
import {
......@@ -27,6 +28,10 @@ import {
onWebviewRemoved
} from './on-webview-lifecycle'
import {
i18n
} from 'uni-core/helpers/i18n'
export function initSubscribeHandlers () {
const {
on,
......@@ -70,4 +75,12 @@ export function initSubscribeHandlers () {
subscribe(WEBVIEW_INSERTED, onWebviewInserted)
subscribe(WEBVIEW_REMOVED, onWebviewRemoved)
}
i18n.i18n.watchLocale(locale => {
const pages = getCurrentPages()
pages.forEach(page => {
publishHandler(SET_LOCALE, locale, page.$page.id)
})
weex.requireModule('plus').setLanguage(locale)
})
}
......@@ -16,7 +16,8 @@ import {
} from '../../constants'
import {
WEBVIEW_READY
WEBVIEW_READY,
SET_LOCALE
} from '../../../constants'
const passiveOptions = supportsPassive ? {
......@@ -56,7 +57,7 @@ function onPageCreate ({
onPageScroll,
onPageReachBottom,
onReachBottomDistance
}, pageId) {
}, pageId) {
setLocale(locale)
onCssVar({
......@@ -85,4 +86,5 @@ function onWebviewReady () { // service 主动发起检测
export default function initSubscribe (subscribe) {
subscribe(WEBVIEW_READY, onWebviewReady)
subscribe(ON_PAGE_CREATE, onPageCreate)
}
subscribe(SET_LOCALE, setLocale)
}
......@@ -743,11 +743,6 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
"@dcloudio/uni-i18n@^2.0.0-31920210514002":
version "2.0.0-31920210514002"
resolved "https://registry.yarnpkg.com/@dcloudio/uni-i18n/-/uni-i18n-2.0.0-31920210514002.tgz#f63d14c234ea0353fabe2d8c681601c7ba07e488"
integrity sha512-shHf27U0KEs//ieCBG1R1aRKNDn6KwcVUIb5GsPuDOqoN7WQY+nEz9QFdOSQY8j9tX4ABOAc1ra0Opz8xFVngA==
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册