diff --git a/build/rollup.config.app.js b/build/rollup.config.app.js index 98e8309aa3560076406088c3d87a6da242101755..aed98434dd5615bda2a7d2eb978c57384dfe1cfc 100644 --- a/build/rollup.config.app.js +++ b/build/rollup.config.app.js @@ -1,4 +1,5 @@ const path = require('path') +const json = require('@rollup/plugin-json') const alias = require('@rollup/plugin-alias') const replace = require('@rollup/plugin-replace') const nodeResolve = require('@rollup/plugin-node-resolve') @@ -88,7 +89,8 @@ module.exports = { find: 'uni-api-protocol', replacement: resolve('src/core/helpers/protocol') }] - }), + }), + json(), nodeResolve(), requireContext(), commonjs(), diff --git a/build/webpack.config.js b/build/webpack.config.js index 2ca26492e4fe0839517512213f38420a306859d6..217cf83ee4bb3f8e40ffb607ed61b70aaeae7990 100644 --- a/build/webpack.config.js +++ b/build/webpack.config.js @@ -47,7 +47,7 @@ const provides = { } if (process.env.UNI_VIEW) { // 方便调试 delete provides.console -} +} if (process.env.UNI_VIEW === 'true') { alias.vue$ = resolve('packages/vue-cli-plugin-uni/packages/h5-vue/dist/vue.runtime.esm.js') @@ -66,7 +66,8 @@ module.exports = { plugins: [ new webpack.DefinePlugin({ __VERSION__: JSON.stringify(pkg.version), - __PLATFORM__: JSON.stringify(process.env.UNI_PLATFORM) + __PLATFORM__: JSON.stringify(process.env.UNI_PLATFORM), + __VIEW__: JSON.stringify(!!process.env.UNI_VIEW) }), new webpack.ProvidePlugin(provides) ] diff --git a/package.json b/package.json index 5a79f08b50bb51c99d30d63c15b264094a04cdae..8276c67d897a9cd6ea83dc95440f2234eacd7e4e 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "release:v3": "npm run lint:cli && lerna publish --no-git-tag-version --force-publish=* --npm-tag=v3" }, "dependencies": { + "@dcloudio/uni-i18n": "^0.0.1", "base64-arraybuffer": "^0.2.0", "intersection-observer": "^0.7.0", "pako": "^1.0.11", @@ -43,6 +44,7 @@ "devDependencies": { "@rollup/plugin-alias": "^3.1.0", "@rollup/plugin-commonjs": "^11.1.0", + "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^7.1.3", "@rollup/plugin-replace": "^2.3.1", "@types/html5plus": "^1.0.0", @@ -118,6 +120,8 @@ "__registerPage": true, "UniViewJSBridge": true, "UniServiceJSBridge": true, + "__DEV__": true, + "__VIEW__": true, "__PLATFORM__": true, "__VERSION__": true, "__GLOBAL__": true, @@ -144,4 +148,4 @@ "main": "index.js", "description": "", "author": "" -} +} diff --git a/src/core/helpers/i18n/en.json b/src/core/helpers/i18n/en.json new file mode 100644 index 0000000000000000000000000000000000000000..7bd1e99a14e4ff8798ba365eb1dc9e8d00821c06 --- /dev/null +++ b/src/core/helpers/i18n/en.json @@ -0,0 +1,9 @@ +{ + "uni.showActionSheet.cancel": "cancel", + "uni.showToast.unpaired": "Please note showToast must be paired with hideToast", + "uni.showLoading.unpaired": "Please note showLoading must be paired with hideLoading", + "uni.showModal.cancel": "cancel", + "uni.showModal.confirm": "confirm", + "uni.button.feedback.title": "feedback", + "uni.button.feedback.send": "send" +} diff --git a/src/core/helpers/i18n/es.json b/src/core/helpers/i18n/es.json new file mode 100644 index 0000000000000000000000000000000000000000..d1d5cd68b338f0ab2cd875e6ad496ce572dd6560 --- /dev/null +++ b/src/core/helpers/i18n/es.json @@ -0,0 +1,9 @@ +{ + "uni.showActionSheet.cancel": "cancelar", + "uni.showToast.unpaired": "Tenga en cuenta que showToast debe estar emparejado con hideToast", + "uni.showLoading.unpaired": "Tenga en cuenta que showLoading debe estar emparejado con hideLoading", + "uni.showModal.cancel": "cancelar", + "uni.showModal.confirm": "confirmar", + "uni.button.feedback.title": "realimentación", + "uni.button.feedback.send": "enviar" +} diff --git a/src/core/helpers/i18n/fr.json b/src/core/helpers/i18n/fr.json new file mode 100644 index 0000000000000000000000000000000000000000..bcd94c29140473a080536c4e766d3cd5fd834220 --- /dev/null +++ b/src/core/helpers/i18n/fr.json @@ -0,0 +1,9 @@ +{ + "uni.showActionSheet.cancel": "Annuler", + "uni.showToast.unpaired": "Veuillez noter que showToast doit être associé à hideToast", + "uni.showLoading.unpaired": "Veuillez noter que showLoading doit être associé à hideLoading", + "uni.showModal.cancel": "Annuler", + "uni.showModal.confirm": "confirmer", + "uni.button.feedback.title": "retour d'information", + "uni.button.feedback.send": "envoyer" +} diff --git a/src/core/helpers/i18n/index.js b/src/core/helpers/i18n/index.js new file mode 100644 index 0000000000000000000000000000000000000000..3df1bded75006e0c9c05c7a42902d25af1107ffd --- /dev/null +++ b/src/core/helpers/i18n/index.js @@ -0,0 +1,66 @@ +import i18n from '@dcloudio/uni-i18n' + +import en from './en.json' +import es from './es.json' +import fr from './fr.json' +import zhHans from './zh-Hans.json' +import zhHant from './zh-Hant.json' + +const messages = { + en, + es, + fr, + 'zh-Hans': zhHans, + 'zh-Hant': zhHant +} + +const fallbackLocale = 'en' + +export function initI18n (locale, onChange) { + i18n.init({ + locale, + fallbackLocale, + messages + }) + if (onChange) { + i18n.watchLocale((newLocale, oldLocale) => { + onChange(newLocale, oldLocale) + }) + } +} + +function initLocaleWatcher (app) { + app.$i18n.vm.$watch('locale', (newLocale) => { + i18n.setLocale(newLocale) + }, { + immediate: true + }) +} + +export function t (key, values) { + if (__VIEW__) { + return i18n.t(key, values) + } + const app = getApp() + if (!app.$t) { + /* eslint-disable no-func-assign */ + t = function (key, values) { + return i18n.t(key, values) + } + } else { + initLocaleWatcher(app) + /* eslint-disable no-func-assign */ + t = function (key, values) { + const $i18n = app.$i18n + const silentTranslationWarn = $i18n.silentTranslationWarn + $i18n.silentTranslationWarn = true + const msg = app.$t(key, values) + $i18n.silentTranslationWarn = silentTranslationWarn + if (msg !== key) { + return msg + } + return i18n.t(key, values) + } + } + return t(key, values) +} diff --git a/src/core/helpers/i18n/zh-Hans.json b/src/core/helpers/i18n/zh-Hans.json new file mode 100644 index 0000000000000000000000000000000000000000..678b4378dd0d46f4fdaac73a650621f0ed6dedb7 --- /dev/null +++ b/src/core/helpers/i18n/zh-Hans.json @@ -0,0 +1,9 @@ +{ + "uni.showActionSheet.cancel": "取消", + "uni.showToast.unpaired": "请注意 showToast 与 hideToast 必须配对使用", + "uni.showLoading.unpaired": "请注意 showLoading 与 hideLoading 必须配对使用", + "uni.showModal.cancel": "取消", + "uni.showModal.confirm": "确认", + "uni.button.feedback.title": "问题反馈", + "uni.button.feedback.send": "发送" +} diff --git a/src/core/helpers/i18n/zh-Hant.json b/src/core/helpers/i18n/zh-Hant.json new file mode 100644 index 0000000000000000000000000000000000000000..dd20a4233ebd04f7ffe7c11c095c314ea7274922 --- /dev/null +++ b/src/core/helpers/i18n/zh-Hant.json @@ -0,0 +1,9 @@ +{ + "uni.showActionSheet.cancel": "取消", + "uni.showToast.unpaired": "請注意 showToast 與 hideToast 必須配對使用", + "uni.showLoading.unpaired": "請注意 showLoading 與 hideLoading 必須配對使用", + "uni.showModal.cancel": "取消", + "uni.showModal.confirm": "確認", + "uni.button.feedback.title": "問題反饋", + "uni.button.feedback.send": "發送" +} diff --git a/src/core/helpers/protocol/ui/popup.js b/src/core/helpers/protocol/ui/popup.js index b1ad96df3eb6c07733e746b01a9ef2e6b5e58ef1..0396fc3e8775c84cde24d53b104196254a20684c 100644 --- a/src/core/helpers/protocol/ui/popup.js +++ b/src/core/helpers/protocol/ui/popup.js @@ -1,3 +1,7 @@ +import { + t +} from 'uni-core/helpers/i18n' + import getRealPath from 'uni-platform/helpers/get-real-path' export const showModal = { @@ -15,7 +19,9 @@ export const showModal = { }, cancelText: { type: String, - default: '取消' + default () { + return t('uni.showModal.cancel') + } }, cancelColor: { type: String, @@ -23,7 +29,9 @@ export const showModal = { }, confirmText: { type: String, - default: '确定' + default () { + return t('uni.showModal.confirm') + } }, confirmColor: { type: String, @@ -114,4 +122,4 @@ export const showActionSheet = { popover: { type: Object } -} +} diff --git a/src/core/service/plugins/app/create-app.js b/src/core/service/plugins/app/create-app.js index e31a63ae66650be22148dfbb591bf982c0824a69..5e3b8c9f417dd63e315a466815b73759ec9e2a7c 100644 --- a/src/core/service/plugins/app/create-app.js +++ b/src/core/service/plugins/app/create-app.js @@ -1,3 +1,8 @@ +import { + t, + initI18n +} from 'uni-core/helpers/i18n' + import initRouterGuard from './router-guard' let appVm = false @@ -23,7 +28,8 @@ export function getCurrentPages (isAll = false, ignoreError = false) { childrenVm = layoutVm } childrenVm.$children.forEach(vm => { - if (tabBarVm !== vm && vm.$children.length && vm.$children[0].$options.name === 'Page' && vm.$children[0].$slots.page) { + if (tabBarVm !== vm && vm.$children.length && vm.$children[0].$options.name === 'Page' && vm.$children[0].$slots + .page) { // vm.$children[0]=Page->PageBody->RealPage const pageBody = vm.$children[0].$children.find(vm => vm.$options.name === 'PageBody') const pageVm = pageBody && pageBody.$children.find(vm => !!vm.$page) @@ -64,8 +70,11 @@ export function getCurrentPages (isAll = false, ignoreError = false) { export default function createApp (vm, routes) { appVm = vm + appVm.$$t = t appVm.globalData = appVm.$options.globalData || {} + // h5 + initI18n(navigator.userLanguage || navigator.language) // initEvents(appVm) initRouterGuard(appVm, routes) -} +} diff --git a/src/core/view/components/button/index.vue b/src/core/view/components/button/index.vue index cfea188fe71e9af433cca2970e86118d9068f996..c94b0c40ce00c9968655165169ec1e2b63847ffd 100644 --- a/src/core/view/components/button/index.vue +++ b/src/core/view/components/button/index.vue @@ -1,5 +1,12 @@ + .button-hover[type="warn"][plain] { + color: rgba(230, 67, 64, 0.6); + border-color: rgba(230, 67, 64, 0.6); + background-color: transparent; + } + diff --git a/src/core/view/mixins/i18n.js b/src/core/view/mixins/i18n.js new file mode 100644 index 0000000000000000000000000000000000000000..0b03f271d55a13daf9de49590654af5af106df80 --- /dev/null +++ b/src/core/view/mixins/i18n.js @@ -0,0 +1,20 @@ +import i18n from '@dcloudio/uni-i18n' +import { + t +} from 'uni-core/helpers/i18n' + +export default { + beforeCreate () { + const unwatch = i18n.watchLocale(() => { + this.$forceUpdate() + }) + this.$once('hook:beforeDestroy', function () { + unwatch() + }) + }, + methods: { + $$t (key, values) { + return t(key, values) + } + } +} diff --git a/src/platforms/app-plus/service/api/ui/popup.js b/src/platforms/app-plus/service/api/ui/popup.js index 0f756553e3e568fae7becb07d429d153e41b800b..6755bdfd9af03af9ad45cf34fb0227515f7be612 100644 --- a/src/platforms/app-plus/service/api/ui/popup.js +++ b/src/platforms/app-plus/service/api/ui/popup.js @@ -11,7 +11,9 @@ let toastType let timeout export function showLoading (args) { - return callApiSync(showToast, Object.assign({}, args, { type: 'loading' }), 'showToast', 'showLoading') + return callApiSync(showToast, Object.assign({}, args, { + type: 'loading' + }), 'showToast', 'showLoading') } export function hideLoading () { @@ -111,10 +113,10 @@ export function showModal ({ title = '', content = '', showCancel = true, - cancelText = '取消', - cancelColor = '#000000', - confirmText = '确定', - confirmColor = '#3CC51F' + cancelText, + cancelColor, + confirmText, + confirmColor } = {}, callbackId) { content = content || ' ' plus.nativeUI.confirm(content, (e) => { @@ -151,7 +153,9 @@ export function showActionSheet ({ options.cancel = '' - plus.nativeUI.actionSheet(Object.assign(options, { popover }), (e) => { + plus.nativeUI.actionSheet(Object.assign(options, { + popover + }), (e) => { if (e.index > 0) { invoke(callbackId, { errMsg: 'showActionSheet:ok', @@ -163,4 +167,4 @@ export function showActionSheet ({ }) } }) -} +} diff --git a/src/platforms/app-plus/service/framework/app.js b/src/platforms/app-plus/service/framework/app.js index d5d5fa979a8065f5f4f50146d460453e257eb7f9..1f87035d25f9127c91051aa00da6dad6b76b1868 100644 --- a/src/platforms/app-plus/service/framework/app.js +++ b/src/platforms/app-plus/service/framework/app.js @@ -1,3 +1,7 @@ +import { + t, + initI18n +} from 'uni-core/helpers/i18n' import { callAppHook } from 'uni-core/service/plugins/util' @@ -206,7 +210,7 @@ export function registerApp (appVm) { if (process.env.NODE_ENV !== 'production') { console.log('[uni-app] registerApp') } - + appVm.$$t = t appCtx = appVm appCtx.$vm = appVm @@ -216,6 +220,9 @@ export function registerApp (appVm) { // merge globalData appCtx.globalData = Object.assign(globalData, appCtx.globalData) + // TODO + initI18n(plus.os.language) + initOn(UniServiceJSBridge.on, { getApp, getCurrentPages @@ -237,4 +244,4 @@ export function registerApp (appVm) { __uniConfig.ready = true process.env.NODE_ENV !== 'production' && perf('registerApp') -} +} diff --git a/src/platforms/app-plus/service/framework/plugins/lifecycle.js b/src/platforms/app-plus/service/framework/plugins/lifecycle.js index adcd26df17c08a363498e0cbf8f7e7e0d148b48d..848d2feb3c3cc4933fa5696fbe39c91fecf91565 100644 --- a/src/platforms/app-plus/service/framework/plugins/lifecycle.js +++ b/src/platforms/app-plus/service/framework/plugins/lifecycle.js @@ -25,11 +25,15 @@ import { } from '../../constants' -import { NAVBAR_HEIGHT } from 'uni-helpers/constants' +import { + NAVBAR_HEIGHT +} from 'uni-helpers/constants' import tabBar from '../tab-bar' -import { getStatusbarHeight } from 'uni-platform/helpers/status-bar' +import { + getStatusbarHeight +} from 'uni-platform/helpers/status-bar' import { preloadSubPackages @@ -51,6 +55,7 @@ function parsePageCreateOptions (vm, route) { return { version: VD_SYNC_VERSION, + locale: plus.os.language, // TODO disableScroll, onPageScroll, onPageReachBottom, @@ -83,6 +88,10 @@ export function initLifecycle (Vue) { } if (this.mpType === 'page') { + const app = getApp() + if (app.$vm && app.$vm.$i18n) { + this._i18n = app.$vm.$i18n + } this.$scope = this.$options.pageInstance this.$scope.$vm = this delete this.$options.pageInstance @@ -112,4 +121,4 @@ export function initLifecycle (Vue) { } } }) -} +} diff --git a/src/platforms/app-plus/view/bridge/subscribe/index.js b/src/platforms/app-plus/view/bridge/subscribe/index.js index 79bd557fab4c31e64292f8ef16d0ec743a3d83a4..5566dfe76dddea4787f762a2e1627c0c3c67537a 100644 --- a/src/platforms/app-plus/view/bridge/subscribe/index.js +++ b/src/platforms/app-plus/view/bridge/subscribe/index.js @@ -2,6 +2,10 @@ import { supportsPassive } from 'uni-shared' +import { + initI18n +} from 'uni-core/helpers/i18n' + import { disableScroll as disableScrollListener, createScrollListener @@ -27,10 +31,10 @@ function onCssVar ({ global.__WINDOW_TOP = windowTop global.__WINDOW_BOTTOM = windowBottom if (uni.canIUse('css.var')) { - const style = document.documentElement.style - // TODO - style.setProperty('--window-left', '0px') - style.setProperty('--window-right', '0px') + const style = document.documentElement.style + // TODO + style.setProperty('--window-left', '0px') + style.setProperty('--window-right', '0px') style.setProperty('--window-top', windowTop + 'px') style.setProperty('--window-bottom', windowBottom + 'px') @@ -44,6 +48,7 @@ function onCssVar ({ } function onPageCreate ({ + locale, statusbarHeight, windowTop, windowBottom, @@ -51,7 +56,9 @@ function onPageCreate ({ onPageScroll, onPageReachBottom, onReachBottomDistance -}, pageId) { +}, pageId) { + initI18n(locale) + onCssVar({ statusbarHeight, windowTop, @@ -78,4 +85,4 @@ function onWebviewReady () { // service 主动发起检测 export default function initSubscribe (subscribe) { subscribe(WEBVIEW_READY, onWebviewReady) subscribe(ON_PAGE_CREATE, onPageCreate) -} +} diff --git a/src/platforms/h5/components/app/popup/actionSheet.vue b/src/platforms/h5/components/app/popup/actionSheet.vue index 1c61fc34a5909c3dc76ea47d611e491394f3b295..33b67d926d8806cb1c4e8596418ad2d4ddfefa6c 100644 --- a/src/platforms/h5/components/app/popup/actionSheet.vue +++ b/src/platforms/h5/components/app/popup/actionSheet.vue @@ -53,7 +53,7 @@ class="uni-actionsheet__cell" @click="_close(-1)" > - 取消 + {{ $$t('uni.showActionSheet.cancel') }}
@@ -66,7 +66,8 @@