From dbbc633989919a99e6c0cdf2564a6cd51497b55e Mon Sep 17 00:00:00 2001 From: kazuya kawaguchi Date: Wed, 1 Jan 2025 00:03:40 +0900 Subject: [PATCH] fix: vue-i18n v8 EOL (#2060) * fix: vue-i18n v8 eol * fix: update lifecycle figure --- README.md | 13 +- .../.vuepress/components/sponsor-button.vue | 23 - docs-old/.vuepress/config.js | 305 ----- .../.vuepress/public/patrons/babeledit.png | Bin 6976 -> 0 bytes docs-old/.vuepress/public/patrons/locize.png | Bin 2601 -> 0 bytes .../.vuepress/public/patrons/sendcloud.png | Bin 38600 -> 0 bytes .../.vuepress/public/patrons/sendcloud.svg | 50 - .../public/patrons/zenarchitects.png | Bin 7127 -> 0 bytes docs-old/.vuepress/public/vue-i18n-logo.png | Bin 15042 -> 0 bytes docs-old/README.md | 92 -- docs-old/api/README.md | 917 ------------- docs-old/guide/component.md | 153 --- docs-old/guide/datetime.md | 77 -- docs-old/guide/directive.md | 182 --- docs-old/guide/fallback.md | 141 -- docs-old/guide/formatting.md | 205 --- docs-old/guide/hot-reload.md | 99 -- docs-old/guide/interpolation.md | 272 ---- docs-old/guide/lazy-loading.md | 85 -- docs-old/guide/locale.md | 56 - docs-old/guide/messages.md | 292 ---- docs-old/guide/number.md | 133 -- docs-old/guide/pluralization.md | 168 --- docs-old/guide/sfc.md | 400 ------ docs-old/guide/tooling.md | 72 - docs-old/installation.md | 86 -- docs-old/introduction.md | 93 -- docs-old/pt/README.md | 76 -- docs-old/pt/api/README.md | 924 ------------- docs-old/pt/guide/component.md | 152 --- docs-old/pt/guide/datetime.md | 77 -- docs-old/pt/guide/directive.md | 181 --- docs-old/pt/guide/fallback.md | 149 --- docs-old/pt/guide/formatting.md | 227 ---- docs-old/pt/guide/hot-reload.md | 99 -- docs-old/pt/guide/interpolation.md | 285 ---- docs-old/pt/guide/lazy-loading.md | 85 -- docs-old/pt/guide/locale.md | 54 - docs-old/pt/guide/messages.md | 319 ----- docs-old/pt/guide/number.md | 142 -- docs-old/pt/guide/pluralization.md | 174 --- docs-old/pt/guide/sfc.md | 410 ------ docs-old/pt/guide/tooling.md | 72 - docs-old/pt/installation.md | 85 -- docs-old/pt/introduction.md | 80 -- docs-old/pt/started.md | 62 - docs-old/ru/README.md | 74 - docs-old/ru/api/README.md | 922 ------------- docs-old/ru/guide/component.md | 152 --- docs-old/ru/guide/datetime.md | 77 -- docs-old/ru/guide/directive.md | 181 --- docs-old/ru/guide/fallback.md | 145 -- docs-old/ru/guide/formatting.md | 227 ---- docs-old/ru/guide/hot-reload.md | 99 -- docs-old/ru/guide/interpolation.md | 275 ---- docs-old/ru/guide/lazy-loading.md | 85 -- docs-old/ru/guide/locale.md | 54 - docs-old/ru/guide/messages.md | 318 ----- docs-old/ru/guide/number.md | 142 -- docs-old/ru/guide/pluralization.md | 174 --- docs-old/ru/guide/sfc.md | 408 ------ docs-old/ru/guide/tooling.md | 72 - docs-old/ru/installation.md | 85 -- docs-old/ru/introduction.md | 78 -- docs-old/ru/started.md | 61 - docs-old/started.md | 61 - docs-old/zh/README.md | 77 -- docs-old/zh/api/README.md | 701 ---------- docs-old/zh/guide/component.md | 151 --- docs-old/zh/guide/datetime.md | 77 -- docs-old/zh/guide/directive.md | 181 --- docs-old/zh/guide/fallback.md | 111 -- docs-old/zh/guide/formatting.md | 200 --- docs-old/zh/guide/hot-reload.md | 102 -- docs-old/zh/guide/interpolation.md | 183 --- docs-old/zh/guide/lazy-loading.md | 85 -- docs-old/zh/guide/locale.md | 55 - docs-old/zh/guide/messages.md | 290 ---- docs-old/zh/guide/number.md | 133 -- docs-old/zh/guide/pluralization.md | 166 --- docs-old/zh/guide/sfc.md | 397 ------ docs-old/zh/guide/tooling.md | 67 - docs-old/zh/installation.md | 66 - docs-old/zh/introduction.md | 79 -- docs-old/zh/started.md | 60 - docs/.vitepress/config.mts | 8 +- docs/guide/maintenance.md | 5 +- docs/guide/v8-docs.md | 22 - docs/public/lifecycle2025-1.excalidraw | 1189 +++++++++++++++++ docs/public/lifecycle2025-1.png | Bin 0 -> 147298 bytes docs/public/lifecycle2025-1.svg | 10 + 91 files changed, 1209 insertions(+), 14463 deletions(-) delete mode 100644 docs-old/.vuepress/components/sponsor-button.vue delete mode 100644 docs-old/.vuepress/config.js delete mode 100644 docs-old/.vuepress/public/patrons/babeledit.png delete mode 100644 docs-old/.vuepress/public/patrons/locize.png delete mode 100644 docs-old/.vuepress/public/patrons/sendcloud.png delete mode 100644 docs-old/.vuepress/public/patrons/sendcloud.svg delete mode 100644 docs-old/.vuepress/public/patrons/zenarchitects.png delete mode 100644 docs-old/.vuepress/public/vue-i18n-logo.png delete mode 100644 docs-old/README.md delete mode 100644 docs-old/api/README.md delete mode 100644 docs-old/guide/component.md delete mode 100644 docs-old/guide/datetime.md delete mode 100644 docs-old/guide/directive.md delete mode 100644 docs-old/guide/fallback.md delete mode 100644 docs-old/guide/formatting.md delete mode 100644 docs-old/guide/hot-reload.md delete mode 100644 docs-old/guide/interpolation.md delete mode 100644 docs-old/guide/lazy-loading.md delete mode 100644 docs-old/guide/locale.md delete mode 100644 docs-old/guide/messages.md delete mode 100644 docs-old/guide/number.md delete mode 100644 docs-old/guide/pluralization.md delete mode 100644 docs-old/guide/sfc.md delete mode 100644 docs-old/guide/tooling.md delete mode 100644 docs-old/installation.md delete mode 100644 docs-old/introduction.md delete mode 100644 docs-old/pt/README.md delete mode 100644 docs-old/pt/api/README.md delete mode 100644 docs-old/pt/guide/component.md delete mode 100644 docs-old/pt/guide/datetime.md delete mode 100644 docs-old/pt/guide/directive.md delete mode 100644 docs-old/pt/guide/fallback.md delete mode 100644 docs-old/pt/guide/formatting.md delete mode 100644 docs-old/pt/guide/hot-reload.md delete mode 100644 docs-old/pt/guide/interpolation.md delete mode 100644 docs-old/pt/guide/lazy-loading.md delete mode 100644 docs-old/pt/guide/locale.md delete mode 100644 docs-old/pt/guide/messages.md delete mode 100644 docs-old/pt/guide/number.md delete mode 100644 docs-old/pt/guide/pluralization.md delete mode 100644 docs-old/pt/guide/sfc.md delete mode 100644 docs-old/pt/guide/tooling.md delete mode 100644 docs-old/pt/installation.md delete mode 100644 docs-old/pt/introduction.md delete mode 100644 docs-old/pt/started.md delete mode 100644 docs-old/ru/README.md delete mode 100644 docs-old/ru/api/README.md delete mode 100644 docs-old/ru/guide/component.md delete mode 100644 docs-old/ru/guide/datetime.md delete mode 100644 docs-old/ru/guide/directive.md delete mode 100644 docs-old/ru/guide/fallback.md delete mode 100644 docs-old/ru/guide/formatting.md delete mode 100644 docs-old/ru/guide/hot-reload.md delete mode 100644 docs-old/ru/guide/interpolation.md delete mode 100644 docs-old/ru/guide/lazy-loading.md delete mode 100644 docs-old/ru/guide/locale.md delete mode 100644 docs-old/ru/guide/messages.md delete mode 100644 docs-old/ru/guide/number.md delete mode 100644 docs-old/ru/guide/pluralization.md delete mode 100644 docs-old/ru/guide/sfc.md delete mode 100644 docs-old/ru/guide/tooling.md delete mode 100644 docs-old/ru/installation.md delete mode 100644 docs-old/ru/introduction.md delete mode 100644 docs-old/ru/started.md delete mode 100644 docs-old/started.md delete mode 100644 docs-old/zh/README.md delete mode 100755 docs-old/zh/api/README.md delete mode 100644 docs-old/zh/guide/component.md delete mode 100644 docs-old/zh/guide/datetime.md delete mode 100644 docs-old/zh/guide/directive.md delete mode 100644 docs-old/zh/guide/fallback.md delete mode 100644 docs-old/zh/guide/formatting.md delete mode 100644 docs-old/zh/guide/hot-reload.md delete mode 100644 docs-old/zh/guide/interpolation.md delete mode 100644 docs-old/zh/guide/lazy-loading.md delete mode 100644 docs-old/zh/guide/locale.md delete mode 100644 docs-old/zh/guide/messages.md delete mode 100644 docs-old/zh/guide/number.md delete mode 100644 docs-old/zh/guide/pluralization.md delete mode 100644 docs-old/zh/guide/sfc.md delete mode 100644 docs-old/zh/guide/tooling.md delete mode 100644 docs-old/zh/installation.md delete mode 100644 docs-old/zh/introduction.md delete mode 100644 docs-old/zh/started.md delete mode 100644 docs/guide/v8-docs.md create mode 100644 docs/public/lifecycle2025-1.excalidraw create mode 100644 docs/public/lifecycle2025-1.png create mode 100644 docs/public/lifecycle2025-1.svg diff --git a/README.md b/README.md index fe7a0c032..9fd125a44 100644 --- a/README.md +++ b/README.md @@ -103,25 +103,22 @@ Vue I18n is part of the Vue Ecosystem and Intlify Project is an open source proj
## Status: [![CI](https://github.com/intlify/vue-i18n/actions/workflows/ci.yml/badge.svg)](https://github.com/intlify/vue-i18n/actions/workflows/ci.yml) -- v10: stable (About maintenance status, see the [here](https://vue-i18n.intlify.dev/guide/maintenance.html)) +- v11: stable (About maintenance status, see the [here](https://vue-i18n.intlify.dev/guide/maintenance.html)) - [Documentation](https://vue-i18n.intlify.dev/) -- If you use Vue I18n v8 for Vue 2, see this [repository](https://github.com/kazupon/vue-i18n) ## Quickstart -- Via CDN: `` +- Via CDN: `` - In-browser playground on [CodeSandbox](https://codesandbox.io/s/vue-i18n-9-template-h28c0) - Add it to an existing Vue Project: ```bash - npm install vue-i18n@9 + npm install vue-i18n@11 ``` -## Changes from Vue I18n v8 +## Vue I18n v8 -Please consult the [Migration Guide](https://vue-i18n.intlify.dev/guide/migration/breaking.html). +Vue I18n v8 has reached EOL and is no longer actively maintained. Upgrade to Vue I18n v9 or later. -## 🙋‍♂️ About support for v9 and earlier -- v7 and v8: we will follow Vue v2 maintenance lifespan ## 🍭 Examples diff --git a/docs-old/.vuepress/components/sponsor-button.vue b/docs-old/.vuepress/components/sponsor-button.vue deleted file mode 100644 index 39dc26c1a..000000000 --- a/docs-old/.vuepress/components/sponsor-button.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - - - diff --git a/docs-old/.vuepress/config.js b/docs-old/.vuepress/config.js deleted file mode 100644 index fdd176c50..000000000 --- a/docs-old/.vuepress/config.js +++ /dev/null @@ -1,305 +0,0 @@ -module.exports = { - base: '/vue-i18n/', - locales: { - '/': { - lang: 'en-US', - title: 'Vue I18n', - description: 'Vue I18n is internationalization plugin for Vue.js' - }, - '/zh/': { - lang: 'zh-CN', - title: 'Vue I18n', - description: 'Vue I18n 是 Vue.js 的国际化插件' - }, - '/ru/': { - lang: 'ru-RU', - title: 'Vue I18n', - description: 'Vue I18n — плагин для интернационализации во Vue.js' - } - }, - head: [['meta', { name: 'theme-color', content: '#3eaf7c' }]], - serviceWorker: false, - themeConfig: { - repo: 'kazupon/vue-i18n', - editLinks: true, - sidebarDepth: 3, - docsDir: 'vuepress', - locales: { - '/': { - label: 'English', - selectText: 'Languages', - editLinkText: 'Edit this page on GitHub', - lastUpdated: 'Last Updated', - nav: [ - { - text: 'Guide', - link: '/guide/formatting' - }, - { - text: 'API', - link: '/api/' - }, - { - text: 'Ecosystem', - items: [ - { - text: 'Official Tooling', - items: [ - { - text: 'Vue CLI Plugin', - link: 'https://github.com/kazupon/vue-cli-plugin-i18n' - }, - { - text: 'Webpack Loader', - link: 'https://github.com/kazupon/vue-i18n-loader' - }, - { - text: 'ESLint Plugin', - link: 'https://intlify.github.io/eslint-plugin-vue-i18n/' - }, - { - text: 'Extensions', - link: 'https://github.com/kazupon/vue-i18n-extensions' - } - ] - }, - { - text: '3rd Party Tooling', - items: [ - { - text: 'BabelEdit', - link: 'https://www.codeandweb.com/babeledit?utm_campaign=vue-i18n-2019-01' - }, - { - text: 'i18n Ally', - link: 'https://marketplace.visualstudio.com/items?itemName=antfu.i18n-ally' - } - ] - } - ] - }, - { - text: 'Patreon', - link: 'https://www.patreon.com/kazupon' - }, - { - text: 'Release Notes', - link: 'https://github.com/kazupon/vue-i18n/releases' - } - ], - sidebar: [ - '/introduction', - '/started', - '/installation', - { - title: 'Guide', - collapsable: false, - children: [ - '/guide/formatting', - '/guide/pluralization', - '/guide/datetime', - '/guide/number', - '/guide/messages', - '/guide/fallback', - '/guide/component', - '/guide/directive', - '/guide/interpolation', - '/guide/sfc', - '/guide/hot-reload', - '/guide/locale', - '/guide/lazy-loading', - '/guide/tooling' - ] - }, - { - title: 'Legacy', - collapsable: false, - children: ['/legacy/', '/legacy/v5'] - } - ] - }, - '/zh/': { - label: '简体中文', - selectText: '选择语言', - editLinkText: '在 GitHub 上编辑此页', - lastUpdated: '最近一次更新', - nav: [ - { - text: '指南', - link: '/zh/guide/formatting' - }, - { - text: 'API', - link: '/zh/api/' - }, - { - text: '生态', - items: [ - { - text: '官方工具', - items: [ - { - text: '脚手架插件', - link: 'https://github.com/kazupon/vue-cli-plugin-i18n' - }, - { - text: 'Webpack Loader', - link: 'https://github.com/kazupon/vue-i18n-loader' - }, - { - text: 'ESLint 插件', - link: 'https://intlify.github.io/eslint-plugin-vue-i18n/' - }, - { - text: '扩展', - link: 'https://github.com/kazupon/vue-i18n-extensions' - } - ] - }, - { - text: '翻译工具', - items: [ - { - text: 'BabelEdit', - link: 'https://www.codeandweb.com/babeledit?utm_campaign=vue-i18n-2019-01' - } - ] - } - ] - }, - { - text: '赞助', - link: 'https://www.patreon.com/kazupon' - }, - { - text: '发布日志', - link: 'https://github.com/kazupon/vue-i18n/releases' - } - ], - sidebar: [ - '/zh/introduction', - '/zh/started', - '/zh/installation', - { - title: 'Guide', - collapsable: false, - children: [ - '/zh/guide/formatting', - '/zh/guide/pluralization', - '/zh/guide/datetime', - '/zh/guide/number', - '/zh/guide/messages', - '/zh/guide/fallback', - '/zh/guide/component', - '/zh/guide/directive', - '/zh/guide/interpolation', - '/zh/guide/sfc', - '/zh/guide/hot-reload', - '/zh/guide/locale', - '/zh/guide/lazy-loading', - '/zh/guide/tooling' - ] - }, - { - title: 'Legacy', - collapsable: false, - children: ['/zh/legacy/', '/zh/legacy/v5'] - } - ] - }, - '/ru/': { - label: 'Русский', - selectText: 'Переводы', - editLinkText: 'Изменить эту страницу на GitHub', - lastUpdated: 'Последнее обновление', - nav: [ - { - text: 'Руководство', - link: '/ru/guide/formatting' - }, - { - text: 'Справочник API', - link: '/ru/api/' - }, - { - text: 'Экосистема', - items: [ - { - text: 'Оф. инструментарий', - items: [ - { - text: 'Плагин для Vue CLI', - link: 'https://github.com/kazupon/vue-cli-plugin-i18n' - }, - { - text: 'Загрузчик Webpack', - link: 'https://github.com/kazupon/vue-i18n-loader' - }, - { - text: 'Плагин для ESLint', - link: 'https://intlify.github.io/eslint-plugin-vue-i18n/' - }, - { - text: 'Расширения', - link: 'https://github.com/kazupon/vue-i18n-extensions' - } - ] - }, - { - text: 'Сторонние разработки', - items: [ - { - text: 'BabelEdit', - link: 'https://www.codeandweb.com/babeledit?utm_campaign=vue-i18n-2019-01' - }, - { - text: 'i18n Ally', - link: 'https://marketplace.visualstudio.com/items?itemName=antfu.i18n-ally' - } - ] - } - ] - }, - { - text: 'Patreon', - link: 'https://www.patreon.com/kazupon' - }, - { - text: 'История изменений', - link: 'https://github.com/kazupon/vue-i18n/releases' - } - ], - sidebar: [ - '/ru/introduction', - '/ru/started', - '/ru/installation', - { - title: 'Руководство', - collapsable: false, - children: [ - '/ru/guide/formatting', - '/ru/guide/pluralization', - '/ru/guide/datetime', - '/ru/guide/number', - '/ru/guide/messages', - '/ru/guide/fallback', - '/ru/guide/component', - '/ru/guide/directive', - '/ru/guide/interpolation', - '/ru/guide/sfc', - '/ru/guide/hot-reload', - '/ru/guide/locale', - '/ru/guide/lazy-loading', - '/ru/guide/tooling' - ] - }, - { - title: 'Устаревшие версии', - collapsable: false, - children: ['/ru/legacy/', '/ru/legacy/v5'] - } - ] - } - } - } -} diff --git a/docs-old/.vuepress/public/patrons/babeledit.png b/docs-old/.vuepress/public/patrons/babeledit.png deleted file mode 100644 index 13e250d8a0864d195d5093335e826bc68c0d9657..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6976 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 bm%%KeJlkK49&!MiF_40+s!X+%S=j#oL@NxC diff --git a/docs-old/.vuepress/public/patrons/locize.png b/docs-old/.vuepress/public/patrons/locize.png deleted file mode 100644 index f7008dd7fd8c71abd037bce907509d60f9b6f446..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2601 zcmb7-`#;kQ1AxD~*~OZSF6WRMY?|<+$QQ`X&N-q4wJQGP;Vxx`Rz043^$-eCG9hy!=-0 z*N9jAN~W`J;lNT&MBmky(}ISm>zO5QmnRV-VJG%pM3zqFw?9!9oEt9Kcneb&DUr>FVxo zKiJtb@VN9Cq(R~@OE_+1bP|Tdn2Td4=NhIeHN_|X-m^qnnO~cSs0qH$k2wprjv$bm zb6D-c89D%ltvah#B3xORNaXC07DWG%q55_d9?$Bfy=Gzn3RwsO7V_dcqA&xl6{I^3 zTRiH1`&vadGD5|y!+=1&ps79ey48_@hi(m5?-ov@Lnv-^?K)(o$Ms~&DxjxH)gFO z{7n4XOr|~!V?IpO!iw$i7Wki!FrT_U)0Mo3HDm|;4cG0aMIM5iGfLPThP1S9Yc9RW z0!FFK!t~9w7VSaUpR|gfY&KG)&g>6&3UfCTwuaw0)#iiVCkAFh{!?`m%4(dmYr8hj za))wW5AmjS4C=;+dv)tr`DQRIIGny`eXlFVM(q-eJI6GXxQ?kF3`lhfyXC5fT4i#% zeWA0n8EZ@IqT8}{yz>mdyxRr$_2Zctkn&>VR;UPzFR-&Z;qQkw(=D|&gUL~qOuVYW zgIPKpQo>`B*_rfv8lf^II8rWtR%aH=n~ONYr+`pE1C&iY$n*?&9Od_#gh}X82|~Y; z=j{d16tZlJns&!yoS9$AWo-D=As_-PwnP_I=()~bx=>@wrd1&U`h2xAaY8z@L3_Ei zM4~u9u<2R5mY!A(rfLOUkH>ofIOa&~S;E2YRSAzWn^jDm8_GIx?W885PInR-Q{G75 zJb;1asgS7_#;nyGJ)1)D+HbrSf#hZZQ6GNif?)_y^AxlKs)i?thLYFxlF2C{RY#iNXv!*zV{CQ+pyFTeynwHJhy-bc~Tr2 zV0Qf13x?sfsY)Yfau>B4>!+7lkFqK;c58C9b|s$^2`2ZoQ^_15dlG*C$EN_VD{A9- z{1&YQ9oz@PY~d8)#0qDm z4p>$wN(WofEqWip6g}aImAbK+2Zma1}Qcv z#B`aD!8RDPfvSSjhIL~Gi0brcEur1Iw1$@E<2tx2vD(bkhmKOTjhRKHNZd!9!lpHk z3eX0sr*t{i<|2Y1=wzPqn|exhfpT^5VN;ZfJ>0NDiAu{!9g5gSiY#~ zI-=RRmMZu8042-P@CzAE%C+=^$hE$aJ}m)pm_?F`{qRJO5Yp8-ihCD(kV1ZCnOOzmrYQlv(>Q71)igF7d_AQX#2>;etKws9FdpR zP%c#r9b_R&!{B0k-uh&>KJ(%`+zS-T7Y_o+(tpH2cB08q%b^sn^+$4jrMA?bq4WsR z`k%xE4M3?32?!Q1cgOj!p{qO8GAoNo#JC@$cWzVQ6R>(;ENsLmMk z%}kK^cB0inK-!DZQTc7dgbtZji_*NJ^vYxvw6I@C;t9Fz>aqMf=@{>`{@H(}Bpw^V zuNXp8Q)QkRvWE*KA;n@i1gN2l=V{tSK_ruyguRSQgiB}Qif+PBM&$Gz^+DUV)bUY@ z+3OjlVr~STf|_$7hUGa?GgZmj9%WNiD!svsv@XYiy>$mL5RLE;lK5OeRM>J)#Wx}4 zN#gqlc!8XoO{8RCLwh}6R~sjZEUzufx4yeQNywpIhy+gS3>dqngaR<%YS{h zv18j>qqNMyPeBtiK;YKeJLi zlb6VjSuv9AY%EerQu{rqT_U@nwnGV$dH&94^_|%i&e@!Zr^ilZRFU2WX{D)vriQ9z*ru!u_%rz=jbv41neAmkQxA7^b)yrSAJ-a13qv*oc~2p<9N zE(;v)0**ljABc0a?di4^(7{KLz|@H0f#LN1ed7C1Pa~Kiw&FgZpURGnf?H+uo(lgv zK7+Efsmwa-Cj*fy$9)N7CFT=c)7>?0M)RDy%T~|X-S2k?nir@8Tm6x{|L`PQmh4=9 x4j1mOm%6kpdk*}3|8n<7Wk$=FK$q>06T2G?11+oJ1KU&EyPKeeH3|R@{}-?krGNkc diff --git a/docs-old/.vuepress/public/patrons/sendcloud.png b/docs-old/.vuepress/public/patrons/sendcloud.png deleted file mode 100644 index 1b536605c56eff88e98005a13f53387a6559f8aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38600 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 T)DiB1xtm_G{Iwi$^Zx$;cxHqc diff --git a/docs-old/.vuepress/public/patrons/sendcloud.svg b/docs-old/.vuepress/public/patrons/sendcloud.svg deleted file mode 100644 index 8be041559..000000000 --- a/docs-old/.vuepress/public/patrons/sendcloud.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/docs-old/.vuepress/public/patrons/zenarchitects.png b/docs-old/.vuepress/public/patrons/zenarchitects.png deleted file mode 100644 index 250b51618b978b4aaaff306b79b5e81ea23e5ca6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7127 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 AT>t<8 diff --git a/docs-old/.vuepress/public/vue-i18n-logo.png b/docs-old/.vuepress/public/vue-i18n-logo.png deleted file mode 100644 index 4fdeb1ffc811628d2c78e27931e706e07737fa53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15042 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≷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 KSdEB5(EkNOQe>zA diff --git a/docs-old/README.md b/docs-old/README.md deleted file mode 100644 index c5c80736a..000000000 --- a/docs-old/README.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -home: true -heroImage: ./vue-i18n-logo.png -actionText: Get Started → -actionLink: introduction.md -footer: MIT Licensed | Copyright © 2020 kazuya kawaguchi ---- - -
-

🥇 Gold Sponsors

- - Nuxt.js - -

🥈 Silver Sponsors

- - BabelEdit translation editor for apps (web apps) - -

🥉 Bronze Sponsors

- - zenarchitects - - - sendcloud - - - vuemastery - -
- -
- -
- -
-
-

Easy

-

You can introduce internationalization into your app with simple API

-
-
-

Powerful

-

In addition to simple translation, support localization such as pluralization, number, datetime ... etc

-
-
-

Component-oriented

-

You can manage locale messages on single file component

-
-
diff --git a/docs-old/api/README.md b/docs-old/api/README.md deleted file mode 100644 index 93074c784..000000000 --- a/docs-old/api/README.md +++ /dev/null @@ -1,917 +0,0 @@ ---- -sidebar: auto ---- - -# API references - -## Extension of Vue - -### Vue constructor options - -#### i18n - - * **Type:** `I18nOptions` - -Component based localization option. - - * **See also:** `VueI18n` class constructor options - -### Vue injected methods - -#### $t - - * **Arguments:** - - * `{Path} key`: required - * `{Locale} locale`: optional - * `{Array | Object} values`: optional - - * **Return:** `TranslateResult` - -Localize the locale message of `key`. Localize in preferentially component locale messages than global locale messages. If not specified component locale messages, localize with global locale messages. If you specified `locale`, localize the locale messages of `locale`. If you specified `key` of list / named formatting local messages, you must specify `values` too. For `values` more details see [Formatting](../guide/formatting.md). - -If default pluralization does not suit your needs, see [pluralization rules in constructor options](#pluralizationrules) and [custom pluralization](../guide/pluralization.md). - -:::danger Tip -Note that you need to guarantee this context equal to component instance in lifecycle methods (e.g. in `data` options, `const $t = this.$t.bind(this)`). -::: - -#### $tc - - * **Arguments:** - - * `{Path} key`: required - * `{number} choice`: optional, default 1 - * `{Locale} locale`: optional - * `{string | Array | Object} values`: optional - - * **Return:** `TranslateResult` - -Localize the locale message of `key` with pluralization. Localize in preferentially component locale messages than global locale messages. If not specified component locale messages, localize with global locale messages. If you specified `locale`, localize the locale messages of `locale`. If you will specify string value to `values`, localize the locale messages of value. If you will specify Array or Object value to `values`, you must specify with `values` of $t. - -:::danger Tip -Note that you need to guarantee this context equal to component instance in lifecycle methods (e.g. in `data` options, `const $tc = this.$tc.bind(this)`). -::: - -#### $te - - * **Arguments:** - - * `{Path} key`: required - * `{Locale} locale`: optional - - * **Return:** `boolean` - -Check whether key exists. In Vue instance, If not specified component locale messages, check with global locale messages. If you specified `locale`, check the locale messages of `locale`. - -:::danger Tip -Note that you need to guarantee this context equal to component instance in lifecycle methods (e.g. in `data` options, `const $te = this.$te.bind(this)`). -::: - -#### $d - -> :new: 7.0+ - - * **Arguments:** - - * `{number | Date} value`: required - * `{Path | Object} key`: optional - * `{Locale | Object} locale`: optional - - * **Return:** `DateTimeFormatResult` - -Localize the datetime of `value` with datetime format of `key`. The datetime format of `key` need to register to `dateTimeFormats` option of `VueI18n` class, and depend on `locale` option of `VueI18n` constructor. If you will specify `locale` argument, it will have priority over `locale` option of `VueI18n` constructor. - -If the datetime format of `key` not exist in `dateTimeFormats` option, fallback to depend on `fallbackLocale` option of `VueI18n` constructor. - -:::danger Tip -Note that you need to guarantee this context equal to component instance in lifecycle methods (e.g. in `data` options, `const $d = this.$d.bind(this)`). -::: - -#### $n - -> :new: 7.0+ - - * **Arguments:** - - * `{number} value`: required - * `{Path | Object} format`: optional - * `{Locale} locale`: optional - - * **Return:** `NumberFormatResult` - -Localize the number of `value` with number format of `format`. The number format of `format` need to register to `numberFormats` option of `VueI18n` class, and depend on `locale` option of `VueI18n` constructor. If you will specify `locale` argument, it will have priority over `locale` option of `VueI18n` constructor. - -If the number format of `format` not exist in `numberFormats` option, fallback to depend on `fallbackLocale` option of `VueI18n` constructor. - -If the second `format` argument specified as an object, it should have the following properties: - -* `key {Path}`: optional, number format -* `locale {Locale}`: optional, locale -* `compactDisplay {string}`: optional, number format option -* `currency {string}`: optional, number format option -* `currencyDisplay {string}`: optional, number format option -* `currencySign {string}`: optional, number format option -* `localeMatcher {string}`: optional, number format option -* `notation {string}`: optional, number format option -* `numberingSystem {string}`: optional, number format option -* `signDisplay {string}`: optional, number format option -* `style {string}`: optional, number format option -* `unit {string}`: optional, number format option -* `unitDisplay {string}`: optional, number format option -* `useGrouping {string}`: optional, number format option -* `minimumIntegerDigits {string}`: optional, number format option -* `minimumFractionDigits {string}`: optional, number format option -* `maximumFractionDigits {string}`: optional, number format option -* `minimumSignificantDigits {string}`: optional, number format option -* `maximumSignificantDigits {string}`: optional, number format option - -Any specified number format options will have priority over `numberFormats` of `VueI18n` constructor. - -:::danger Tip -Note that you need to guarantee this context equal to component instance in lifecycle methods (e.g. in `data` options, `const $n = this.$n.bind(this)`). -::: - -### Injected properties - -#### $i18n - - * **Type:** `I18n` - - * **Read only** - -Get a `VueI18n` instance. If you are specify. - -If you have specified an `i18n` option at component options, you will be able to get a `VueI18n` instance at the component, Otherwise, you will be able get root `VueI18n` instance. - -## `VueI18n` class - -`VueI18n` class implement `I18n` interface of [flowtype definitions](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -### Static properties - -#### version - - * **Type:** `string` - -vue-i18n version. - -#### availabilities - -> :new: 7.0+ - - * **Type:** `IntlAvailability` - -Whether the following internationalization features are available: - - * `{boolean} dateTimeFormat`: locale sensitive datetime formatting - - * `{boolean} numberFormat`: locale sensitive number formatting - -The above internationalization features are depends on [the browser environments](http://kangax.github.io/compat-table/esintl/), due to implement with ECMAScript Internationalization API (ECMA-402). - -### Constructor options - -You can specify the below some options of `I18nOptions` constructor options of [flowtype definitions](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -#### locale - - * **Type:** `Locale` - - * **Default:** `'en-US'` - -The locale of localization. If the locale contains a territory and a dialect, this locale contains an implicit fallback. - -#### fallbackLocale - - * **Type:** `FallbackLocale` - - * **Default:** `false` - -The locale of fallback localization. For more complex fallback definitions see [fallback](../guide/fallback.md). - -#### messages - - * **Type:** `LocaleMessages` - - * **Default:** `{}` - -The locale messages of localization. - -#### dateTimeFormats - -> :new: 7.0+ - - * **Type:** `DateTimeFormats` - - * **Default:** `{}` - -The datetime formats of localization. - - * **See also:** `DateTimeFormats` type of [flowtype definitions](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -#### numberFormats - -> :new: 7.0+ - - * **Type:** `NumberFormats` - - * **Default:** `{}` - -The number formats of localization. - - * **See also:** `NumberFormats` type of [flowtype definitions](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -#### availableLocales - -> :new: 8.9.0+ - - * **Type:** `Locale[]` - - * **Default:** `[]` - - * **Examples:** `["en", "ja"]` - -The list of available locales in `messages` in lexical order. - -#### formatter - - * **Type:** `Formatter` - - * **Default:** Built in formatter - -The formatter that implemented with `Formatter` interface. - -#### modifiers - -> :new: 8.15.0+ - - * **Type:** `Modifiers` - - * **Default:** `lower` and `upper` modifiers - -Modifiers functions for linked messages - -#### missing - - * **Type:** `MissingHandler` - - * **Default:** `null` - -A handler for localization missing. The handler gets called with the localization target locale, localization path key, the Vue instance and values. - -If missing handler is assigned, and occurred localization missing, it's not warned. - -#### fallbackRoot - - * **Type:** `Boolean` - - * **Default:** `true` - -In the component localization, whether to fall back to root level (global) localization when localization fails. - -If `false`, it's warned, and is returned the key. - -#### sync - - * **Type:** `Boolean` - - * **Default:** `true` - -Whether synchronize the root level locale to the component localization locale. - -If `false`, regardless of the root level locale, localize for each component locale. - -#### silentTranslationWarn - -> 6.1+, :up: 8.13 - - * **Type:** `Boolean | RegExp` - - * **Default:** `false` - -Whether suppress warnings outputted when localization fails. - -If `true`, suppress localization fail warnings. -If you use regular expression, you can suppress localization fail warnings that it match with translation `key` (e.g. `$t`). - -#### silentFallbackWarn - -> :new: 8.8+, :up: 8.13 - - * **Type:** `Boolean | RegExp` - * **Default:** `false` - -Whether suppress warnings when falling back to either `fallbackLocale` or `root`. - -If `true`, warnings will be generated only when no translation is available at all, and not for fallbacks. -If you use regular expression, you can suppress the fallback warnings that it match `key` (e.g. `$t`). - -#### pluralizationRules - -> 8.5+ - - * **Type:** `PluralizationRules` - - * **Default:** `{}` - - A set of rules for word pluralization in a following format: - ```js - { - // Key - locale for the rule to be applied to. - // Value - mapping function that maps a choice index from `$tc` to the actual choice of the plural word. (See getChoiceIndex for details) - 'pt': function(choice, choiceIndex) => Number/* index of the plural word */; - 'ru': function(choice, choiceIndex) => Number/* index of the plural word */; - 'en': function(choice, choiceIndex) => Number/* index of the plural word */; - 'jp': function(choice, choiceIndex) => Number/* index of the plural word */; - } - ``` - -#### preserveDirectiveContent - -> 8.7+ - - * **Type:** `Boolean` - - * **Default:** `false` - -Whether `v-t` directive's element should preserve `textContent` after directive is unbinded. - -#### warnHtmlInMessage - -> 8.11+ - - * **Type:** `WarnHtmlInMessageLevel` - - * **Default:** `off` - -Whether to allow the use locale messages of HTML formatting. See the `warnHtmlInMessage` property. - -:::danger Important!! -In next major version, `warnHtmlInMessage` option is `warn` as default. -::: - -#### sharedMessages - -> 8.12+ - - * **Type:** `LocaleMessages` - - * **Default:** `undefined` - -The shared locale messages of localization for components. More detail see [Component based localization](../guide/component.md#shared-locale-messages-for-components). - -#### postTranslation - -> 8.16+ - - * **Type:** `PostTranslationHandler` - - * **Default:** `null` - -A handler for post processing of translation. The handler gets after being called with the `$t`, `t`, `$tc`, and `tc`. - -This handler is useful if you want to filter on translated text such as space trimming. - -#### componentInstanceCreatedListener - -> 8.18+ - - * **Type:** `ComponentInstanceCreatedListener` - - * **Default:** `null` - -A handler for getting notified when component-local instance was created. The handler gets called with new and old (root) VueI18n instances. - -This handler is useful when extending the root VueI18n instance and wanting to also apply those extensions to component-local instance. - -#### escapeParameterHtml - -> 8.22+ - - * **Type:** `Boolean` - - * **Default:** `false` - -If `escapeParameterHtml` is configured as true then interpolation parameters are escaped before the message is translated. -This is useful when translation output is used in `v-html` and the translation resource contains html markup (e.g. `` -around a user provided value). This usage pattern mostly occurs when passing precomputed text strings into UI compontents. - -The escape process involves replacing the following symbols with their respective HTML character entities: `<`, `>`, `"`, `'`. - -Setting `escapeParameterHtml` as true should not break existing functionality but provides a safeguard against a subtle -type of XSS attack vectors. - -### Properties - -#### locale - - * **Type:** `Locale` - - * **Read/Write** - -The locale of localization. If the locale contains a territory and a dialect, this locale contains an implicit fallback. - -#### fallbackLocale - - * **Type:** `FallbackLocale` - - * **Read/Write** - -The locale of fallback localization. For more complex fallback definitions see [fallback](../guide/fallback.md). - -#### messages - - * **Type:** `LocaleMessages` - - * **Read only** - -The locale messages of localization. - -#### dateTimeFormats - -> :new: 7.0+ - - * **Type:** `DateTimeFormats` - - * **Read only** - -The datetime formats of localization. - -#### numberFormats - -> :new: 7.0+ - - * **Type:** `NumberFormats` - - * **Read only** - -The number formats of localization. - -#### missing - - * **Type:** `MissingHandler` - - * **Read/Write** - -A handler for localization missing. - -#### formatter - - * **Type:** `Formatter` - - * **Read/Write** - -The formatter that implemented with `Formatter` interface. - -#### silentTranslationWarn - -> 6.1+, :up: 8.13 - - * **Type:** `Boolean | RegExp` - - * **Read/Write** - -Whether suppress warnings outputted when localization fails. - -#### silentFallbackWarn - -> :new: 8.8+, :up: 8.13 - - * **Type:** `Boolean | RegExp` - - * **Read/Write** - -Whether suppress fallback warnings when localization fails. - -#### pluralizationRules - -> 8.5+ - - * **Type:** `PluralizationRules` - - * **Read/Write** - -A set of locale-dependent rules for word pluralization. - -#### preserveDirectiveContent - -> 8.7+ - - * **Type:** `Boolean` - - * **Read/Write** - -Whether `v-t` directive's element should preserve `textContent` after directive is unbinded. - -#### warnHtmlInMessage - -> 8.11+ - - * **Type:** `WarnHtmlInMessageLevel` - - * **Read/Write** - -Whether to allow the use locale messages of HTML formatting. - -If you set `warn` or` error`, will check the locale messages on the VueI18n instance. - -If you are specified `warn`, a warning will be output at console. - -If you are specified `error` will occurred an Error. - -In VueI18n instance, set the `off` as default. - -#### postTranslation - -> 8.16+ - - * **Type:** `PostTranslationHandler` - - * **Read/Write** - -A handler for post processing of translation. - -### Methods - -#### getChoiceIndex - - * **Arguments:** - - * `{number} choice` - * `{number} choicesLength` - - * **Return:** `finalChoice {number}` - -Get pluralization index for current pluralizing number and a given amount of choices. -Can be overridden through prototype mutation: - -```js -VueI18n.prototype.getChoiceIndex = /* custom implementation */ -``` - -However, for most usages [pluralizationRules constructor option](#pluralizationrules) should be enough. - -#### getLocaleMessage( locale ) - - * **Arguments:** - - * `{Locale} locale` - - * **Return:** `LocaleMessageObject` - -Get the locale message of locale. - -#### setLocaleMessage( locale, message ) - - * **Arguments:** - - * `{Locale} locale` - * `{LocaleMessageObject} message` - -Set the locale message of locale. - -:::tip NOTE -> 8.11+ - -If you set `warn` or` error` in the `warnHtmlInMessage` property, when this method is executed, it will check if HTML formatting is used for locale message. -::: - -#### mergeLocaleMessage( locale, message ) - -> 6.1+ - - * **Arguments:** - - * `{Locale} locale` - * `{LocaleMessageObject} message` - -Merge the registered locale messages with the locale message of locale. - -:::tip NOTE -> 8.11+ - -If you set `warn` or` error` in the `warnHtmlInMessage` property, when this method is executed, it will check if HTML formatting is used for locale message. -::: - -#### t( key, [locale], [values] ) - - * **Arguments:** - - * `{Path} key`: required - * `{Locale} locale`: optional - * `{Array | Object} values`: optional - - * **Return:** : `TranslateResult` - -This is the same as the `Function` returned with `$t` method. More detail see [$t](#t). - -#### tc( key, [choice], [values] ) - - * **Arguments:** - - * `{Path} key`: required - * `{number} choice`: optional, default `1` - * `{string | Array | Object} values`: optional - - * **Return:** `TranslateResult` - -This is the same as the `Function` returned `$tc` method. More detail see [$tc](#tc). - -#### te( key, [locale] ) - - * **Arguments:** - - * `{string} key`: required - * `{Locale} locale`: optional - - * **Return:** `boolean` - -Check whether key path exists in global locale message. If you specified `locale`, check the locale message of `locale`. - -#### getDateTimeFormat ( locale ) - -> :new: 7.0+ - - * **Arguments:** - - * `{Locale} locale` - - * **Return:** `DateTimeFormat` - -Get the datetime format of locale. - -#### setDateTimeFormat ( locale, format ) - -> :new: 7.0+ - - * **Arguments:** - - * `{Locale} locale` - * `{DateTimeFormat} format` - -Set the datetime format of locale. - -#### mergeDateTimeFormat ( locale, format ) - -> :new: 7.0+ - - * **Arguments:** - - * `{Locale} locale` - * `{DateTimeFormat} format` - -Merge the registered datetime formats with the datetime format of locale. - -#### d( value, [key], [locale] ) - -> :new: 7.0+ - - * **Arguments:** - - * `{number | Date} value`: required - * `{Path | Object} key`: optional - * `{Locale | Object} locale`: optional - - * **Return:** `DateTimeFormatResult` - -This is the same as `$d` method of Vue instance method. More detail see [$d](#d). - -#### getNumberFormat ( locale ) - -> :new: 7.0+ - - * **Arguments:** - - * `{Locale} locale` - - * **Return:** `NumberFormat` - -Get the number format of locale. - -#### setNumberFormat ( locale, format ) - -> :new: 7.0+ - - * **Arguments:** - - * `{Locale} locale` - * `{NumberFormat} format` - -Set the number format of locale. - -#### mergeNumberFormat ( locale, format ) - -> :new: 7.0+ - - * **Arguments:** - - * `{Locale} locale` - * `{NumberFormat} format` - -Merge the registered number formats with the number format of locale. - -#### n( value, [format], [locale] ) - -> :new: 7.0+ - - * **Arguments:** - - * `{number} value`: required - * `{Path | Object} format`: optional - * `{Locale} locale`: optional - - * **Return:** `NumberFormatResult` - -This is the same as `$n` method of Vue instance method. More detail see [$n](#n). - -## Directives - -> :new: 7.3+ - -### v-t - - * **Expects:** `string | Object` - - * **Modifiers:** - - * `.preserve`: (8.7.0+) preserves element `textContent` when directive is unbinded. - - * **Details:** - -Update the element `textContent` that localized with locale messages. You can use string syntax or object syntax. string syntax can be specified as a keypath of locale messages. If you can be used object syntax, you need to specify as the object key the following params: - - * `path`: required, key of locale messages - * `locale`: optional, locale - * `args`: optional, for list or named formatting - -:::tip NOTE -The element `textContent` will be cleared by default when `v-t` directive is unbinded. This might be undesirable situation when used inside [transitions](https://vuejs.org/v2/guide/transitions.html). To preserve `textContent` data after directive unbind use `.preserve` modifier or global [`preserveDirectiveContent` option](#preservedirectivecontent). -::: - - * **Examples:** - -```html - -

- - -

- - -

- - -

- - -

-``` - - * **See also:** [Custom directive localization](../guide/directive.md) - -## Components - -### i18n functional component - -> :new: 7.0+ - -#### Props: - - * `path {Path}`: required, keypath of locale messages - * `locale {Locale}`: optional, locale - * `tag {string | boolean | Object}`: optional, default `'span'` - * `places {Array | Object}`: optional (7.2+) - -:::danger Important!! -In next major version, `places` prop is deprecated. Please switch to slots syntax. -::: - -#### Usage: - -```html -
- - - {{ $t('tos') }} - - -
-``` -```js -const messages = { - en: { - tos: 'Term of Service', - term: 'I accept xxx {0}.' - }, - ja: { - tos: '利用規約', - term: '私は xxx の{0}に同意します。' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) -new Vue({ - i18n, - data: { - url: '/term' - } -}).$mount('#app') -``` - -#### See also: - -[Component interpolation](../guide/interpolation.md) - -### i18n-n functional component - -> :new: 8.10+ - -#### Props: - - * `value {number}`: required, number to format - * `format {string | NumberFormatOptions}`: optional, number format name or object with explicit format options - * `locale {Locale}`: optional, locale - * `tag {string | boolean | Object}`: optional, default `'span'` - -#### Usage: - -```html -
- - - {{ slotProps.currency }} - - -
-``` -```js -var numberFormats = { - 'en-US': { - currency: { - style: 'currency', currency: 'USD' - } - }, - 'ja-JP': { - currency: { - style: 'currency', currency: 'JPY' - } - } -} - -const i18n = new VueI18n({ - locale: 'en-US', - numberFormats -}) -new Vue({ - i18n, - data: { - money: 10234, - } -}).$mount('#app') -``` - -#### Scoped slots - -`` functional component can accept a number of named scoped slots. List of supported slot names is based on [`Intl.NumberFormat.formatToParts()` output types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat/formatToParts): - -* `currency` -* `decimal` -* `fraction` -* `group` -* `infinity` -* `integer` -* `literal` -* `minusSign` -* `nan` -* `plusSign` -* `percentSign` - -Each of these named scoped slots will accept three scope parameters: - -* `[slotName] {FormattedNumberPartType}`: parameter of the same name as actual slot name (like `integer`) -* `index {Number}`: index of the specific part in the array of number parts -* `parts {Array}`: array of all formatted number parts - -#### See also: - -[Number custom formatting](../guide/number.md#custom-formatting) - -## Special Attributes - -### place - -> :new: 7.2+ - -#### Expects: `{number | string}` - -Used on component interpolation to indicate which index of list formatting or key of named formatting. - -For detailed usage, see the guide section linked below. - -#### See also: - -[Component interpolation](../guide/interpolation.md) diff --git a/docs-old/guide/component.md b/docs-old/guide/component.md deleted file mode 100644 index ec0d7926f..000000000 --- a/docs-old/guide/component.md +++ /dev/null @@ -1,153 +0,0 @@ -# Component based localization - -In general, locale info (e.g. `locale`,`messages`, etc) is set as constructor option of `VueI18n` instance and it sets `i18n` option as root Vue instance. - -Therefore you can globally translate using `$t` or `$tc` in the root Vue instance and any composed component. You can also manage locale info for each component separately, which might be more convenient due to Vue components oriented design. - -Component based localization example: - -```js -// setup locale info for root Vue instance -const i18n = new VueI18n({ - locale: 'ja', - messages: { - en: { - message: { - hello: 'hello world', - greeting: 'good morning' - } - }, - ja: { - message: { - hello: 'こんにちは、世界', - greeting: 'おはようございます' - } - } - } -}) - -// Define component -const Component1 = { - template: ` -
-

Component1 locale messages: {{ $t("message.hello") }}

-

Fallback global locale messages: {{ $t("message.greeting") }}

-
`, - i18n: { // `i18n` option, setup locale info for component - messages: { - en: { message: { hello: 'hello component1' } }, - ja: { message: { hello: 'こんにちは、component1' } } - } - } -} - -new Vue({ - i18n, - components: { - Component1 - } -}).$mount('#app') -``` - -Template: - - -```html -
-

{{ $t("message.hello") }}

- -
-``` - -Outputs the following: - -```html -
-

こんにちは、世界

-
-

Component1 locale messages: こんにちは、component1

-

Fallback global locale messages: おはようございます

-
-
-``` - -As in the example above, if the component doesn't have the locale message, it falls back to globally defined localization info. The component uses the language set in the root instance (in the above example: `locale: 'ja'`). - -Note that, by default, falling back to root locale generates two warnings in the console: - -``` -[vue-i18n] Value of key 'message.greeting' is not a string! -[vue-i18n] Fall back to translate the keypath 'message.greeting' with root locale. -``` - -To suppress these warnings (while keeping those which warn of the total absence of translation for the given key) set `silentFallbackWarn: true` when initializing the `VueI18n` instance. - -If you want to localize using the component locale, you can do that with `sync: false` and `locale` in the `i18n` option. - - -## Shared locale messages for components - -Sometimes you may want to import shared locale messages for certain components, not fallback from global locale messages (e.g. common messages of certain feature for components. - -You can use `sharedMessages` options of `i18n`. - -Common Locale Messages example: - -```js -export default { - en: { - buttons: { - save: "Save", - // ... - } - }, - ja: { - buttons: { - save: "保存", - // ... - } - } -} -``` - -Components: -```js -import commonMessage from './locales/common' // import common locale messages - -export default { - name: 'ServiceModal', - template: ` - - `, - i18n: { - messages: { ... }, - sharedMessages: commonMessages - } -} -``` - -If `sharedMessages` option is specified along with the `messages` option, those messages will be merged into locale messages into the VueI18n instance of the target component. - - -## Translation in functional component - -When using a functional component, all data (including `props`, `children`, `slots`, `parent`, etc.) is passed through the `context` containing the attributes, and it doesn't recognize the `this` scope, so when using the vue-i18n on functional components, you must refer to `$t` as `parent.$t`, check the example below: - -```html -... - -... -``` diff --git a/docs-old/guide/datetime.md b/docs-old/guide/datetime.md deleted file mode 100644 index 77a51099c..000000000 --- a/docs-old/guide/datetime.md +++ /dev/null @@ -1,77 +0,0 @@ -# DateTime localization - -:::tip Support Version -:new: 7.0+ -::: - -You can localize the datetime with your definition formats. - -DateTime formats the below: - -```js -const dateTimeFormats = { - 'en-US': { - short: { - year: 'numeric', - month: 'short', - day: 'numeric' - }, - long: { - year: 'numeric', - month: 'long', - day: 'numeric', - weekday: 'long', - hour: 'numeric', - minute: 'numeric' - } - }, - 'ja-JP': { - short: { - year: 'numeric', - month: 'short', - day: 'numeric' - }, - long: { - year: 'numeric', - month: 'long', - day: 'numeric', - weekday: 'long', - hour: 'numeric', - minute: 'numeric', - hour12: true - } - } -} -``` - -As seen above, you can define named datetime format (e.g. `short`, `long`, etc), and you need to use [the options with ECMA-402 Intl.DateTimeFormat](http://www.ecma-international.org/ecma-402/2.0/#sec-intl-datetimeformat-constructor) - -After that, when using the locale messages, you need to specify the `dateTimeFormats` option of the `VueI18n` constructor: - -```js -const i18n = new VueI18n({ - dateTimeFormats -}) - -new Vue({ - i18n -}).$mount('#app') -``` - -Template the below: - -```html -
-

{{ $d(new Date(), 'short') }}

-

{{ $d(new Date(), 'long', 'ja-JP') }}

-
-``` - -Output the below: - -```html -
-

Jan 18, 2021

-

2021年1月18日日曜日 午前5:47

-
-``` diff --git a/docs-old/guide/directive.md b/docs-old/guide/directive.md deleted file mode 100644 index 754495a19..000000000 --- a/docs-old/guide/directive.md +++ /dev/null @@ -1,182 +0,0 @@ -# Custom directive localization - -:::tip Support Version -:new: 7.3+ -::: - -You can translate not only with `v-t` custom directive, but also with the `$t` -method. - -## String syntax - -You can pass the keypath of locale messages with string syntax. - -Javascript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { hello: 'hi there!' }, - ja: { hello: 'こんにちは!' } - } - }), - data: { path: 'hello' } -}).$mount('#string-syntax') -``` - -Templates: - -```html -
- -

- -

-
-``` - -Outputs: - -```html -
-

hi there!

-

hi there!

-
-``` - -## Object syntax - -You can use object syntax. - -Javascript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { hello: 'hi {name}!' }, - ja: { hello: 'こんにちは、{name}!' } - } - }), - computed: { - nickName () { return 'kazupon' } - }, - data: { path: 'hello' } -}).$mount('#object-syntax') -``` - -Templates: - -```html -
- -

- -

-
-``` - -Outputs: - -```html -
-

こんにちは、kazupon!

-

hi kazupon!

-
-``` - -## Use with transitions - -:::tip Support Version -:new: 8.7+ -::: - -When `v-t` directive is applied to an element inside [`` component](https://vuejs.org/v2/api/#transition), you may notice that the translated message disappears during the transition. This behavior is related to the nature of the `` component implementation – all directives in the disappearing element inside the `` component will be destroyed **before the transition starts**. This behavior may result in content flickering on short animations, but is most noticeable on long transitions. - -To make sure directive content stays un-touched during a transition, just add the [`.preserve` modifier](../api/#v-t) to the `v-t` directive definition. - -Javascript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { preserve: 'with preserve' }, - } - }), - data: { toggle: true } -}).$mount('#in-transitions') -``` - -Templates: - -```html -
- - - - -
-``` - -It is also possible to set global settings on the `VueI18n` instance itself, which will affect all `v-t` directives without modifier. - -Javascript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { preserve: 'with preserve' }, - }, - preserveDirectiveContent: true - }), - data: { toggle: true } -}).$mount('#in-transitions') -``` - -Templates: - -```html -
- - - - -
-``` - -About the above examples, see the [example](https://github.com/kazupon/vue-i18n/tree/dev/examples/directive) - -## `$t` vs `v-t` - -### `$t` - -`$t` is an extended Vue instance method. It has the following pros and cons: - -#### Pros - -You can **flexibly** use mustache syntax `{{}}` in templates and also computed props and methods in Vue instance. - -#### Cons - -`$t` is executed **every time** when re-render occurs, so it does have translation costs. - -### `v-t` - -`v-t` is a custom directive. It has the following pros and cons: - -#### Pros - -`v-t` has **better performance** than the `$t` method due to its cache with the custom directive, when translated once. Also, pre-translation is possible with the Vue compiler module which was provided by [`vue-i18n-extensions`](https://github.com/kazupon/vue-i18n-extensions). - -Therefore it's possible to make **more performance optimizations**. - -#### Cons - -`v-t` cannot be flexibly used like `$t`, it's rather **complex**. The translated content with `v-t` is inserted into the `textContent` of the element. Also, when you use server-side rendering, you need to set the [custom directive](https://github.com/kazupon/vue-i18n-extensions#directive-v-t-custom-directive-for-server-side) to `directives` option of the `createRenderer` function. diff --git a/docs-old/guide/fallback.md b/docs-old/guide/fallback.md deleted file mode 100644 index 549cdb21c..000000000 --- a/docs-old/guide/fallback.md +++ /dev/null @@ -1,141 +0,0 @@ -# Fallback localization - -*Summary: Use `fallbackLocale: ''` to choose which language to use when your preferred language lacks a translation.* - -## Implicit fallback using locales - -If a `locale` is given containing a territory and an optional dialect, the implicit fallback is activated automatically. - -For example `de-DE-bavarian` would fallback -1. `de-DE-bavarian` -1. `de-DE` -1. `de` - -To suppress the automatic fallback, add the postfix exclamation mark `!`, for example `de-DE!` - -## Explicit fallback with one locale - -Sometimes some items will not be translated into some languages. In this example, the item `hello` is available in English but not Japanese: - -```js -const messages = { - en: { - hello: 'Hello, world!' - }, - ja: { - // Localization without translation to `hello` - } -} -``` - -If you want to use (say) `en` items when an item is not available in your desired locale, set the `fallbackLocale` option in the VueI18n constructor: - -```js -const i18n = new VueI18n({ - locale: 'ja', - fallbackLocale: 'en', - messages -}) -``` - -Template: - -```html -

{{ $t('hello') }}

-``` - -Output: - -```html -

Hello, world!

-``` - -By default, falling back to `fallbackLocale` generates two console warnings: - -``` -[vue-i18n] Value of key 'hello' is not a string! -[vue-i18n] Fall back to translate the keypath 'hello' with 'en' locale. -``` - -To suppress these warnings (while keeping those which warn of the total absence of translation for the given key) set `silentFallbackWarn: true` when initializing the `VueI18n` instance. - -## Explicit fallback with an array of locales - -It is possible to set more than one fallback locale by using an array of locales. For example - -```javascript -fallbackLocale: [ 'fr', 'en' ], -``` - -## Explicit fallback with decision maps -If more complex decision maps for fallback locales are required, it is possible to define decision maps with according fallback locales. -Using the following decision map -```javascript -fallbackLocale: { - /* 1 */ 'de-CH': ['fr', 'it'], - /* 2 */ 'zh-Hant': ['zh-Hans'], - /* 3 */ 'es-CL': ['es-AR'], - /* 4 */ 'es': ['en-GB'], - /* 5 */ 'pt': ['es-AR'], - /* 6 */ 'default': ['en', 'da'] -}, -``` -will result in the following fallback chains -| locale | fallback chains | -|--------|-----------------| -| `'de-CH'` | de-CH > fr > it > en > da | -| `'de'` | de > en > da | -| `'zh-Hant'` | zh-Hant > zh-Hans > zh > en > da | -| `'es-SP'` | es-SP > es > en-GB > en > da | -| `'es-SP!'` | es-SP > en > da | -| `'fr'` | fr > en > da | -| `'pt-BR'` | pt-BR > pt > es-AR > es > en-GB > en > da | -| `'es-CL'` | es-CL > es-AR > es > en-GB > en > da | - -## Fallback interpolation - -*Summary: Set `formatFallbackMessages: true` to do template interpolation on translation keys when your language lacks a translation for a key.* - -Since the keys to the translations are strings, you can use a user-readable message (for a particular language) as a key. -E.g. - -```javascript -const messages = { - ja: { - 'Hello, world!': 'こんにちは、世界!' - } -} -``` - -This is useful because you don't have to specify a translation for the string "Hello, world!" into English. - -In fact, you can even include template parameters in a key. Together with `formatFallbackMessages: true`, this lets you skip writing templates for your "base" language; the keys *are* your templates. - -```javascript -const messages = { - ru: { - 'Hello {name}': 'Здравствуйте {name}' - } -} - -const i18n = new VueI18n({ - locale: 'ru', - fallbackLocale: 'en', - formatFallbackMessages: true, - messages -}) -``` - -When the template is as below: - -```html -

{{ $t('Hello {name}', { name: 'John' }}) }}

-

{{ $t('The weather today is {condition}!', { condition: 'sunny' }) }}

-``` - -The following will be output: - -```html -

Здравствуйте, John

-

The weather today is sunny!

-``` diff --git a/docs-old/guide/formatting.md b/docs-old/guide/formatting.md deleted file mode 100644 index 54ed67942..000000000 --- a/docs-old/guide/formatting.md +++ /dev/null @@ -1,205 +0,0 @@ -# Formatting - -## Named formatting - -Locale messages: - -```js -const messages = { - en: { - message: { - hello: '{msg} world' - } - } -} -``` - -Template: - -```html -

{{ $t('message.hello', { msg: 'hello' }) }}

-``` - -Output: - -```html -

hello world

-``` - -## List formatting - -Locale messages: - -```js -const messages = { - en: { - message: { - hello: '{0} world' - } - } -} -``` - -Template: - -```html -

{{ $t('message.hello', ['hello']) }}

-``` - -Output: - -```html -

hello world

-``` - -List formatting also accepts array-like objects: - -```html -

{{ $t('message.hello', {'0': 'hello'}) }}

-``` - -Output: - -```html -

hello world

-``` - -## HTML formatting - -:::warning Notice -:warning: Dynamically localizing arbitrary HTML on your website can be very dangerous because it can easily lead to XSS vulnerabilities. Only use HTML interpolation on trusted content and never on user-provided content. - -We recommended using the [component interpolation](interpolation.md) feature. -::: - -:::warning Notice -> :new: 8.11+ - -You can control the use of HTML formatting. see the detail `warnHtmlInMessage` constructor option and property API. -::: - -In some cases you might want to render your translation as an HTML message and not a static string. - - -```js -const messages = { - en: { - message: { - hello: 'hello
world' - } - } -} -``` - -Template: - - -```html -

-``` - -Output (instead of the pre-formatted message ) - - -```html -

hello - -world

-``` - - -## Support ruby on rails i18n format - -Locale messages: - -```js -const messages = { - en: { - message: { - hello: '%{msg} world' - } - } -} -``` - -Template: - -```html -

{{ $t('message.hello', { msg: 'hello' }) }}

-``` - -Output: - -```html -

hello world

-``` - -## Custom formatting - -Sometimes, you may need to translate using custom formatting (e.g. [ICU message syntax](http://userguide.icu-project.org/formatparse/messages)). - -You can do that with a custom formatter that implements the [Formatter Interface](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js#L145-L147). - -The following custom formatter with ES2015 class syntax: - -```js -// Custom Formatter implementation -class CustomFormatter { - constructor (options) { - // ... - } - - // - // interpolate - // - // @param {string} message - // string of list or named format. - // e.g. - // - named formatting: 'Hi {name}' - // - list formatting: 'Hi {0}' - // - // @param {Object | Array} values - // values of `message` interpolation. - // passed values with `$t`, `$tc` and `i18n` functional component. - // e.g. - // - $t('hello', { name: 'kazupon' }) -> passed values: Object `{ name: 'kazupon' }` - // - $t('hello', ['kazupon']) -> passed values: Array `['kazupon']` - // - `i18n` functional component (component interpolation) - // - //

kazupon

- //

how are you?

- //
- // -> passed values: Array (included VNode): - // `[VNode{ tag: 'p', text: 'kazupon', ...}, VNode{ tag: 'p', text: 'how are you?', ...}]` - // - // @return {Array} - // interpolated values. you need to return the following: - // - array of string, when is using `$t` or `$tc`. - // - array included VNode object, when is using `i18n` functional component. - // - interpolate (message, values) { - // implement interpolation logic here - // ... - - // return the interpolated array - return ['resolved message string'] - } -} - -// register with `formatter` option -const i18n = new VueI18n({ - locale: 'en-US', - formatter: new CustomFormatter(/* here the constructor options */), - messages: { - 'en-US': { - // ... - }, - // ... - } -}) - -// Run! -new Vue({ i18n }).$mount('#app') -``` - -You can check [the custom formatter official example](https://github.com/kazupon/vue-i18n/tree/dev/examples/formatting/custom). diff --git a/docs-old/guide/hot-reload.md b/docs-old/guide/hot-reload.md deleted file mode 100644 index 2f95126a0..000000000 --- a/docs-old/guide/hot-reload.md +++ /dev/null @@ -1,99 +0,0 @@ -# Hot reloading - -You can use Webpack's [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/) (HMR) feature to watch for changes in localization files and hot reload changes into your application. - -## Basic example - -If you only use a static set of locales, you can hot reload those locales explicitly: - -```js -import Vue from "vue" -import VueI18n from "vue-i18n" -import en from './en' -import ja from './ja' - -const messages = { - en, - ja -} - -// VueI18n instance -const i18n = new VueI18n({ - locale: 'en', - messages -}) - -// Run app -const app = new Vue({ - i18n, - // ... -}).$mount('#app') - -// Hot updates -if (module.hot) { - module.hot.accept(['./en', './ja'], function () { - i18n.setLocaleMessage('en', require('./en').default) - i18n.setLocaleMessage('ja', require('./ja').default) - // Or the following hot updates via $i18n property - // app.$i18n.setLocaleMessage('en', require('./en').default) - // app.$i18n.setLocaleMessage('ja', require('./ja').default) - }) -} -``` - -## Advanced example - -If you want to support a changing set of locales, you can hot reload those locales dynamically using `require.context`: - -```js -import Vue from "vue"; -import VueI18n from "vue-i18n"; - -Vue.use(VueI18n); - -// Load all locales and remember context -function loadMessages() { - const context = require.context("./locales", true, /[a-z0-9-_]+\.json$/i); - - const messages = context - .keys() - .map((key) => ({ key, locale: key.match(/[a-z0-9-_]+/i)[0] })) - .reduce( - (messages, { key, locale }) => ({ - ...messages, - [locale]: context(key), - }), - {} - ); - - return { context, messages }; -} - -const { context, messages } = loadMessages(); - -// VueI18n instance -const i18n = new VueI18n({ - locale: "en", - messages, -}); - -// Run app -const app = new Vue({ - i18n, - // ... -}).$mount('#app'); - -// Hot updates -if (module.hot) { - module.hot.accept(context.id, () => { - const { messages: newMessages } = loadMessages(); - - Object.keys(newMessages) - .filter((locale) => messages[locale] !== newMessages[locale]) - .forEach((locale) => { - messages[locale] = newMessages[locale]; - i18n.setLocaleMessage(locale, messages[locale]); - }); - }); -} -``` diff --git a/docs-old/guide/interpolation.md b/docs-old/guide/interpolation.md deleted file mode 100644 index 44ad212fb..000000000 --- a/docs-old/guide/interpolation.md +++ /dev/null @@ -1,272 +0,0 @@ -# Component interpolation - -## Basic Usage - -:::tip Support Version -:new: 7.0+ -::: - -Sometimes, we need to localize with a locale message that was included in a HTML tag or component. For example: - -```html -

I accept xxx Terms of Service Agreement

-``` - -In the above message, if you use `$t`, you will probably try to compose the following locale messages: - -```js -const messages = { - en: { - term1: 'I Accept xxx\'s', - term2: 'Terms of Service Agreement' - } -} -``` - -And your localized template may look like this: - -```html -

{{ $t('term1') }}{{ $t('term2') }}

-``` - -Output: - -```html -

I accept xxx Terms of Service Agreement

-``` - -This is very cumbersome, and if you configure the `` tag in a locale message, there is a possibility of XSS vulnerabilities due to localizing with -`v-html="$t('term')"`. - -You can avoid it using the `i18n` functional component. For example: - -```html - -``` -```js -const messages = { - en: { - tos: 'Term of Service', - term: 'I accept xxx {0}.' - }, - ja: { - tos: '利用規約', - term: '私は xxx の{0}に同意します。' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) -new Vue({ - i18n, - data: { - url: '/term' - } -}).$mount('#app') -``` - -the following output: - -```html -
- - - -
-``` - -About the above example, see the [example](https://github.com/kazupon/vue-i18n/tree/dev/examples/interpolation/places) - -The children of `i18n` functional component are interpolated with locale message of `path` prop. - -In the above example: -:::v-pre -`{{ $t('tos') }}` -::: -is interpolated with `term` locale message. - -In the above example, the component interpolation follows the **list formatting**. The children of `i18n` functional component are interpolated by their order of appearance. - -You can choose the root container's node type by specifying a `tag` prop. If omitted, it defaults to `'span'`. You can also set it to the boolean value `false` to insert the child nodes directly without creating a root element. - -## Slots syntax usage - -:::tip Support Version -:new: 8.14+ -::: - -It's more convenient to use the named slots syntax. For example: - -```html -
- - - - - - -
-``` - -```js -const messages = { - en: { - info: 'You can {action} until {limit} minutes from departure.', - change: 'change your flight', - refund: 'refund the ticket' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) - -new Vue({ - i18n, - data: { - changeUrl: '/change', - refundUrl: '/refund', - changeLimit: 15, - refundLimit: 30 - } -}).$mount('#app') -``` - -Outputs: - -```html -
- -

- You can change your flight until 15 minutes from departure. -

- -
-``` - -In Vue 2.6 and later, you can use the following slots syntax in templates: - -```html -
- - - - - - -
-``` - -:::warning Limitation -:warning: In `i18n` component, slots props are not supported. -::: - - -## Places syntax usage - -:::danger Important!! -In the next major version, the `place` and `places` props will be deprecated. Please switch to slots syntax. -::: - -:::tip Support Version -:new: 7.2+ -::: - -:::warning Notice -:warning: In `i18n` component, text content consisting of only white spaces will be omitted. -::: - -Named formatting is supported with the help of `place` attribute. For example: - -```html -
- - - {{ changeLimit }} - {{ $t('change') }} - - -
-``` -```js -const messages = { - en: { - info: 'You can {action} until {limit} minutes from departure.', - change: 'change your flight', - refund: 'refund the ticket' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) -new Vue({ - i18n, - data: { - changeUrl: '/change', - refundUrl: '/refund', - changeLimit: 15, - refundLimit: 30 - } -}).$mount('#app') -``` - -Outputs: - -```html -
- -

- You can change your flight until 15 minutes from departure. -

- -
-``` - -:::warning Notice -:warning: To use named formatting, all children of `i18n` component must have `place` attribute set. Otherwise it will fallback to list formatting. -::: - -If you still want to interpolate text content in named formatting, you could define `places` property on `i18n` component. For example: - -```html -
- - - {{ $t('refund') }} - - -
-``` - -Outputs: - -```html -
- -

- You can refund your ticket until 30 minutes from departure. -

- -
-``` diff --git a/docs-old/guide/lazy-loading.md b/docs-old/guide/lazy-loading.md deleted file mode 100644 index 144dc4359..000000000 --- a/docs-old/guide/lazy-loading.md +++ /dev/null @@ -1,85 +0,0 @@ -# Lazy loading translations - -Loading all of your translation files at once is overkill and unnecessary. - -Lazy loading or asynchronously loading the translation files is really easy when using Webpack. - -Let´s assume we have a project directory similar to the one below: - -``` -our-cool-project --dist --src ---routes ---store ---setup ----i18n-setup.js ---lang ----en.js ----it.js -``` - -The `lang` folder is where all of our translation files reside. The `setup` folder is where our arbitrary setup files like the i18n-setup, global component inits, plugin inits and other reside. - -```js -//i18n-setup.js -import Vue from 'vue' -import VueI18n from 'vue-i18n' -import messages from '@/lang/en' -import axios from 'axios' - -Vue.use(VueI18n) - -export const i18n = new VueI18n({ - locale: 'en', // set locale - fallbackLocale: 'en', - messages // set locale messages -}) - -const loadedLanguages = ['en'] // our default language that is preloaded - -function setI18nLanguage (lang) { - i18n.locale = lang - axios.defaults.headers.common['Accept-Language'] = lang - document.querySelector('html').setAttribute('lang', lang) - return lang -} - -export function loadLanguageAsync(lang) { - // If the same language - if (i18n.locale === lang) { - return Promise.resolve(setI18nLanguage(lang)) - } - - // If the language was already loaded - if (loadedLanguages.includes(lang)) { - return Promise.resolve(setI18nLanguage(lang)) - } - - // If the language hasn't been loaded yet - return import(/* webpackChunkName: "lang-[request]" */ `@/i18n/messages/${lang}.js`).then( - messages => { - i18n.setLocaleMessage(lang, messages.default) - loadedLanguages.push(lang) - return setI18nLanguage(lang) - } - ) -} -``` - -In short we are creating a new VueI18n instance as we normally would. Then we are creating a `loadedLanguages` array that will keep track of our loaded languages. Next is the `setI18nLanguage` function that will actually change the language in our vueI18n instance, axios and where ever else is needed. - -The `loadLanguageAsync` function is what we will actually use to change the languages. Loading the new files is done via the `import` function, which is generously provided by Webpack and it allows us to load files dynamically, and because it uses promises we can easily wait for the loading to finish. - -You can learn more about the import function in the [Webpack documentation](https://webpack.js.org/guides/code-splitting/#dynamic-imports). - -Using the `loadLanguageAsync` function is straightforward. A common use case is inside a vue-router beforeEach hook. - -```js -router.beforeEach((to, from, next) => { - const lang = to.params.lang - loadLanguageAsync(lang).then(() => next()) -}) -``` - -We could improve this by checking if the `lang` is actually supported by us or not, call `reject` so we can catch that in the `beforeEach` stopping the route transition. diff --git a/docs-old/guide/locale.md b/docs-old/guide/locale.md deleted file mode 100644 index a9f9ebb07..000000000 --- a/docs-old/guide/locale.md +++ /dev/null @@ -1,56 +0,0 @@ -# Locale changing - -Normally, using the root Vue instance as the starting point, all child components are localized using the `locale` property of the `VueI18n` class as a reference. - -Sometimes you might want to dynamically change the locale. In that case you can change the value of the `locale` property of the `VueI18n` instance. - - -```js -const i18n = new VueI18n({ - locale: 'ja', // set locale - ... -}) - -// create root Vue instance -new Vue({ - i18n, - ... -}).$mount('#app') - -// change other locale -i18n.locale = 'en' -``` - -Each component contains a `VueI18n` instance referenced as the `$i18n` property that can also be used to change the locale. - -Example: - -```vue - - - -``` - -:::warning Notice -:warning: Locale changing is ignored for components that use `sync: false`. -::: - -:::warning Component vs. root scope -:warning: Changing `$i18n.locale` inside a component does not update the root locale. -If you rely on the root locale, for example when using [root fallbacks](./fallback.html), use `$root.$i18n.locale` instead of `$i18n.locale`. -::: diff --git a/docs-old/guide/messages.md b/docs-old/guide/messages.md deleted file mode 100644 index 3be84c052..000000000 --- a/docs-old/guide/messages.md +++ /dev/null @@ -1,292 +0,0 @@ -# Locale messages syntax - -## Structure - -Locale Messages syntax below: - -```typescript -// As Flowtype definition, Locale Messages syntax like BNF annotation -type LocaleMessages = { [key: Locale]: LocaleMessageObject }; -type LocaleMessageObject = { [key: Path]: LocaleMessage }; -type LocaleMessageArray = LocaleMessage[]; -type MessageContext = { - list: (index: number) => mixed, - named: (key: string) => mixed -}; -type MessageFunction = (ctx: MessageContext) => string; -type LocaleMessage = string | MessageFunction | LocaleMessageObject | LocaleMessageArray; -type Locale = string; -type Path = string; -``` - -Based on the above syntax, You can configure the following Locale Messages structure: - -```json -{ - "en": { // 'en' Locale - "key1": "this is message1", // basic - "nested": { // nested - "message1": "this is nested message1" - }, - "errors": [ // array - "this is 0 error code message", - { // object in array - "internal1": "this is internal 1 error message" - }, - [ // array in array - "this is nested array error 1" - ] - ] - }, - "ja": { // 'ja' Locale - // ... - } -} -``` - -In the above Locale Messages structure, You can translate using below key paths. - -```html -
- -

{{ $t('key1') }}

- -

{{ $t('nested.message1') }}

- -

{{ $t('errors[0]') }}

- -

{{ $t('errors[1].internal1') }}

- -

{{ $t('errors[2][0]') }}

-
-``` - -Output the following: - -```html -
- -

this is message1

- -

this is nested message1

- -

this is 0 error code message

- -

this is internal 1 error message

- -

this is nested array error 1

-
-``` - -## Linked locale messages - -If there's a translation key that will always have the same concrete text as another one you can just link to it. To link to another translation key, all you have to do is to prefix its contents with an `@:` sign followed by the full name of the translation key including the namespace you want to link to. - -Locale messages the below: - -```js -const messages = { - en: { - message: { - the_world: 'the world', - dio: 'DIO:', - linked: '@:message.dio @:message.the_world !!!!' - } - } -} -``` - -Template: - -```html -

{{ $t('message.linked') }}

-``` - -Output: - -```html -

DIO: the world !!!!

-``` - -### Formatting linked locale messages - -If the language distinguish cases of character, you may need control the case of the linked locale messages. -Linked messages can be formatted with modifier `@.modifier:key` - -The below modifiers are available currently. - -* `upper`: Uppercase all characters in the linked message. -* `lower`: Lowercase all characters in the linked message. -* `capitalize`: Capitalize the first character in the linked message. - -Locale messages the below: - -```javascript -const messages = { - en: { - message: { - homeAddress: 'Home address', - missingHomeAddress: 'Please provide @.lower:message.homeAddress' - } - } -} -``` - -```html - - -

{{ $t('message.missingHomeAddress') }}

-``` - -Output the below: - -```html - - -

Please provide home address

-``` - -You can add modifiers or overwrite the existing ones passing the `modifiers` options to the `VueI18n` constructor. - -```javascript -const i18n = new VueI18n({ - locale: 'en', - modifiers: { - // Adding a new modifier - snakeCase: (str) => str.split(' ').join('-') - }, - messages: { - // ... - }, -}) -``` - -### Grouping by brackets - -A translation key of linked locale message can also have the form of `@:(message.foo.bar.baz)` in which the link to another translation key is within brackets `()`. - -This can be useful if the link `@:message.something` is followed by period `.`, which otherwise would be part of the link and may not need to be. - -Locale messages: - -```js -const messages = { - en: { - message: { - dio: 'DIO', - linked: 'There\'s a reason, you lost, @:(message.dio).' - } - } -} -``` - -Template: - -```html -

{{ $t('message.linked') }}

-``` - -Output: - -```html -

There's a reason, you lost, DIO.

-``` - -## Message Function - -vue-i18n recommends using the string base on list or named format as locale messages when translating messages. - -There are situations however, where you really need the full programmatic power of JavaScript, due to the complex language syntax. So instead of string-based messages, you can use the **message function**. - -The following is a message function that returns a simple greeting: - -```js -const messages = { - en: { - greeting: (ctx) => 'hello!' - } -} -``` - -The use of the message function is very easy! You just specify the key of the message function with `$t` or `t`: - -```html -

{{ $t('greeting') }}

-``` - -Output is the below: - -```html -

hello!

-``` - -The message function outputs the message of the return value of the message function. - -### Named formatting - -vue-i18n supports [named formatting](./formatting.md#named-formatting) as a string-based message format. vue-i18n interpolate the parameter values with `$t` or `t`, and it can be output it. - -You can do the same thing with the message function by using **message context**: - -here is the example of greeting: - -```js -const messages = { - en: { - greeting: (ctx) => `hello, ${ctx.named('name')}!` - } -} -``` - -Template: - -```html -

{{ $t('greeting', { name: 'DIO' }) }}

-``` - -Output is the below: - -```html -

hello, DIO!

-``` - -The message context has a named function. You need to specify the key that resolves the value specified with the named of `$t` or `t`. - -### List formatting - -The use of the list format is similar to the named format described above. - -vue-i18n supports [list formatting](./formatting.md#list-formatting) as a string-based message format. vue-i18n interpolate the parameter values with `$t` or `t`, and it can be output it. - -You can do the same thing with the message function by using message context: - -here is the example of greeting: - -```js -const messages = { - en: { - greeting: (ctx) => `hello, ${ctx.list(0)}!` - } -} -``` - -Template: - -```html -

{{ $t('greeting', ['DIO']) }}

-``` - -Output is the below: - -```html -

hello, DIO!

-``` - -The message context has a list function. You need to specify the index that resolves the value specified with the list of `$t` or `t`. - -### Limitation - -In the message function, the following functions, which are provided on a string basis, are not available via a message context: - -- Linked locale messages -- Pluralization diff --git a/docs-old/guide/number.md b/docs-old/guide/number.md deleted file mode 100644 index 630d5fff8..000000000 --- a/docs-old/guide/number.md +++ /dev/null @@ -1,133 +0,0 @@ -# Number localization - -:::tip Support Version -:new: 7.0+ -::: - -You can localize the number with your definition formats. - -Number formats the below: - -```js -const numberFormats = { - 'en-US': { - currency: { - style: 'currency', - currency: 'USD' - } - }, - 'ja-JP': { - currency: { - style: 'currency', - currency: 'JPY', - currencyDisplay: 'symbol' - } - } -} -``` - -As the above, you can define named number formats (e.g. `currency`, etc), and you need to use [the options with ECMA-402 Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat) - -After that, when using the locale messages, you need to specify the `numberFormats` option of the `VueI18n` constructor: - -```js -const i18n = new VueI18n({ - numberFormats -}) - -new Vue({ - i18n -}).$mount('#app') -``` - -Template the below: - -```html -
-

{{ $n(100, 'currency') }}

-

{{ $n(100, 'currency', 'ja-JP') }}

-
-``` - - -Output the below: - -```html -
-

$100.00

-

¥100

-
-``` - -## Custom formatting - -:::tip Support Version -:new: 8.10+ -::: - -`$n` method returns resulting string with fully formatted number, which can only be used as a whole. In situations when you need to style some part of the formatted number (like fraction digits), `$n` is not enough. In such cases `` functional component will be of help. - -With a minimum set of properties, `` generates the same output as `$n`, wrapped into configured DOM element. - -The following template: - -```html -
- - - -
-``` - -will produce the below output: - -```html -
- 100 - $100.00 - ¥100 -
-``` - -But the real power of this component comes into play when it is used with [scoped slots](https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots). - -Let's say there is a requirement to render the integer part of the number with a bolder font. This can be achieved by specifying `integer` scoped slot element: - -```html - - {{ slotProps.integer }} - -``` - -Template above will result in the following HTML: - -```html -$100.00 -``` - -It is possible to specify multiple scoped slots at the same time: - -```html - - {{ slotProps.currency }} - {{ slotProps.integer }} - {{ slotProps.group }} - {{ slotProps.fraction }} - -``` - -(this resulting HTML was formatted for better readability) - -```html - - - 1 - , - 234 - 00 - -``` - -You can choose the root container's node type by specifying a `tag` prop. If omitted, it defaults to `'span'`. You can also set it to the boolean value `false` to insert the child nodes directly without creating a root element. - -Full list of the supported scoped slots as well as other `` properties can be found [on API page](../api/readme.md#i18n-n-functional-component). diff --git a/docs-old/guide/pluralization.md b/docs-old/guide/pluralization.md deleted file mode 100644 index 3e32bc656..000000000 --- a/docs-old/guide/pluralization.md +++ /dev/null @@ -1,168 +0,0 @@ -# Pluralization - -You can translate with pluralization. You must define the locale that have a pipe `|` separator, and define plurals in pipe separator. - -*Your template will need to use `$tc()` instead of `$t()`.* - -Locale messages below: - -```js -const messages = { - en: { - car: 'car | cars', - apple: 'no apples | one apple | {count} apples' - } -} -``` - -Template below: - -```html -

{{ $tc('car', 1) }}

-

{{ $tc('car', 2) }}

- -

{{ $tc('apple', 0) }}

-

{{ $tc('apple', 1) }}

-

{{ $tc('apple', 10, { count: 10 }) }}

-``` - -Output below: - -```html -

car

-

cars

- -

no apples

-

one apple

-

10 apples

-``` - -## Accessing the number via the pre-defined argument - -You don't need to explicitly give the number for pluralization. -The number can be accessed within locale messages via pre-defined named arguments `{count}` and/or `{n}`. -You can overwrite those pre-defined named arguments if necessary. - -Locale messages the below: - -```js -const messages = { - en: { - apple: 'no apples | one apple | {count} apples', - banana: 'no bananas | {n} banana | {n} bananas' - } -} -``` - -Template below: - -```html -

{{ $tc('apple', 10, { count: 10 }) }}

-

{{ $tc('apple', 10) }}

- -

{{ $tc('banana', 1, { n: 1 }) }}

-

{{ $tc('banana', 1) }}

-

{{ $tc('banana', 100, { n: 'too many' }) }}

-``` - -Output below: - -```html -

10 apples

-

10 apples

- -

1 banana

-

1 banana

-

too many bananas

-``` - - -## Custom pluralization - -Such pluralization, however, does not apply to all languages (Slavic languages, for example, have different pluralization rules). - -In order to implement these rules you can pass an optional `pluralizationRules` object into `VueI18n` constructor options. - -Very simplified example using rules for Slavic languages (Russian, Ukrainian, etc.): -```js -new VueI18n({ - // Key - language to use the rule for, `'ru'`, in this case - // Value - function to choose right plural form - pluralizationRules: { - /** - * @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)` - * @param choicesLength {number} an overall amount of available choices - * @returns a final choice index to select plural word by - */ - 'ru': function(choice, choicesLength) { - // this === VueI18n instance, so the locale property also exists here - - if (choice === 0) { - return 0; - } - - const teen = choice > 10 && choice < 20; - const endsWithOne = choice % 10 === 1; - - if (choicesLength < 4) { - return (!teen && endsWithOne) ? 1 : 2; - } - if (!teen && endsWithOne) { - return 1; - } - if (!teen && choice % 10 >= 2 && choice % 10 <= 4) { - return 2; - } - - return (choicesLength < 4) ? 2 : 3; - } - } -}) -``` - -This would effectively give this: - -```javascript -const messages = { - ru: { - car: '0 машин | {n} машина | {n} машины | {n} машин', - banana: 'нет бананов | {n} банан | {n} банана | {n} бананов' - } -} -``` -Where the format is `0 things | things count ends with 1 | things count ends with 2-4 | things count ends with 5-9, 0 and teens (10-19)`. -P.S. Slavic pluralization is difficult, you can read more about it [here](http://www.russianlessons.net/lessons/lesson11_main.php). - -Your template still needs to use `$tc()`, not `$t()`: - -```html -

{{ $tc('car', 1) }}

-

{{ $tc('car', 2) }}

-

{{ $tc('car', 4) }}

-

{{ $tc('car', 12) }}

-

{{ $tc('car', 21) }}

- -

{{ $tc('banana', 0) }}

-

{{ $tc('banana', 4) }}

-

{{ $tc('banana', 11) }}

-

{{ $tc('banana', 31) }}

-``` - -Which results in: - -```html -

1 машина

-

2 машины

-

4 машины

-

12 машин

-

21 машина

- -

нет бананов

-

4 банана

-

11 бананов

-

31 банан

-``` - -### Default pluralization - -If your current locale is not found in a pluralization map, the [default](#pluralization) rule of the english language will be used. diff --git a/docs-old/guide/sfc.md b/docs-old/guide/sfc.md deleted file mode 100644 index 0220e274c..000000000 --- a/docs-old/guide/sfc.md +++ /dev/null @@ -1,400 +0,0 @@ -# Single file components - -## Basic Usage - -If you are building Vue component or Vue application using single file components, you can manage the locale messages `i18n` custom block. - -The following in [single file components example](https://github.com/kazupon/vue-i18n/tree/dev/examples/sfc): - -```vue - -{ - "en": { - "hello": "hello world!" - }, - "ja": { - "hello": "こんにちは、世界!" - } -} - - - - - -``` - -## Installing vue-i18n-loader - -You need to install `vue-loader` and `vue-i18n-loader` due to use `` custom blocks. While [vue-loader](https://github.com/vuejs/vue-loader) most likely is already used in your project if you are working with single file components, you must install [vue-i18n-loader](https://github.com/kazupon/vue-i18n-loader) additionally: - -```sh -npm i --save-dev @kazupon/vue-i18n-loader -``` - -## Webpack - -For Webpack the configuration below is required: - -for vue-loader v15 or later: -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - }, - { - resourceQuery: /blockType=i18n/, - type: 'javascript/auto', - loader: '@kazupon/vue-i18n-loader' - } - // ... - ] - }, - // ... -} -``` - -for vue-loader v14: -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - loaders: { - // you need to specify `i18n` loaders key with `vue-i18n-loader` (https://github.com/kazupon/vue-i18n-loader) - i18n: '@kazupon/vue-i18n-loader' - } - } - }, - // ... - ] - }, - // ... -} -``` - -## Vue CLI 3.0 - -[Vue CLI 3.0](https://github.com/vuejs/vue-cli) hides the webpack configuration, so, if we want to add support to the `` tag inside a single file component we need to modify the existing configuration. - -In order to do that we have to create a `vue.config.js` at the root of our project. Once we have done that, we have to include the following: - -for vue-loader v15 or later: -```js -module.exports = { - chainWebpack: config => { - config.module - .rule("i18n") - .resourceQuery(/blockType=i18n/) - .type('javascript/auto') - .use("i18n") - .loader("@kazupon/vue-i18n-loader") - .end(); - } -} -``` - -for vue-loader v14: -```js -const merge = require('deepmerge') - -module.exports = { - chainWebpack: config => { - config.module - .rule('vue') - .use('vue-loader') - .tap(options => - merge(options, { - loaders: { - i18n: '@kazupon/vue-i18n-loader' - } - }) - ) - } -} -``` -_Don 't forget to install [deepmerge](https://github.com/KyleAMathews/deepmerge)! (`npm i deepmerge -D` or `yarn add deepmerge -D`)_ - -If you want to read more about modifying the existing configuration [click here](https://cli.vuejs.org/guide/webpack.html). - -## Laravel-Mix - -for Laravel-mix 4 with vue-loader v15 or later: -```js -// Extend Mix with the "i18n" method, that loads the vue-i18n-loader -mix.extend( 'i18n', new class { - webpackRules() { - return [ - { - resourceQuery: /blockType=i18n/, - type: 'javascript/auto', - loader: '@kazupon/vue-i18n-loader', - }, - ]; - } - }(), -); - -// Make sure to call the .i18n() (to load the loader) before .js(..., ...) -mix.i18n() - .js( 'resources/js/App.js', 'public/js/app.js' ) - ... -``` - -for Laravel-mix 2 with vue-loader v14: - -As of [V2.1](https://github.com/JeffreyWay/laravel-mix/releases/tag/v2.1) of Laravel-mix, you can add custom rules via mix.extend(). Laravel mix already has its own rules for handling .vue files. To add the `vue-i18n-loader`, add the following to `webpack.mix.js` - -```js -// The below code will inject i18n Kazupon/vue-18-loader as a loader for .vue files. -mix.extend( 'i18n', function( webpackConfig, ...args ) { - webpackConfig.module.rules.forEach( ( module ) => { - // Search for the "vue-loader" component, which handles .vue files. - if( module.loader !== 'vue-loader' ) { - return; - } - - // Within this module, add the vue-i18n-loader for the i18n tag. - module.options.loaders.i18n = '@kazupon/vue-i18n-loader'; - } ); -} ); - -// Make sure to call .i18n() before .js(..., ...) -mix.i18n() - .js( 'resources/assets/js/App.js', 'public/js/app.js' ) - ... -``` - -## YAML loading - -`i18n` custom blocks need to specify `JSON` format, also you can use `YAML` format by using pre-loader feature of `vue-loader`. - -the `i18n` custom blocks below of `YAML` format: - -```vue - -en: - hello: "hello world!" -ja: - hello: "こんにちは、世界!" - -``` - - -Webpack conf the below: - -for vue-loader v15 or later: -```js -// Vue CLI 3.0 -module.exports = { - chainWebpack: config => { - config.module - .rule("i18n") - .resourceQuery(/blockType=i18n/) - .type('javascript/auto') - .use("i18n") - .loader("@kazupon/vue-i18n-loader") - .end() - .use('yaml') - .loader('yaml-loader') - .end() - } -} -``` - -for vue-loader v14: -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - preLoaders: { - i18n: 'yaml-loader' - }, - loaders: { - i18n: '@kazupon/vue-i18n-loader' - } - } - }, - // ... - ] - }, - // ... -} -``` - -## Multiple custom blocks - -You can use locale messages with multiple `i18n` custom blocks. - -```vue - - - { - "en": { - "hello": "hello world!" - }, - "ja": { - "hello": "こんにちは、世界!" - } - } - -``` - -In the above, first custom block load the common locale message with `src` attribute, second custom block load the locale message that is defined only at single file component. These locale messages will be merged as locale message of component. - -In this way, multiple custom blocks useful when want to be used as module. - -## Scoped style - -When using `vue-i18n` with `scoped style`, it's important to remember to use a [deep selector](https://vue-loader.vuejs.org/guide/scoped-css.html#child-component-root-elements) for styling an element __*inside*__ the translation string. For example: - -__Translation contains only text__ (Work without deep selector) - -```vue - -{ - "en": { - "hello": "hello world!" - }, - "ja": { - "hello": "こんにちは、世界" - } -} - - - - - - -``` - -__Translation with HTML element__ (Must use deep selector) - -```vue - -{ - "en": { - "hello": "helloworld!" - }, - "ja": { - "hello": "こんにちは、世界!" - } -} - - - - - - - - - - - - - - - -``` - -## Custom blocks in functional component - -If the single file components have the template using a functional component, and you had been defined `i18n` custom blocks, note you cannot localize using locale messages. - -For example, the following code cannot localize with the locale message of `i18n` custom block. - -```vue - -{ - "en": { - "hello": "hello world" - }, - "ja": { - "hello": "こんにちは、世界" - } -} - - - -``` diff --git a/docs-old/guide/tooling.md b/docs-old/guide/tooling.md deleted file mode 100644 index ddc4ed113..000000000 --- a/docs-old/guide/tooling.md +++ /dev/null @@ -1,72 +0,0 @@ -# Tooling - -To support the i18n of Vue applications, some tools are officially provided. - -There are also tools from third vendors integrating Vue I18n. - -## Official tooling - -### Vue CLI Plugin - -[vue-cli-plugin-i18n](https://github.com/kazupon/vue-cli-plugin-i18n) is officially provided as the Vue CLI Plugin. - -With this plugin, you can setup the i18n environment for the Vue application, and support the i18n development environment. - -### Nuxt Module - -[nuxt-i18n](https://github.com/nuxt-community/nuxt-i18n/) is corresponding Nuxt.js module. - -### Webpack loader - -[vue-i18n-loader](https://github.com/kazupon/vue-i18n-loader) is an officially provided webpack loader. - -With this loader, you can use the `i18n` custom block in the Single file components. - -In about `i18n` custom block, see the [Single file components section](./sfc.md) - -### ESLint Plugin - -[eslint-plugin-vue-i18n](https://intlify.github.io/eslint-plugin-vue-i18n/) is ESLint plugin for Vue I18n. - -It easily integrates some localization lint features to your Vue.js Application. - -### Extensions - -[vue-i18n-extensions](https://github.com/kazupon/vue-i18n-extensions) provides some extensions for Vue I18n. - -You can use this extension to enable SSR and improve i18n performance. - -## 3rd party tooling - -### BabelEdit - -[BabelEdit](https://www.codeandweb.com/babeledit) is translation editor for web apps. - -BabelEdit can translate `json` files, and it can also translate `i18n` custom block of Single-file components. - -Read more about BabelEdit in [tutorial page](https://www.codeandweb.com/babeledit/tutorials/how-to-translate-your-vue-app-with-vue-i18n). - -### i18n Ally - -[i18n Ally](https://marketplace.visualstudio.com/items?itemName=antfu.i18n-ally) is i18n extension for VSCode. - -i18n Ally give awesome DX for your i18n development. - -Read more about i18n Ally in [README](https://github.com/antfu/i18n-ally/blob/master/README.md). - -### i18nPlugin (intellij platform) - -[i18nPlugin](https://github.com/nyavro/i18nPlugin) Intellij idea i18next support plugin ( [Jetbrains plugin page ](https://plugins.jetbrains.com/plugin/12981-i18n-support)). - -Plugin for i18n typescript/javascript/PHP. Supports vue-i18n. To enable vue-i18n support go to settings -> Tools -> i18n Plugin configuration and check "Vue-i18n". You need set vue locales directory (locales by default). - -### vue-i18n-extract - -[vue-i18n-extract](https://github.com/pixari/vue-i18n-extract) performs static analysis on a Vue.js project based on vue-i18n and reports the following information: - -- list of all the **unused vue-i18n keys** (entries found in the language files but not used in the project) -- list of all the **missing keys** (entries fond in the project but not in the language files) - -It's possible to show the output in the console or to write it in a json file. - -The missing keys can be also automatically added to the given language files. diff --git a/docs-old/installation.md b/docs-old/installation.md deleted file mode 100644 index 4e1da9042..000000000 --- a/docs-old/installation.md +++ /dev/null @@ -1,86 +0,0 @@ -# Installation - -## Compatibility Note - -- Vue.js `2.0.0`+ - -## Direct Download / CDN - - - -[unpkg.com](https://unpkg.com) provides NPM-based CDN links. The above link will always point to the latest release on NPM. You can also use a specific version/tag via URLs like - -Include vue-i18n after Vue and it will install itself automatically: - - -```html - - -``` - -## NPM - -```sh -npm install vue-i18n -``` - -## Yarn - -```sh -yarn add vue-i18n -``` - -When using with a module system, you must explicitly install the `vue-i18n` -via `Vue.use()`: - - -```javascript -import Vue from 'vue' -import VueI18n from 'vue-i18n' - -Vue.use(VueI18n) -``` - -You don't need to do this when using global script tags ` -``` - -:::warning Aviso -:warning: As alterações de localização são ignoradas pelos componentes com a opção `sync: false`. -::: - -:::warning Componente vs. escopo root -:warning: Alterarando `$i18n.locale` dentro do componente não altera a localização root. Se você está contando com a localização root, por exemplo, ao usar [root fallback](./fallback.html), use `$root.$I18n.locale` ao vez de `$i18n.locale`. -::: diff --git a/docs-old/pt/guide/messages.md b/docs-old/pt/guide/messages.md deleted file mode 100644 index c01a2926b..000000000 --- a/docs-old/pt/guide/messages.md +++ /dev/null @@ -1,319 +0,0 @@ -# Sintaxe mensagens locais - -## Estrutura - -Sintaxe local das mensagens: - -```typescript -// Como definição do Flowtype, a sintaxe das mensagens de tradução é semelhante à anotação BNF -type LocaleMessages = { [key: Locale]: LocaleMessageObject } -type LocaleMessageObject = { [key: Path]: LocaleMessage } -type LocaleMessageArray = LocaleMessage[] -type MessageContext = { - list: (index: number) => mixed, - named: (key: string) => mixed -}; -type MessageFunction = (ctx: MessageContext) => string; -type LocaleMessage = string | MessageFunction | LocaleMessageObject | LocaleMessageArray; -type Locale = string -type Path = string -``` - -Com base na sintaxe acima, você pode configurar a seguinte estrutura de mensagens locais: - -```json -{ - // localização 'pt' - "pt": { - "key1": "esta é a mensagem 1", // uso comum - "nested": { - // aninhado - "message1": "esta é a mensagem aninhada 1" - }, - "errors": [ - // array - "esta é a mensagem de código de erro 0", - { - // um objeto em array - "internal1": "esta é uma mensagem de código de erro interno 1" - }, - [ - // array em array - "este é o erro de array aninhado 1" - ] - ] - }, - // localização 'en' - "en": { - // ... - } -} -``` - -Na estrutura de mensagens locais acima, você pode traduzir usando os caminhos-chave abaixo. - -```html -
- -

{{ $t('key1') }}

- -

{{ $t('nested.message1') }}

- -

{{ $t('errors[0]') }}

- -

{{ $t('errors[1].internal1') }}

- -

{{ $t('errors[2][0]') }}

-
-``` - -O resultado será o seguinte: - -```html -
- -

esta é a mensagem 1

- -

esta é a mensagem aninhada 1

- -

esta é a mensagem de código de erro 0

- -

esta é uma mensagem de código de erro interno 1

- -

este é o erro de array aninhado 1

-
-``` - -## Mensagens de localização relacionadas - -Se houver uma chave de tradução que sempre terá o mesmo texto concreto igual outra, você pode simplesmente criar um link para essa. Para vincular a outra chave de tradução, tudo que você precisa fazer é prefixar seu conteúdo com um sinal `@:` seguido pelo nome completo da chave de tradução incluindo o namespace ao qual deseja vincular. - -Mensagens de localização a seguir: - -```js -const messages = { - en: { - message: { - the_world: 'the world', - dio: 'DIO:', - linked: '@:message.dio @:message.the_world !!!!' - } - } -} -``` - -Template: - -```html -

{{ $t('message.linked') }}

-``` - -O resultado será o seguinte: - -```html -

DIO: the world !!!!

-``` - -### Formatando mensagens de localização relacionadas - -Se o idioma distinguir casos de caracteres, você pode precisar controlar o caso das mensagens de localização relacionadas. -Mensagens relacionadas podem ser formatadas com o modificador `@.modifier:key` - -Mensagens de localização a seguir: - -* `upper`: Letras maiúsculas em todos os caracteres na mensagem vinculada. -* `lower`: Letras minúsculas em todos os caracteres na mensagem vinculada. -* `capitalize`: Primeiro caractere em maiúsculo da mensagem vinculada. - -Mensagens de localização: - -```js -const messages = { - en: { - message: { - homeAddress: 'Home address', - missingHomeAddress: 'Please provide @.lower:message.homeAddress' - } - }, - pt: { - message: { - homeAddress: 'Endereço residencial', - missingHomeAddress: 'Por favor, providencie o @.lower:message.homeAddress' - } - } -} -``` - -```html - - -

{{ $t('message.missingHomeAddress') }}

-``` - -O resultado será o seguinte: - -```html - - -

Por favor, providencie o Endereço residencial

-``` - -Você pode adicionar modificadores ou sobrescrever os existentes passando as opções de `modificadores` para o construtor `VueI18n`. - -```js -const i18n = new VueI18n({ - locale: 'pt', - modifiers: { - // Adicionando um novo modificador - snakeCase: str => str.split(' ').join('-') - }, - messages: { - // ... - }, -}) -``` - -### Agrupando com parêntese - -Uma chave de tradução de uma mensagem também pode ser especificada com `@:(message.foo.bar.baz)`, onde a referência a outra chave de tradução está entre parêntese `()`. - -Isso pode ser necessário se um ponto `.` for exigido após um link para outra mensagem `@:message.something`, que de outra forma seria considerado parte do link. - -Mensagens de localização: - -```js -const messages = { - en: { - message: { - dio: 'DIO', - linked: "There's a reason, you lost, @:(message.dio)." - } - }, - pt: { - message: { - dio: 'DIO', - linked: "Há uma razão pela qual você falhou, @:(message.dio)." - } - } -} -``` - -Template: - -```html -

{{ $t('message.linked') }}

-``` - -O resultado será o seguinte: - -```html -

Há uma razão pela qual você falhou, DIO.

-``` - -## Mensagem com função - -vue-i18n recomenda o uso de strings para formatação de lista ou formatação nomeada como mensagem de localização ao traduzir as mensagens. - -No entanto, existem situações em que, devido à sintaxe complexa da linguagem, todo o poder do JavaScript é necessário. Nesse caso, em vez de mensagens de string, você pode usar **uma mensagem com função**. - -A função abaixo retorna uma saudação: - -```js -const messages = { - en: { - greeting: (ctx) => 'Hello!' - }, - pt: { - greeting: (ctx) => 'Olá!' - } -} -``` - -Usar a função da mensagem é fácil! Você só precisa especificar a chave usando `$t` ou `t`: - -```html -

{{ $t('greeting') }}

-``` - -O resultado será o seguinte: - -```html -

Olá!

-``` - -O resultado de retorno da função é usado para a mensagem. - -### Formatação nomeada - -vue-i18n suporta [formatação nomeada](./formatting.md#named-formatting) como um formato de mensagem baseado em string. vue-i18n interpola os valores dos parâmetros com `$t` ou `t`, e os retorna. - -O mesmo pode ser feito com a função da mensagem usando o **contexto de mensagem**: - -Aqui está o exemplo de saudação: - -```js -const messages = { - en: { - greeting: (ctx) => `Hello, ${ctx.named('name')}!` - }, - pt: { - greeting: (ctx) => `Olá, ${ctx.named('name')}!` - } -} -``` - -Template: - -```html -

{{ $t('greeting', { name: 'DIO' }) }}

-``` - -O resultado será o seguinte: - -```html -

Olá, DIO!

-``` - -O contexto da mensagem fornece acesso à função `named`. Você deve especificar a chave especificada para `$t` ou `t`, que resolverá com o valor necessário. - -### Formatação de lista - -O uso da formatação de lista é semelhante ao formatação nomeada descrito acima. - -vue-i18n suporta [formatação de lista](./formatting.md#list-formatting) para mensagens de string. vue-i18n interpola os valores dos parâmetros com `$t` ou `t`, e os retorna. - -O mesmo pode ser feito com a função da mensagem usando o **contexto de mensagem**: - -Aqui está o exemplo de saudação: - -```js -const messages = { - en: { - greeting: (ctx) => `Hello, ${ctx.list(0)}!` - }, - pt: { - greeting: (ctx) => `Olá, ${ctx.list(0)}!` - } -} -``` - -Template: - -```html -

{{ $t('greeting', ['DIO']) }}

-``` - -O resultado será o seguinte: - -```html -

Olá, DIO!

-``` - -O contexto da mensagem fornece acesso à função `list`. Você deve especificar a chave especificada para `$t` ou `t`, que resolverá com o valor necessário. - -### Limitação - -Em uma função para mensagem, os seguintes recursos, que estão disponíveis em uma versão de string, não estarão disponíveis por meio do contexto da mensagem: - -- Mensagens de localidade vinculadas -- Pluralização diff --git a/docs-old/pt/guide/number.md b/docs-old/pt/guide/number.md deleted file mode 100644 index a388f386a..000000000 --- a/docs-old/pt/guide/number.md +++ /dev/null @@ -1,142 +0,0 @@ -# Localização de números - -:::tip Suporta a versão -:new: 7.0+ -::: - -Você pode localizar números com seus formatos de definição. - -Formato de exemplo para números: - -```js -const numberFormats = { - 'en-US': { - currency: { - style: 'currency', - currency: 'USD' - } - }, - 'pt-BR': { - currency: { - style: 'currency', - currency: 'BRL', - currencyDisplay: 'symbol' - } - } -} -``` - -Conforme declarado acima, você pode especificar formatos numéricos (por exemplo, `currency` para moeda) usando opções [ECMA-402 Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat). - -Depois disso, para poder usar este formato em mensagens de localização, você precisa definir a opção `numberFormats` do construtor na instância `VueI18n`: - -```js -const i18n = new VueI18n({ - numberFormats -}) - -new Vue({ - i18n -}).$mount('#app') -``` - -Template: - -```html -
-

{{ $n(100, 'currency') }}

-

{{ $n(100, 'currency', 'pt-BR') }}

-
-``` - -O resultado será o seguinte: - -```html -
-

$100.00

-

100,00 ₽

-
-``` - -## Formatação personalizada - -:::tip Suporta a versão -:new: 8.10+ -::: - -O método `$n` retorna o resultado como uma string numérica totalmente formatada que só pode ser usada em sua totalidade. Nos casos em que você precisa estilizar alguma parte de um número formatado (por exemplo, uma parte fracionária), `$n` não será suficiente. Nesses casos, é necessário usar o componente funcional `` será útil. - -Com um conjunto mínimo de propriedades, `` gera o mesmo resultado que `$n` envolvido em um elemento DOM configurado. - -Template: - -```html -
- - - -
-``` - -O resultado será o seguinte: - -```html -
- 100 - $100.00 - R$ 100,00 -
-``` - -O verdadeiro poder deste componente entra em ação quando é usado com [slots com escopo](https://br.vuejs.org/v2/guide/components-slots.html#Slots-com-Escopo-Definido). - -Digamos que haja um requisito para exibir a parte inteira de um número em negrito. Isso pode ser obtido especificando `integer` no elemento do slot com escopo: - -```html - - - {{ slotProps.integer }} - - -``` - -O resultado será o seguinte: - -```html -$100.00 -``` - -É possível especificar vários slots com escopo ao mesmo tempo: - -```html - - - {{ slotProps.currency }} - - - {{ slotProps.integer }} - - - {{ slotProps.group }} - - - {{ slotProps.fraction }} - - -``` - -(O HTML de resultado abaixo é formatado para melhor legibilidade) - -```html - - - 1 - , - 234 - 00 - -``` - -Você pode especificar o tipo do elemento raiz usando o parâmetro de entrada `tag`. Se nenhum parâmetro de entrada for especificado, o padrão é `'span'`. Você também pode defini-lo com o valor booleano `false` para inserir os nós filhos diretamente sem criar um elemento raiz. - -A lista completa dos slots de escopo suportados, bem como outras propriedades ``, pode ser encontradas [na página da API](../api/readme.md#i18n-n-functional-component). diff --git a/docs-old/pt/guide/pluralization.md b/docs-old/pt/guide/pluralization.md deleted file mode 100644 index db9ed5ab8..000000000 --- a/docs-old/pt/guide/pluralization.md +++ /dev/null @@ -1,174 +0,0 @@ -# Pluralização - -Você pode usar pluralização para mensagens traduzidas. Para fazer isso, precisa definir a localidade e especificar as strings de tradução para os diferentes casos por meio do separador `|`. - -*Seu template precisará usar `$tc()` em vez de `$t()`.* - -Mensagens locais abaixo: - -```js -const messages = { - en: { - car: 'car | cars', - apple: 'no apples | one apple | {count} apples' - }, - pt: { - car: 'carro | carros', - apple: 'sem maçãs | uma maçã | {count} maçãs' - } -} -``` - -Template: - -```html -

{{ $tc('car', 1) }}

-

{{ $tc('car', 2) }}

- -

{{ $tc('apple', 0) }}

-

{{ $tc('apple', 1) }}

-

{{ $tc('apple', 10, { count: 10 }) }}

-``` - -O resultado será o seguinte: - -```html -

carro

-

carros

- -

sem maçãs

-

uma maçã

-

10 maçãs

-``` - -## Acessando o número por meio do argumento predefinido - -Não há necessidade de passar explicitamente o número para pluralização. Em mensagens de localização, um número está disponível através dos argumentos nomeados `{count}` e/ou `{n}`. Você pode substituí-los, se desejar. - -Mensagens locais abaixo: - -```js -const messages = { - en: { - apple: 'no apples | one apple | {count} apples', - banana: 'no bananas | {n} banana | {n} bananas' - }, - pt: { - apple: 'sem maçãs | uma maçã | {count} maçãs' - banana: 'sem bananas | {n} banana | {n} bananas' - } -} -``` - -Template: - -```html -

{{ $tc('apple', 10, { count: 10 }) }}

-

{{ $tc('apple', 10) }}

- -

{{ $tc('banana', 1, { n: 1 }) }}

-

{{ $tc('banana', 1) }}

-

{{ $tc('banana', 100, { n: 'Muitas' }) }}

-``` - -O resultado será o seguinte: - -```html -

10 maçãs

-

10 maçãs

- -

1 banana

-

1 banana

-

Muitas bananas

-``` - -## Pluralização personalizadas - -Essa pluralização, entretanto, não se aplica a todas as línguas (as línguas eslavas, por exemplo, têm regras de pluralização diferentes). - -Para implementar essas regras, você pode passar um objeto `pluralizationRules` opcional para as opções do construtor `VueI18n`. - -Um exemplo simplificado para idiomas eslavos (russo, ucraniano e outros): -```js -new VueI18n({ - // Key - idioma para usar a regra, `'ru'`, neste caso - // Value - função para escolher a forma plural correta - pluralizationRules: { - /** - * @param choice {number} um índice de escolha dado pela entrada de $tc: `$tc('path.to.rule', choiceIndex)` - * @param choicesLength {number} quantidade geral de opções disponíveis - * @returns índice final para selecionar as palavras no plural - */ - 'ru': function(choice, choicesLength) { - // this === Instância VueI18n, então a propriedade locale também existe aqui - - if (choice === 0) { - return 0; - } - - const teen = choice > 10 && choice < 20; - const endsWithOne = choice % 10 === 1; - - if (choicesLength < 4) { - return (!teen && endsWithOne) ? 1 : 2; - } - if (!teen && endsWithOne) { - return 1; - } - if (!teen && choice % 10 >= 2 && choice % 10 <= 4) { - return 2; - } - - return (choicesLength < 4) ? 2 : 3; - } - } -}) -``` - -Essa implementação permitirá que você use: - -```js -const messages = { - ru: { - car: '0 машин | {n} машина | {n} машины | {n} машин', - banana: 'нет бананов | {n} банан | {n} банана | {n} бананов' - } -} -``` - -Onde o formato é `0 coisas | número de itens termina em 1 | o número de coisas que termina em 2-4 | o número de coisas que termina com 5-9, 0 e o número coisas que termina de 11 a 19`. -P.S. A pluralização eslava é complexa, você pode ler mais sobre isso [aqui](http://www.russianlessons.net/lessons/lesson11_main.php). - -No template, você ainda precisa usar `$tc()` em vez de `$t()`: - -```html -

{{ $tc('car', 1) }}

-

{{ $tc('car', 2) }}

-

{{ $tc('car', 4) }}

-

{{ $tc('car', 12) }}

-

{{ $tc('car', 21) }}

- -

{{ $tc('banana', 0) }}

-

{{ $tc('banana', 4) }}

-

{{ $tc('banana', 11) }}

-

{{ $tc('banana', 31) }}

-``` - -O resultado será o seguinte: - -```html -

1 машина

-

2 машины

-

4 машины

-

12 машин

-

21 машина

- -

нет бананов

-

4 банана

-

11 бананов

-

31 банан

-``` - -### Pluralização padrão - -Se nenhuma regra de pluralização for fornecida para a localidade em uso, a regra [padrão](#pluralizacao) do idioma inglês será usada. diff --git a/docs-old/pt/guide/sfc.md b/docs-old/pt/guide/sfc.md deleted file mode 100644 index d5e06460c..000000000 --- a/docs-old/pt/guide/sfc.md +++ /dev/null @@ -1,410 +0,0 @@ -# Componentes de arquivo único - -## Uso básico - -Se você estiver construindo um componente ou aplicativo Vue usando componentes de arquivo único, você pode gerenciar as mensagens de localização usando um bloco `i18n` personalizado. - -Código de componente com [exemplo de componentes de arquivo único](https://github.com/kazupon/vue-i18n/tree/dev/examples/sfc): - -```vue - -{ - "en": { - "hello": "Hello World!" - }, - "pt": { - "hello": "Olá Mundo!" - } -} - - - - - -``` - -## Instalação vue-i18n-loader - -Você precisa instalar `vue-loader` e `vue-i18n-loader` devido ao uso de blocos personalizados ``. Embora [vue-loader](https://github.com/vuejs/vue-loader) provavelmente já seja usado em seu projeto se você estiver trabalhando com componentes de arquivo único, mas você vai precisar instalar [vue-i18n-loader](https://github.com/kazupon/vue-i18n-loader) adicionalmente: - -```bash -npm i --save-dev @kazupon/vue-i18n-loader -``` - -## Webpack - -O Webpack requer a seguinte configuração: - -Para vue-loader v15 ou posterior: - -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader' - }, - { - resourceQuery: /blockType=i18n/, - type: 'javascript/auto', - loader: '@kazupon/vue-i18n-loader' - } - // ... - ] - } - // ... -} -``` - -Para vue-loader v14: - -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - loaders: { - // você precisa especificar a chave do carregador `i18n` com o `vue-i18n-loader` - // (https://github.com/kazupon/vue-i18n-loader) - i18n: '@kazupon/vue-i18n-loader' - } - } - } - // ... - ] - } - // ... -} -``` - -## Vue CLI 3.0 - -[Vue CLI 3.0](https://github.com/vuejs/vue-cli) ocultar a configuração do Webpack, portanto, para adicionar suporte para tags `` em componentes de arquivo único, precisamos modificar a configuração existente. - -Para fazer isso, temos que criar um `vue.config.js` na raiz do nosso projeto. Depois de fazer isso, devemos incluir o seguinte código: - -Para vue-loader v15 ou posterior: - -```js -module.exports = { - chainWebpack: config => { - config.module - .rule('i18n') - .resourceQuery(/blockType=i18n/) - .type('javascript/auto') - .use('i18n') - .loader('@kazupon/vue-i18n-loader') - .end() - } -} -``` - -Para vue-loader v14: - -```js -const merge = require('deepmerge') - -module.exports = { - chainWebpack: config => { - config.module - .rule('vue') - .use('vue-loader') - .tap(options => - merge(options, { - loaders: { - i18n: '@kazupon/vue-i18n-loader' - } - }) - ) - } -} -``` - -_Não se esqueça de instalar o [deepmerge](https://github.com/KyleAMathews/deepmerge)! (`npm i deepmerge -D` ou `yarn add deepmerge -D`)_ - -Você pode aprender mais sobre as possibilidades de modificar a configuração do Webpack existente [neste guia](https://cli.vuejs.org/guide/webpack.html). - -## Laravel-Mix - -Para Laravel-mix 4 com vue-loader v15 ou posterior: - -```js -// Estenda o Mix usando o método "i18n", que carrega o vue-i18n-loader -mix.extend( 'i18n', new class { - webpackRules() { - return [ - { - resourceQuery: /blockType=i18n/, - type: 'javascript/auto', - loader: '@kazupon/vue-i18n-loader', - }, - ]; - } - }(), -); - -// Certifique-se de chamar .i18n() para carregar o loader antes do .js(..., ...) -mix.i18n() - .js( 'resources/js/App.js', 'public/js/app.js' ) - ... -``` - -para Laravel-mix 2 com vue-loader v14: - -No Laravel-mix, começando na versão [V2.1](https://github.com/JeffreyWay/laravel-mix/releases/tag/v2.1), você pode adicionar regras personalizadas usando `mix.extend()`. O Laravel-mix já possui suas próprias regras para lidar com arquivos `.vue`. Para adicionar `vue-i18n-loader`, no arquivo `webpack.mix.js` adicione o seguinte código: - -```js -// O código a seguir injetará o i18n Kazupon/vue-18-loader como o loader de arquivos .vue -mix.extend( 'i18n', function( webpackConfig, ...args ) { - webpackConfig.module.rules.forEach( ( module ) => { - // Procure o componente "vue-loader", que processa os arquivos .vue - if( module.loader !== 'vue-loader' ) { - return; - } - - // Neste módulo, adicione o vue-i18n-loader para a tag i18n. - module.options.loaders.i18n = '@kazupon/vue-i18n-loader'; - } ); -} ); - -// Certifique-se de chamar .i18n() para carregar o loader antes de .js(..., ...) -mix.i18n() - .js( 'resources/assets/js/App.js', 'public/js/app.js' ) - ... -``` - -## Carregando YAML - -Os blocos personalizados `i18n` podem ser especificados no formato `JSON` ou `YAML` usando o recurso de pré-carregador do `vue-loader`. - -Os blocos personalizados `i18n` no formato `YAML`: - -```vue - - en: - hello: "Hello World!" - pt: - hello: "Olá Mundo!" - -``` - -Configuração do Webpack: - -Para vue-loader v15 ou posterior: - -```js -// Vue CLI 3.0 -module.exports = { - chainWebpack: config => { - config.module - .rule('i18n') - .resourceQuery(/blockType=i18n/) - .type('javascript/auto') - .use('i18n') - .loader('@kazupon/vue-i18n-loader') - .end() - .use('yaml') - .loader('yaml-loader') - .end() - } -} -``` - -Para vue-loader v14: - -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - preLoaders: { - i18n: 'yaml-loader' - }, - loaders: { - i18n: '@kazupon/vue-i18n-loader' - } - } - } - // ... - ] - } - // ... -} -``` - -## Vários blocos personalizados - -Você pode usar mensagens de localização com vários blocos personalizados `i18n`. - -```vue - - - { - "en": { - "hello": "Hello World!" - }, - "pt": { - "hello": "Olá Mundo!" - } - } - -``` - -No exemplo acima, o primeiro bloco personalizado carrega as mensagens de localização genérica usando o atributo `src`, o segundo bloco personalizado carrega as mensagens de localização que são definidas apenas neste componente de arquivo único. Todos eles serão mesclados com mensagens de localização de componentes. - -Desta forma, vários blocos personalizados são úteis quando usados ​​como módulos. - -## Estilos Locais - -Ao usar `vue-i18n` com estilos locais `style scoped`, é importante lembrar de usar [deep selector](https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors) para estilizar o elemento __*dentro*__ da string de tradução. - -Por exemplo: - -__Quando a tradução contém apenas texto__ (funciona sem deep selector) - -```vue - - { - "en": { - "hello": "Hello World!" - }, - "pt": { - "hello": "Olá Mundo!" - } - } - - - - - - -``` - -__Tradução que contém elemento HTML__ (deve usar deep selector) - -```vue - - { - "en": { - "hello": "Hello World!" - }, - "pt": { - "hello": "Olá Mundo!" - } - } - - - - - - - - - - - - - - - -``` - -## Blocos personalizados em componente funcional - -Se os componentes de arquivo único têm o template usando um componente funcional, e você definiu blocos personalizados `i18n`, observe que você não pode localizar usando mensagens de local. - -Por exemplo, o código a seguir não pode usar mensagens de localização do bloco `i18n`. - -```vue - - { - "en": { - "hello": "Hello World" - }, - "pt": { - "hello": "Olá Mundo" - } - } - - - -``` diff --git a/docs-old/pt/guide/tooling.md b/docs-old/pt/guide/tooling.md deleted file mode 100644 index f05d23595..000000000 --- a/docs-old/pt/guide/tooling.md +++ /dev/null @@ -1,72 +0,0 @@ -# Ferramentas - -Para suportar os aplicativos i18n do Vue, algumas ferramentas são fornecidas oficialmente. - -Existem também ferramentas de terceiros que integram o Vue I18n. - -## Ferramentas oficiais - -### Plugin para Vue CLI - -[vue-cli-plugin-i18n](https://github.com/kazupon/vue-cli-plugin-i18n) é o plugin oficial para o Vue CLI. - -Com este plugin, você pode configurar um ambiente i18n para seu aplicativo Vue e oferecer suporte ao ambiente de desenvolvimento i18n. - -### Módulo para Nuxt - -[nuxt-i18n](https://github.com/nuxt-community/nuxt-i18n/) é o módulo correspondente para Nuxt.js. - -### Loader para Webpack - -[vue-i18n-loader](https://github.com/kazupon/vue-i18n-loader) — é o loader para webpack oficial. - -Com este loader é possível usar blocos `i18n` personalizados em componentes de arquivo único. - -Para obter mais informações sobre blocos `i18n` personalizados, consulte [Componentes de arquivo único](./sfc.md) - -### Plugin para ESLint - -[eslint-plugin-vue-i18n](https://intlify.github.io/eslint-plugin-vue-i18n/) - Plug-in ESLint para Vue I18n. - -Permite que você integre facilmente alguns recursos de localização do lint ao seu aplicativo Vue.js. - -### Extensões - -[vue-i18n-extensions](https://github.com/kazupon/vue-i18n-extensions) fornece algumas extensões para Vue I18n. - -Você pode usar esta extensão para habilitar o SSR e melhorar o desempenho do i18n. - -## Ferramentas de terceiros - -### BabelEdit - -[BabelEdit](https://www.codeandweb.com/babeledit) é um editor de tradução para aplicativos da web. - -O BabelEdit pode traduzir arquivos `json` e também pode trabalhar com blocos personalizados `i18n` de componentes de arquivo único. - -Mais informações sobre o BabelEdit podem ser encontradas na página de [introdução](https://www.codeandweb.com/babeledit/tutorials/how-to-translate-your-vue-app-with-vue-i18n). - -### i18n Ally - -[i18n Ally] (https://marketplace.visualstudio.com/items?itemName=antfu.i18n-ally) é uma extensão i18n para VSCode. - -i18n Ally oferece um DX(Experiência do desenvolvedor) incrível para o desenvolvimento de i18n. - -Você pode aprender mais sobre a extensão i18n Ally em [README](https://github.com/antfu/i18n-ally/blob/master/README.md). - -### i18nPlugin (plataforma intellij) - -[i18nPlugin](https://github.com/nyavro/i18nPlugin) — Plugin de suporte para idea Intellij i18next ([Página do plugin Jetbrains](https://plugins.jetbrains.com/plugin/12981-i18n-support)). - -Plugin para i18n typescript/javascript/PHP. Suporta vue-i18n. Para habilitar o suporte a vue-i18n vá em configurações -> Ferramentas -> Configuração do plugin i18n e selecione "Vue-i18n". É necessário instalar os diretórios com os arquivos de tradução (tradução por padrão). - -### vue-i18n-extract - -[vue-i18n-extract](https://github.com/pixari/vue-i18n-extract) faz uma análise estática de um projeto Vue.js com base em vue-i18n e relata as seguintes informações: - -- lista de todas as **chaves vue-i18n não utilizadas** (entradas encontradas nos arquivos de idioma, mas não utilizadas no projeto) -- lista de todas as **chaves ausentes** (entradas encontradas no projeto, mas não nos arquivos de idioma) - -É possível mostrar a saída no console ou gravá-la em um arquivo json. - -As chaves ausentes também podem ser adicionadas automaticamente aos arquivos de tradução fornecidos. diff --git a/docs-old/pt/installation.md b/docs-old/pt/installation.md deleted file mode 100644 index dc51f35af..000000000 --- a/docs-old/pt/installation.md +++ /dev/null @@ -1,85 +0,0 @@ -# Instalação - -## Nota de compatibilidade - -- Vue.js versões `2.0.0`+ - -## Download direto / CDN - - - -O serviço [unpkg.com](https://unpkg.com) fornece links CDN com base em pacotes NPM. O link acima sempre apontará para a versão mais recente do NPM. Você pode usar uma versão ou tag específica usando um URL como este - -Ao conectar o vue-i18n após o Vue, o plug-in será instalado automaticamente: - -```html - - -``` - -## NPM - -```bash -npm install vue-i18n -``` - -## Yarn - -```bash -yarn add vue-i18n -``` - -Ao usar o sistema de módulos, você deve definir explicitamente `vue-i18n` -via `Vue.use()`: - -```js -import Vue from 'vue' -import VueI18n from 'vue-i18n' - -Vue.use(VueI18n) -``` - -Você não precisa fazer isso ao usar tags de script globais ` - - -
-

{{ $t("message.hello") }}

-
-``` - -## JavaScript - -```js -// Se você usa um sistema de módulos (p. ex. via vue-cli) -// Importe o Vue e VueI18n assim utilize-o Vue.use(VueI18n). -// -// import Vue from 'vue' -// import VueI18n from 'vue-i18n' -// -// Vue.use(VueI18n) - -// Mensagens traduzidas de suas localidades -const messages = { - en: { - message: { - hello: 'Hello World' - } - }, - pt: { - message: { - hello: 'Olá Mundo' - } - } -} - -// Crie uma instância do VueI18n com opções -const i18n = new VueI18n({ - locale: 'pt', // Defina uma localidade - messages, // Defina as mensagens -}) - - -// Crie uma instância Vue com a opção `i18n` -new Vue({ i18n }).$mount('#app') - -// Pronto agora o aplicativo foi iniciado! -``` - -O resultado será o seguinte: - -```html -
-

Olá Mundo

-
-``` diff --git a/docs-old/ru/README.md b/docs-old/ru/README.md deleted file mode 100644 index 869cdb4c1..000000000 --- a/docs-old/ru/README.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -home: true -heroImage: ./../vue-i18n-logo.png -actionText: Введение → -actionLink: introduction.md -footer: MIT Licensed | Copyright © 2020 kazuya kawaguchi ---- - -
-

🥇 Золотые спонсоры

- - Nuxt.js - -

🥈 Серебряные спонсоры

- - Редактор переводов BabelEdit для приложений (веб-приложений) - -

🥉 Бронзовые спонсоры

- - zenarchitects - - - sendcloud - -
- -
- -
- -
-
-

Простой

-

Позволяет легко добавить интернационализацию в приложение с помощью простого API

-
-
-

Функциональный

-

В дополнение к переводам, поддерживает плюрализацию, локализацию для чисел, дат ... и т.д.

-
-
-

Ориентированный на компоненты

-

Можно управлять сообщениями локализации в однофайловых компонентах

-
-
diff --git a/docs-old/ru/api/README.md b/docs-old/ru/api/README.md deleted file mode 100644 index 8b7849243..000000000 --- a/docs-old/ru/api/README.md +++ /dev/null @@ -1,922 +0,0 @@ ---- -sidebar: auto ---- - -# Справочник API - -## Расширение прототипа Vue - -### Опции конструктора Vue - -#### i18n - -* **Тип:** `I18nOptions` - -Опция локализации на основе компонентов. - -* **См. также:** Опции конструктора класса `VueI18n` - -### Внедряемые методы - -#### $t - -* **Аргументы:** - - * `{Path} key`: обязательный - * `{Locale} locale`: опционально - * `{Array | Object} values`: опционально - -* **Возвращает:** `TranslateResult` - -Получение переведённого сообщения по ключу `key`. Сообщения локализации в компоненте имеют приоритет над глобальными сообщениями. Если сообщений локализации в компоненте нет, то локализация осуществляется с помощью глобальных сообщений локализации. Если указана `locale`, то используются сообщения локализации из `locale`. Если был указан `key` именованного формата / формата списков сообщений локализации, то необходимо указывать также `values`. Подробнее про значения `values` можно изучить в разделе [Формат сообщений локализации](../guide/formatting.md). - -:::danger Совет -Обратите внимание, что в хуках жизненного цикла контекст должен быть экземпляром компонента (например в опции `data`, `const $t = this.$t.bind(this)`). -::: - -#### $tc - -* **Аргументы:** - - * `{Path} key`: обязательный - * `{number} choice`: опционально, по умолчанию `1` - * `{Locale} locale`: опционально - * `{string | Array | Object} values`: опционально - -* **Возвращает:** `TranslateResult` - -Получение переведённого сообщения по ключу `key` с использованием плюрализации. Сообщения локализации компонента имеют приоритет над глобальными сообщениями. Если сообщений локализации в компоненте нет, то локализация осуществляется с помощью глобальных сообщений локализации. Если указана `locale`, то используются сообщения локализации из `locale`. Если указано строковое значение для `values`, то локализация выполняется для этого значения. Если указано значение Array или Object в `values`, то необходимо указывать с `values` из $t. - -Если вам не подходит реализация плюрализации по умолчанию, смотрите [pluralization rules в опциях конструктора](#pluralizationrules) и [пользовательскую плюрализацию](../guide/pluralization.md). - -:::danger Совет -Обратите внимание, что в хуках жизненного цикла контекст должен быть экземпляром компонента (например в опции `data`, `const $tc = this.$tc.bind(this)`). -::: - -#### $te - -* **Аргументы:** - - * `{Path} key`: обязательный - * `{Locale} locale`: опционально - -* **Возвращает:** `boolean` - -Проверяет существует ли перевод для ключа в сообщениях локализации. Если нет сообщений локализации в компоненте, то проверяет в глобальных сообщениях локализации. Если указана `locale`, то проверяется наличие в сообщениях локализации `locale`. - -:::danger Совет -Обратите внимание, что в хуках жизненного цикла контекст должен быть экземпляром компонента (например в опции `data`, `const $te = this.$te.bind(this)`). -::: - -#### $d - -> :new: Добавлено в версии 7.0+ - -* **Аргументы:** - - * `{number | Date} value`: обязательный - * `{Path | Object} key`: опционально - * `{Locale | Object} locale`: опционально - -* **Возвращает:** `DateTimeFormatResult` - -Локализация даты из `value` по указанному формату даты из `key`. Формат указанный в `key` должен быть зарегистрирован в опции `dateTimeFormats` класса `VueI18n`, и зависит от опции `locale` конструктора `VueI18n`. Если указать аргумент `locale`, то он будет иметь приоритет над опцией `locale` конструктора `VueI18n`. - -Если формата даты для `key` нет в опции `dateTimeFormats`, то будет использован запасной формат, основываясь на опции `fallbackLocale` конструктора `VueI18n`. - -:::danger Совет -Обратите внимание, что в хуках жизненного цикла контекст должен быть экземпляром компонента (например в опции `data`, `const $d = this.$d.bind(this)`). -::: - -#### $n - -> :new: Добавлено в версии 7.0+ - -* **Аргументы:** - - * `{number} value`: обязательный - * `{Path | Object} format`: опционально - * `{Locale} locale`: опционально - -* **Возвращает:** `NumberFormatResult` - -Локализация числа `value` с помощью формата чисел `format`. Числовой формат из `format` должен быть зарегистрирован в опции `numberFormats` класса `VueI18n`, и зависит от опции `locale` конструктора `VueI18n`. Если указать аргумент `locale`, то он будет иметь приоритет над опцией `locale` конструктора `VueI18n`. - -Если формат чисел для `format` не указан в опции `numberFormats`, будет использован запасной формат, основываясь на опции `fallbackLocale` конструктора `VueI18n`. - -Если второй аргумент `format` указан объектом, то в нём должны быть следующие свойства: - -* `key {Path}`: опционально, форматируемое число -* `locale {Locale}`: опционально, локализация -* `compactDisplay {string}`: опционально, опция форматирования чисел -* `currency {string}`: опционально, опция форматирования чисел -* `currencyDisplay {string}`: опционально, опция форматирования чисел -* `currencySign {string}`: опционально, опция форматирования чисел -* `localeMatcher {string}`: опционально, опция форматирования чисел -* `notation {string}`: опционально, опция форматирования чисел -* `numberingSystem {string}`: опционально, опция форматирования чисел -* `signDisplay {string}`: опционально, опция форматирования чисел -* `style {string}`: опционально, опция форматирования чисел -* `unit {string}`: опционально, опция форматирования чисел -* `unitDisplay {string}`: опционально, опция форматирования чисел -* `useGrouping {string}`: опционально, опция форматирования чисел -* `minimumIntegerDigits {string}`: опционально, опция форматирования чисел -* `minimumFractionDigits {string}`: опционально, опция форматирования чисел -* `maximumFractionDigits {string}`: опционально, опция форматирования чисел -* `minimumSignificantDigits {string}`: опционально, опция форматирования чисел -* `maximumSignificantDigits {string}`: опционально, опция форматирования чисел - -Любые указанные опции форматирования числа будут иметь приоритет над значениями `numberFormats` из конструктора `VueI18n`. - -:::danger Совет -Обратите внимание, что в хуках жизненного цикла контекст должен быть экземпляром компонента (например в опции `data`, `const $n = this.$n.bind(this)`). -::: - -### Внедряемые свойства - -#### $i18n - -* **Тип:** `I18n` - -* **Только для чтения** - -Получение экземпляра `VueI18n`, если был определён. - -Если в компоненте указана опция `i18n`, то получение экземпляра `VueI18n` компонента. В противном случае, получение корневого экземпляра `VueI18n`. - -## Класс `VueI18n` - -Класс `VueI18n` реализует интерфейс `I18n` из [определений flowtype](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -### Статические свойства - -#### version - -* **Тип:** `string` - -Версия `vue-i18n`. - -#### availabilities - -> :new: Добавлено в версии 7.0+ - -* **Тип:** `IntlAvailability` - -Проверка доступности следующих возможностей интернационализации: - -* `{boolean} dateTimeFormat`: форматирование дат для локалей - -* `{boolean} numberFormat`: форматирование чисел для локалей - -Указанные выше возможности интернационализации зависят от [окружения браузера](http://kangax.github.io/compat-table/esintl/), в котором реализован ECMAScript Internationalization API (ECMA-402). - -### Опции конструктора - -Можно указывать некоторые опции конструктора `I18nOptions`, основываясь на [определениях flowtype](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -#### locale - -* **Тип:** `Locale` - -* **По умолчанию:** `'en-US'` - -Локаль используемая для локализации. Если локаль содержит территорию и диалект, то эта локаль явно определяет запасную локализацию. - -#### fallbackLocale - -* **Тип:** `FallbackLocale` - -* **По умолчанию:** `false` - -Запасная локаль для локализации. Подробнее в разделе [Запасная локализация](../guide/fallback.md). - -#### messages - -* **Тип:** `LocaleMessages` - -* **По умолчанию:** `{}` - -Сообщения локализации для локали. - -#### dateTimeFormats - -> :new: Добавлено в версии 7.0+ - -* **Тип:** `DateTimeFormats` - -* **По умолчанию:** `{}` - -Форматы дат для локализации. - -* **См. также:** тип `DateTimeFormats` в [определениях flowtype](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -#### numberFormats - -> :new: Добавлено в версии 7.0+ - -* **Тип:** `NumberFormats` - -* **По умолчанию:** `{}` - -Форматы чисел для локализации. - -* **См. также:** тип `NumberFormats` в [определениях flowtype](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -#### availableLocales - -> :new: Добавлено в версии 8.9.0+ - -* **Тип:** `Locale[]` - -* **По умолчанию:** `[]` - -* **Примеры:** `["en", "ru"]` - -Список доступных локалей в `messages` в лексическом порядке. - -#### formatter - -* **Тип:** `Formatter` - -* **По умолчанию:** Встроенный formatter - -Метод форматирования, реализующий интерфейс `Formatter`. - -#### modifiers - -> :new: Добавлено в версии 8.15.0+ - -* **Тип:** `Modifiers` - -* **По умолчанию:** модификаторы `lower` и `upper` - -Функции модификаторов для связанных сообщений - -#### missing - -* **Тип:** `MissingHandler` - -* **По умолчанию:** `null` - -Обработчик для отсутствующих сообщений локализации. Обработчик будет вызван с локалью, ключом сообщения локализации и значениями values. - -Если указан этот обработчик и произойдёт попытка доступа к отсутствующему сообщению локализации, то предупреждения в консоли не будет. - -#### fallbackRoot - -* **Тип:** `Boolean` - -* **По умолчанию:** `true` - -При использовании локализации в компонентах определяет обращаться ли к локализации корневого уровня (глобальной) при неудаче. - -При значении `false` будет выбрасываться предупреждение и возвращаться ключ. - -#### sync - -* **Тип:** `Boolean` - -* **По умолчанию:** `true` - -Синхронизировать ли локализацию корневого уровня с локализацией компонента. - -При значении `false`, независимо от локали определённой на корневом уровне, будет использоваться локаль установленная в компоненте. - -#### silentTranslationWarn - -> 6.1+, :up: 8.13 - -* **Тип:** `Boolean | RegExp` - -* **По умолчанию:** `false` - -Отключение предупреждений, отображаемых при неудаче локализации. - -При значении `true`, отключаются предупреждения об ошибках локализации. Если использовать регулярное выражение, то можно отключать предупреждения об ошибках, которые будут соответствовать `key` (например, `$t`). - -#### silentFallbackWarn - -> :new: Добавлено в версии 8.8+, :up: 8.13 - -* **Тип:** `Boolean | RegExp` - -* **По умолчанию:** `false` - -Отключение предупреждений при использовании запасной локали из `fallbackLocale` или `root`. - -При значении `true` предупреждения будут генерироваться только если недоступна локализация вообще, а не для случаев использования запасной локали. При использовании регулярного выражения можно отключать предупреждения которые будут соответствовать `key` (например, `$t`). - -#### pluralizationRules - -> 8.5+ - - * **Тип:** `PluralizationRules` - - * **По умолчанию:** `{}` - - Набор правил для плюрализации в следующем формате: - ```js - { - // Ключ - локаль для которой будет применяться правило. - // Value - функция для получения индекса варианта плюрализации от текущего числа и заданного количества вариантов. (См. функцию getChoiceIndex) - 'pt': function(choice, choiceIndex) => Number/* index of the plural word */; - 'ru': function(choice, choiceIndex) => Number/* index of the plural word */; - 'en': function(choice, choiceIndex) => Number/* index of the plural word */; - 'jp': function(choice, choiceIndex) => Number/* index of the plural word */; - } - ``` - -#### preserveDirectiveContent - -> Добавлено в версии 8.7+ - -* **Тип:** `Boolean` - -* **По умолчанию:** `false` - -Определяет должен ли элемент директивы `v-t` сохранять `textContent` после того как директива будет снята с элемента. - -#### warnHtmlInMessage - -> Добавлено в версии 8.11+ - -* **Тип:** `WarnHtmlInMessageLevel` - -* **По умолчанию:** `off` - -Разрешить ли использование HTML-форматирования в сообщениях локализации. См. также свойство `warnHtmlInMessage`. - -:::danger Внимание! -Со следующей мажорной версии значение по умолчанию `warnHtmlInMessage` будет `warn`. -::: - -#### sharedMessages - -> Добавлено в версии 8.12+ - -* **Тип:** `LocaleMessages` - -* **По умолчанию:** `undefined` - -Общие сообщения локализации при локализации в компонентах. Подробнее в разделе [Локализация на основе компонентов](../guide/component.md#локаnизация-на-основе-компонентов). - -#### postTranslation - -> Добавлено в версии 8.16+ - -* **Тип:** `PostTranslationHandler` - -* **По умолчанию:** `null` - -Пост-обработчик локализации. Выполняется после вызова `$t`, `t`, `$tc` и `tc`. - -Может пригодиться при необходимости дополнительно обработать итоговый текст перевода, например избавиться от висящих пробелов. - -#### componentInstanceCreatedListener - -> Добавлено в версии 8.18+ - -* **Тип:** `ComponentInstanceCreatedListener` - -* **По умолчанию:** `null` - -Обработчик получения уведомления о создании локального экземпляра компонента. Вызывается с новым и старым (корневыми) экземплярами VueI18n. - -Обработчик может потребоваться при расширении корневого экземпляра VueI18n и необходимости ожидания для применения этих расширений к локальному экземпляру компонента. - -#### escapeParameterHtml - -> Добавлено в версии 8.22+ - - * **Тип:** `Boolean` - - * **По умолчанию:** `false` - -Если `escapeParameterHtml` установлен в значение `true`, то параметры интерполяции будут экранированы перед переводом сообщения. Это полезно, когда результат перевода используется в `v-html` и текст для перевода содержит HTML-разметку (например, `` вокруг предоставленного пользователем значения). Этот шаблон в основном предназначен для случаев, когда передаются предварительно скомпилированные текстовые строки в компоненты UI. - -Процесс экранирования включает в себя замену следующих символов на соответствующие HTML-сущности: `<`, `>`, `"`, `'`. - -Установка `escapeParameterHtml` в значение `true` не должна нарушать существующую функциональность, а предоставит защиту от векторов атаки типа XSS. - -### Свойства - -#### locale - -* **Тип:** `Locale` - -* **Чтение/Запись** - -Локаль используемая для локализации. Если локаль содержит территорию и диалект, то эта локаль неявно указывает на запасные варианты. - -#### fallbackLocale - -* **Тип:** `FallbackLocale` - -* **Чтение/Запись** - -Локаль используемая для запасной локализации. Способы определения и переключения на запасную локализацию можно изучить в разделе [Запасная локализация](../guide/fallback.md). - -#### messages - -* **Тип:** `LocaleMessages` - -* **Только для чтения** - -Переведённые сообщения используемые для локализации. - -#### dateTimeFormats - -> :new: Добавлено в версии 7.0+ - -* **Тип:** `DateTimeFormats` - -* **Только для чтения** - -Форматы форматирования дат для локализации. - -#### numberFormats - -> :new: Добавлено в версии 7.0+ - -* **Тип:** `NumberFormats` - -* **Только для чтения** - -Форматы форматирования чисел для локализации. - -#### missing - -* **Тип:** `MissingHandler` - -* **Чтение/Запись** - -Обработчик для отсутствующих ключей локализаций. - -#### formatter - -* **Тип:** `Formatter` - -* **Чтение/Запись** - -Метод форматирования, который реализует интерфейс `Formatter`. - -#### silentTranslationWarn - -> 6.1+, :up: 8.13 - -* **Тип:** `Boolean | RegExp` - -* **Чтение/Запись** - -Отключение предупреждений выводимых при ошибке локализации. - -#### silentFallbackWarn - -> :new: Добавлено в версии 8.8+, :up: 8.13 - -* **Тип:** `Boolean | RegExp` - -* **Чтение/Запись** - -Отключение предупреждений выводимых при ошибке использования запасной локализации. - -#### pluralizationRules - -> 8.5+ - -* **Тип:** `PluralizationRules` - -* **Чтение/Запись** - -Набор зависимых от локали правил плюрализации. - -#### preserveDirectiveContent - -> Добавлено в версии 8.7+ - -* **Тип:** `Boolean` - -* **Чтение/Запись** - -Должен ли элемент директивы `v-t` сохранять `textContent` после того как директива снята с элемента. - -#### warnHtmlInMessage - -> Добавлено в версии 8.11+ - -* **Тип:** `WarnHtmlInMessageLevel` - -* **Чтение/Запись** - -Разрешить ли использование HTML-форматирования в сообщениях локализации. - - -При установке `warn` или `error` проверяются сообщения локализации экземпляра VueI18n. - -При установке `warn` выводятся предупреждения в консоль. - -При установке `error` генерируется Error. - -В качестве значения по умолчанию в экземпляре VueI18n установлено `off`. - -#### postTranslation - -> Добавлено в версии 8.16+ - -* **Тип:** `PostTranslationHandler` - -* **Чтение/Запись** - -Обработчик для пост-обработки перевода. - -### Методы - -#### getChoiceIndex - -* **Аргументы:** - - * `{number} choice` - * `{number} choicesLength` - -* **Возвращает:** `finalChoice {number}` - -Получение индекса для плюрализации текущего числа и заданного количества вариантов. Реализация может быть переопределена через изменение прототипа: - -```js -VueI18n.prototype.getChoiceIndex = /* пользовательская реализация */ -``` - -Однако в большинстве случаев достаточно передать нужную функцию в [pluralizationRules опцию конструктора](#pluralizationrules). - -#### getLocaleMessage( locale ) - -* **Аргументы:** - - * `{Locale} locale` - -* **Возвращает:** `LocaleMessageObject` - -Получение сообщений локализации для локали. - -#### setLocaleMessage( locale, message ) - -* **Аргументы:** - - * `{Locale} locale` - * `{LocaleMessageObject} message` - -Установка сообщений локализации для локали. - -:::tip ПРИМЕЧАНИЕ - -> Добавлено в версии 8.11+ - -При использовании `warn` или `error` в свойстве `warnHtmlInMessage`, при выполнении этого метода будет проверено используется ли HTML-форматирование для сообщения локализации. -::: - -#### mergeLocaleMessage( locale, message ) - -> 6.1+ - -* **Аргументы:** - - * `{Locale} locale` - * `{LocaleMessageObject} message` - -Объединение указанных сообщений локализации с сообщениями локализации локали. - -:::tip ПРИМЕЧАНИЕ - -> Добавлено в версии 8.11+ - -При использовании `warn` или `error` в свойстве `warnHtmlInMessage`, при выполнении этого метода будет проверено используется ли HTML-форматирование для сообщения локализации. -::: - -#### t( key, [locale], [values] ) - -* **Аргументы:** - - * `{Path} key`: обязательный - * `{Locale} locale`: опционально - * `{Array | Object} values`: опционально - -* **Возвращает:** : `TranslateResult` - -Аналогично функции возвращаемой методом `$t`. Подробнее см. [$t](#t). - -#### tc( key, [choice], [values] ) - -* **Аргументы:** - - * `{Path} key`: обязательный - * `{number} choice`: опционально, по умолчанию `1` - * `{string | Array | Object} values`: опционально - -* **Возвращает:** `TranslateResult` - -Аналогично функции возвращаемой методом `$tc`. Подробнее см. [$tc](#tc). - -#### te( key, [locale] ) - -* **Аргументы:** - - * `{string} key`: обязательный - * `{Locale} locale`: опционально - -* **Возвращает:** `boolean` - -Проверяет существует ли указанный ключ в глобальных сообщениях локализации. Если указать `locale`, проверка будет осуществляться в сообщениях локализации `locale`. - -#### getDateTimeFormat ( locale ) - -> :new: Добавлено в версии 7.0+ - -* **Аргументы:** - - * `{Locale} locale` - -* **Возвращает:** `DateTimeFormat` - -Получение форматов форматирования дат локализации. - -#### setDateTimeFormat ( locale, format ) - -> :new: Добавлено в версии 7.0+ - -* **Аргументы:** - - * `{Locale} locale` - * `{DateTimeFormat} format` - -Установка форматов форматирования дат для локализации. - -#### mergeDateTimeFormat ( locale, format ) - -> :new: Добавлено в версии 7.0+ - -* **Аргументы:** - - * `{Locale} locale` - * `{DateTimeFormat} format` - -Объединение указанных форматов форматирования дат с форматами локализации. - -#### d( value, [key], [locale] ) - -> :new: Добавлено в версии 7.0+ - -* **Аргументы:** - - * `{number | Date} value`: обязательный - * `{Path | Object} key`: опционально - * `{Locale | Object} locale`: опционально - -* **Возвращает:** `DateTimeFormatResult` - -Аналогично функции возвращаемой методом `$d`. Подробнее см. [$d](#d). - -#### getNumberFormat ( locale ) - -> :new: Добавлено в версии 7.0+ - -* **Аргументы:** - - * `{Locale} locale` - -* **Возвращает:** `NumberFormat` - -Получение форматов форматирования чисел для локализации. - -#### setNumberFormat ( locale, format ) - -> :new: Добавлено в версии 7.0+ - -* **Аргументы:** - - * `{Locale} locale` - * `{NumberFormat} format` - -Установка форматов форматирования чисел для локализации. - -#### mergeNumberFormat ( locale, format ) - -> :new: Добавлено в версии 7.0+ - -* **Аргументы:** - - * `{Locale} locale` - * `{NumberFormat} format` - -Объединение указанных форматов форматирования чисел с форматами локализации. - -#### n( value, [format], [locale] ) - -> :new: Добавлено в версии 7.0+ - -* **Аргументы:** - - * `{number} value`: обязательный - * `{Path | Object} format`: опционально - * `{Locale} locale`: опционально - -* **Возвращает:** `NumberFormatResult` - -Аналогично функции возвращаемой методом `$n`. Подробнее см. [$n](#n). - -## Директивы - -> :new: Добавлено в версии 7.3+ - -### v-t - -* **Ожидает:** `string | Object` - -* **Модификаторы:** - - * `.preserve`: (8.7.0+) сохраняет `textContent` элемента при снятии директивы с элемента. - -* **Подробности:** - -Обновление `textContent` элемента, который был переведён с помощью сообщений локализации. Можно использовать строковый или объектный синтаксис. Строковый синтаксис может быть задан в качестве пути к сообщению локализации. При использовании объектного синтаксиса необходимо указать следующие свойства: - - * `path`: обязательный, ключ сообщения локализации - * `locale`: опционально, локализация - * `args`: опционально, для списка или именованного форматирования - -:::tip ПРИМЕЧАНИЕ -По умолчанию значение `textContent` элемента удаляется при снятии директивы `v-t`. Это может быть нежелательной ситуацией например при [анимировании списков](https://ru.vuejs.org/v2/guide/transitions.html). Для сохранения данных `textContent` после снятия директивы следует использовать модификатор `.preserve` или глобальную опцию [`preserveDirectiveContent`](#preservedirectivecontent). -::: - -* **Примеры:** - -```html - -

- - -

- - -

- - -

- - -

-``` - -* **См. также:** [Пользовательская директива для локализации](../guide/directive.md) - -## Компоненты - -### Функциональный компонент i18n - -> :new: Добавлено в версии 7.0+ - -#### Входные параметры: - -* `path {Path}`: обязательный, путь к сообщению локализации -* `locale {Locale}`: опционально, локализация -* `tag {string | boolean | Object}`: опционально, по умолчанию `'span'` -* `places {Array | Object}`: опционально (7.2+) - -:::danger Внимание! -Со следующей мажорной версии опция `places` будет удалена. Используйте синтаксис слотов. -::: - -#### Использование: - -```html -
- - - {{ $t('tos') }} - - -
-``` - -```js -const messages = { - en: { - tos: 'Term of Service', - term: 'I accept xxx {0}.' - }, - ru: { - tos: 'Условия обслуживания', - term: 'Я соглашаюсь с xxx {0}.' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) -new Vue({ - i18n, - data: { - url: '/term' - } -}).$mount('#app') -``` - -#### См. также: - -[Интерполяция компонента](../guide/interpolation.md) - -### Функциональный компонент i18n-n - -> :new: Добавлено в версии 8.10+ - -#### Входные параметры: - -* `value {number}`: обязательный, число для форматирования -* `format {string | NumberFormatOptions}`: опционально, форматируемое число или объект с указанными опциями форматирования -* `locale {Locale}`: опционально, локализация -* `tag {string | boolean | Object}`: опционально, по умолчанию `'span'` - -#### Использование: - -```html -
- - - - {{ slotProps.currency }} - - - -
-``` - -```js -var numberFormats = { - 'en-US': { - currency: { - style: 'currency', - currency: 'USD' - } - }, - 'ru-RU': { - currency: { - style: 'currency', - currency: 'RUB' - } - } -} - -const i18n = new VueI18n({ - locale: 'en-US', - numberFormats -}) - -new Vue({ - i18n, - data: { - money: 10234 - } -}).$mount('#app') -``` - -#### Слоты с ограниченной областью видимости - -Функциональный компонент `` может принимать различные слоты с ограниченной областью видимости. Список поддерживаемых имён слотов основан на [выходных типах `Intl.NumberFormat.formatToParts()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat/formatToParts): - -* `currency` -* `decimal` -* `fraction` -* `group` -* `infinity` -* `integer` -* `literal` -* `minusSign` -* `nan` -* `plusSign` -* `percentSign` - -Каждый из слотов предоставляет доступ к значениям трёх параметров: - -* `[slotName] {FormattedNumberPartType}`: параметр с тем же именем, что и имя слота (например, `integer`) -* `index {Number}`: индекс конкретной части в массиве частей числа -* `parts {Array}`: массив со всеми отформатированными частями числа - -#### См. также: - -[Локализация чисел](../guide/number.md#custom-formatting) - -## Специальные атрибуты - -### place - -> :new: Добавлено в версии 7.2+ - -#### Ожидает: `{number | string}` - -Используется при интерполяции компонента для указания индекса при форматировании списком или ключа при именованном форматировании. - -Подробнее об использовании в разделе по ссылке ниже. - -#### См. также: - -[Интерполяция компонента](../guide/interpolation.md) diff --git a/docs-old/ru/guide/component.md b/docs-old/ru/guide/component.md deleted file mode 100644 index 52057d8eb..000000000 --- a/docs-old/ru/guide/component.md +++ /dev/null @@ -1,152 +0,0 @@ -# Локализация на основе компонентов - -В основном данные для локализации (например, `locale`,`messages`, и т.д.) задаются опциями конструктора экземпляра `VueI18n` и устанавливаются через свойство `i18n` в корневой экземпляр Vue. - -Поэтому можно глобально выполнять переводы, используя методы `$t` или `$tc` в корневом экземпляре Vue и любом из компонентов в нём. Но также возможно указывать данные для локализации в каждом компоненте в отдельности, что может быть удобнее благодаря компонентно-ориентированному дизайну. - -Пример локализации на основе компонентов: - -```js -// Установка локализации в корневой экземпляр Vue -const i18n = new VueI18n({ - locale: 'ru', - messages: { - en: { - message: { - hello: 'hello world', - greeting: 'good morning' - } - }, - ru: { - message: { - hello: 'привет мир', - greeting: 'доброе утро' - } - } - } -}) - -// Определение компонента -const Component1 = { - template: ` -
-

Component1 locale messages: {{ $t("message.hello") }}

-

Fallback global locale messages: {{ $t("message.greeting") }}

-
`, - i18n: { - // опция `i18n`, определение данных локализации для компонента - messages: { - en: { message: { hello: 'hello component1' } }, - ru: { message: { hello: 'привет component1' } } - } - } -} - -new Vue({ - i18n, - components: { - Component1 - } -}).$mount('#app') -``` - -Шаблон: - -```html -
-

{{ $t("message.hello") }}

- -
-``` - -Результат: - -```html -
-

привет мир

-
-

Component1 locale messages: привет component1

-

Fallback global locale messages: доброе утро

-
-
-``` - -Если компонент не имеет собственного сообщения для локализации, то в качестве запасного выхода он обратится к глобальным данным для локализации. Компонент использует локаль, установленную в корневом экземпляре (в примере выше установлена: `locale: 'ru'`). - -Обратите внимание, по умолчанию при обращении к данным корневой локализации будут генерироваться предупреждения в консоли: - -``` -[vue-i18n] Value of key 'message.greeting' is not a string! -[vue-i18n] Fall back to translate the keypath 'message.greeting' with root locale. -``` - -Чтобы скрыть эти предупреждения (оставив те, что предупреждают о полном отсутствии перевода для данного ключа) установите опцию `silentFallbackWarn: true` при инициализации экземпляра `VueI18n`. - -Если необходимо осуществлять перевод, основываясь на локали компонента, то это можно сделать с помощью опции `sync: false` и `locale` в настройках `i18n`. - -## Общие сообщения локализации для компонентов - -Иногда может потребоваться импортировать сообщения локализации в определённых компонентах, чтобы не обращаться к глобальным сообщениям локализации (например, общие сообщения для определённых функций компонентов). - -Для этого можно использовать опцию `sharedMessages` в свойстве `i18n` компонента. - -Пример использования общих сообщений локализации: - -```js -export default { - en: { - buttons: { - save: 'Save' - // ... - } - }, - ru: { - buttons: { - save: 'Сохранить' - // ... - } - } -} -``` - -Компонент: - -```js -import commonMessage from './locales/common' // импорт общих сообщений локализации - -export default { - name: 'ServiceModal', - template: ` - - `, - i18n: { - messages: { ... }, - sharedMessages: commonMessages - } -} -``` - -Если указаны опции `sharedMessages` и `messages`, то их сообщения будут объединены в сообщения локализации в экземпляре VueI18n этого компонента. - -## Локализация в функциональных компонентах - -При использовании функционального компонента все данные (включая `props`, `children`, `slots`, `parent`, и т.д.) передаются через `context`, в котором содержатся все эти атрибуты. Кроме того отсутствует возможность использовать `this`, поэтому при использовании vue-i18n с функциональными компонентами следует обращаться к `$t` как к `parent.$t`, например так: - -```html -... - -... -``` diff --git a/docs-old/ru/guide/datetime.md b/docs-old/ru/guide/datetime.md deleted file mode 100644 index 47fe85aa0..000000000 --- a/docs-old/ru/guide/datetime.md +++ /dev/null @@ -1,77 +0,0 @@ -# Локализация дат - -:::tip Поддержка с версии -:new: 7.0+ -::: - -Можно выполнять локализацию дат по соответствующему формату. - -Пример формата для дат: - -```js -const dateTimeFormats = { - 'en-US': { - short: { - year: 'numeric', - month: 'short', - day: 'numeric' - }, - long: { - year: 'numeric', - month: 'long', - day: 'numeric', - weekday: 'long', - hour: 'numeric', - minute: 'numeric' - } - }, - 'pt-BR': { - short: { - year: 'numeric', - month: 'short', - day: 'numeric' - }, - long: { - year: 'numeric', - month: 'long', - day: 'numeric', - weekday: 'long', - hour: 'numeric', - minute: 'numeric', - hour12: true - } - } -} -``` - -Как видно выше, можно определять именованный формат даты (например, `short`, `long` и т.д.) используя [опции ECMA-402 Intl.DateTimeFormat](http://www.ecma-international.org/ecma-402/2.0/#sec-intl-datetimeformat-constructor) - -После этого, для возможности использования данного формата в сообщениях локализации, необходимо задать опцию `dateTimeFormats` в конструкторе `VueI18n`: - -```js -const i18n = new VueI18n({ - dateTimeFormats -}) - -new Vue({ - i18n -}).$mount('#app') -``` - -Шаблон: - -```html -
-

{{ $d(new Date(), 'short') }}

-

{{ $d(new Date(), 'long', 'pt-BR') }}

-
-``` - -Результат: - -```html -
-

Jan 18, 2021

-

domingo, 18 de janeiro de 2021 5:47 AM

-
-``` diff --git a/docs-old/ru/guide/directive.md b/docs-old/ru/guide/directive.md deleted file mode 100644 index 653a50173..000000000 --- a/docs-old/ru/guide/directive.md +++ /dev/null @@ -1,181 +0,0 @@ -# Пользовательская директива - -:::tip Поддержка с версии -:new: 7.3+ -::: - -Переводы можно осуществлять не только используя пользовательскую директиву `v-t`, но и с помощью метода `$t`. - -## Строковый синтаксис - -Можно передавать ключ сообщения локализации строкой. - -JavaScript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { hello: 'hi there!' }, - ru: { hello: 'привет всем!' } - } - }), - data: { path: 'hello' } -}).$mount('#string-syntax') -``` - -Шаблон: - -```html -
- -

- -

-
-``` - -Результат: - -```html -
-

привет всем!

-

привет всем!

-
-``` - -## Объектный синтаксис - -Можно использовать объектный синтаксис. - -JavaScript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { hello: 'hi {name}!' }, - ru: { hello: 'привет {name}!' } - } - }), - computed: { - nickName() { return 'kazupon' } - }, - data: { path: 'hello' } -}).$mount('#object-syntax') -``` - -Шаблон: - -```html -
- -

- -

-
-``` - -Результат: - -```html -
-

привет、kazupon!

-

hi kazupon!

-
-``` - -## Использование с transition - -:::tip Поддержка с версии -:new: 8.7+ -::: - -При использовании директивы `v-t` на элементе внутри [компонента ``](https://ru.vuejs.org/v2/api/#transition), можно заметить как переведённое сообщение исчезает во время анимации перехода. Это поведение связано с реализацией самого компонента `` — все директивы в исчезающем элементе внутри компонента `` должны быть уничтожены **до начала анимации**. Это может привести к мерцанию содержимого на коротких анимациях, но наиболее заметно при длинных анимациях переходов. - -Чтобы сохранить содержимое директивы во время анимации перехода, необходимо добавить [модификатор `.preserve`](../api/#v-t) при определении директивы `v-t`. - -Javascript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { preserve: 'with preserve' } - } - }), - data: { toggle: true } -}).$mount('#in-transitions') -``` - -Шаблон: - -```html -
- - - - -
-``` - -Также можно глобально установить настройку `preserveDirectiveContent` в экземпляре `VueI18n`, что повлияет на все директивы `v-t` без добавления модификатора к ним. - -JavaScript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { preserve: 'with preserve' } - }, - preserveDirectiveContent: true - }), - data: { toggle: true } -}).$mount('#in-transitions') -``` - -Шаблон: - -```html -
- - - - -
-``` - -Подробнее о примерах выше можно изучить [здесь](https://github.com/kazupon/vue-i18n/tree/dev/examples/directive) - -## `$t` или `v-t` - -### `$t` - -`$t` — это метод, добавленный в экземпляр Vue. У него следующие плюсы и минусы: - -#### Плюсы - -Предоставляет **гибкость** в использовании синтаксиса фигурных скобок `{{}}` в шаблонах, а также применять в вычисляемых свойствах и методах экземпляра Vue. - -#### Минусы - -`$t` выполняется **каждый раз** когда происходит перерисовка, поэтому у него есть расходы на осуществление перевода. - -### `v-t` - -`v-t` — пользовательская директива. У неё следующие плюсы и минусы: - -#### Плюсы - -`v-t` имеет **лучшую производительность** в сравнении с методом `$t`, благодаря кэшу в пользовательской директиве после выполнения перевода. Также можно реализовать предварительный перевод с помощью модуля для компилятора Vue, который предоставляет плагин [`vue-i18n-extensions`](https://github.com/kazupon/vue-i18n-extensions). - -Таким образом, можно достичь **большей оптимизации производительности**. - -#### Минусы - -`v-t` нельзя использовать также гибко, как `$t`, и это добавляет **сложности**. Перевод с помощью `v-t` вставляется в `textContent` элемента. Также, при использовании рендеринга на стороне сервера необходимо установить [пользовательскую директиву](https://github.com/kazupon/vue-i18n-extensions#directive-v-t-custom-directive-for-server-side) через опцию `directives` функции `createRenderer`. diff --git a/docs-old/ru/guide/fallback.md b/docs-old/ru/guide/fallback.md deleted file mode 100644 index b1b3fef59..000000000 --- a/docs-old/ru/guide/fallback.md +++ /dev/null @@ -1,145 +0,0 @@ -# Запасная локализация - -*Вкратце: указывайте `fallbackLocale: ''` для определения языка, который будет использоваться, если нет перевода в выбранной локализации.* - -## Неявное определение запасных локализаций при использовании локалей - -Если `locale` содержит территорию и опционально диалект, то неявно будут определены автоматически запасные локали. - -Например для `de-DE-bavarian` в качестве запасных будут считаться следующие: -1. `de-DE-bavarian` -2. `de-DE` -3. `de` - -Для отключения автоматического определения запасных локалей укажите символ `!`, например `de-DE!` - -## Явное определение одной локали запасной локализации - -Иногда не все ключи сообщений переведены на другие языки. В примере ниже, сообщение для ключа `hello` доступно в английской локали, но отсутствует в русской: - -```js -const messages = { - en: { - hello: 'Hello, world!' - }, - ru: { - // упс, не все переведено - } -} -``` - -Если хочется использовать сообщения локализации из `en`, когда перевод отсутствует в нужной локализации, то следует указать опцию `fallbackLocale` в конструкторе VueI18n: - -```js -const i18n = new VueI18n({ - locale: 'ru', - fallbackLocale: 'en', - messages -}) -``` - -Шаблон: - -```html -

{{ $t('hello') }}

-``` - -Результат: - -```html -

Hello, world!

-``` - -По умолчанию, если использовались сообщения запасной локализации из `fallbackLocale`, то в консоли будут выведены соответствующие предупреждения: - -``` -[vue-i18n] Value of key 'hello' is not a string! -[vue-i18n] Fall back to translate the keypath 'hello' with 'en' locale. -``` - -Чтобы скрыть такие предупреждения (оставив при этом те, в случаях полного отсутствия переводов для данного ключа) установите `silentFallbackWarn: true` при инициализации экземпляра `VueI18n`. - -## Явное определение запасной локали с помощью массива - -Можно указать более одной запасной локализации с помощью массива. Например: - -```js -fallbackLocale: ['ru', 'en'], -``` - -## Явное определение запасной локали с помощью объекта - -Более сложный алгоритм принятия решений для определения запасной локали можно реализовать с помощью карты принятия решений в виде объекта. - -Например для подобного объекта: - -```js -fallbackLocale: { - /* 1 */ 'de-CH': ['fr', 'it'], - /* 2 */ 'zh-Hant': ['zh-Hans'], - /* 3 */ 'es-CL': ['es-AR'], - /* 4 */ 'es': ['en-GB'], - /* 5 */ 'pt': ['es-AR'], - /* 6 */ 'default': ['en', 'ru'] -}, -``` - -Будут следующие цепочки выбора запасной локали: - -| Локаль | Цепочка выбора | -| ----------- | ----------------------------------------- | -| `'de-CH'` | de-CH > fr > it > en > ru | -| `'de'` | de > en > ru | -| `'zh-Hant'` | zh-Hant > zh-Hans > zh > en > ru | -| `'es-SP'` | es-SP > es > en-GB > en > ru | -| `'es-SP!'` | es-SP > en > ru | -| `'fr'` | fr > en > ru | -| `'pt-BR'` | pt-BR > pt > es-AR > es > en-GB > en > ru | -| `'es-CL'` | es-CL > es-AR > es > en-GB > en > ru | - -## Резервная интерполяция - -_Вкратце: установите `formatFallbackMessages: true` чтобы выполнять интерполяции шаблона по ключам перевода, когда в выбранном языке отсутствует данный ключ для перевода._ - -Так как ключи переводов являются строками, то можно использовать само сообщение в качестве ключа (для определённого языка). Например: - -```js -const messages = { - ru: { - 'Hello, world!': 'Привет мир!' - } -} -``` - -Это может быть полезным, потому что не нужно будет указывать перевод для строки "Hello, world!" в английской локализации. - -Фактически, можно указывать даже параметры в ключе. Вместе с `formatFallbackMessages: true` это позволит опустить создание шаблонов для «базового» языка; потому что его ключи _уже находятся_ в шаблоне. - -```js -const messages = { - ru: { - 'Hello {name}': 'Здравствуйте {name}' - } -} - -const i18n = new VueI18n({ - locale: 'ru', - fallbackLocale: 'en', - formatFallbackMessages: true, - messages -}) -``` - -Шаблон: - -```html -

{{ $t('Hello {name}', { name: 'John' }}) }}

-

{{ $t('The weather today is {condition}!', { condition: 'sunny' }) }}

-``` - -Результат: - -```html -

Здравствуйте, John

-

The weather today is sunny!

-``` diff --git a/docs-old/ru/guide/formatting.md b/docs-old/ru/guide/formatting.md deleted file mode 100644 index 042e895c9..000000000 --- a/docs-old/ru/guide/formatting.md +++ /dev/null @@ -1,227 +0,0 @@ -# Формат сообщений локализации - -## Именованный формат - -Сообщения локализации: - -```js -const messages = { - en: { - message: { - hello: '{msg} world' - } - }, - ru: { - message: { - hello: '{msg} мир' - } - } -} -``` - -Шаблон: - -```html -

{{ $t('message.hello', { msg: 'привет' }) }}

-``` - -Результат: - -```html -

привет мир

-``` - -## Формат списков - -Сообщения локализации: - -```js -const messages = { - en: { - message: { - hello: '{0} world' - } - }, - ru: { - message: { - hello: '{0} мир' - } - } -} -``` - -Шаблон: - -```html -

{{ $t('message.hello', ['привееет']) }}

-``` - -Результат: - -```html -

привееет мир

-``` - -Форматирование списков также принимает объекты, соответствующие по структуре массиву: - -```html -

{{ $t('message.hello', {'0': 'привееет'}) }}

-``` - -Результат: - -```html -

привееет мир

-``` - -## HTML формат - -:::warning Обратите внимание -:warning: Динамическая локализация произвольного HTML на вебсайте очень опасна, потому что легко может привести к XSS-уязвимостям. Используйте HTML-интерполяцию только для доверенного контента и никогда для пользовательского. - -Рекомендуем в таких случаях использовать возможности [интерполяции компонента](interpolation.md). -::: - -:::warning Обратите внимание - -> :new: Добавлено в версии 8.11+ - -Можно управлять использованием HTML форматирования. Для подробностей см. опцию конструктора `warnHtmlInMessage` и свойства API. -::: - -Иногда требуется отобразить сообщение локализации HTML-кодом, а не статической строкой. - -```js -const messages = { - en: { - message: { - hello: 'hello
world' - } - }, - ru: { - message: { - hello: 'привет
мир' - } - } -} -``` - -Шаблон: - -```html -

-``` - -Результат (вместо отформатированного сообщения) - -```html -

- привет - - мир -

-``` - -## Формат ruby on rails i18n - -Сообщения локализации: - -```js -const messages = { - en: { - message: { - hello: '%{msg} world' - } - }, - ru: { - message: { - hello: '%{msg} мир' - } - } -} -``` - -Шаблон: - -```html -

{{ $t('message.hello', { msg: 'привет' }) }}

-``` - -Результат: - -```html -

привет мир

-``` - -## Пользовательский формат - -Иногда может потребоваться реализовать локализацию для собственного формата сообщений (например, использовать [синтаксиса сообщений ICU](http://userguide.icu-project.org/formatparse/messages)). - -Реализовать это можно с помощью специального пользовательского метода форматирования, который должен реализовать [интерфейс Formatter](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js#L145-L147). - -Пример пользовательского метода форматирования с синтаксисом класса ES2015: - -```js -// Реализация пользовательского Formatter -class CustomFormatter { - constructor(options) { - // ... - } - - // - // interpolate - // - // @param {string} message - // строка или список или именованный формат - // напр. - // - именованный формат: 'Hi {name}' - // - формат списка: 'Hi {0}' - // - // @param {Object | Array} values - // значения интерполяции `message`. - // переданные значения с `$t`, `$tc` и функциональным компонентом `i18n`. - // напр. - // - $t('hello', { name: 'Alex' }) -> переданные значения: Object `{ name: 'Alex' }` - // - $t('hello', ['Alex']) -> переданные значения: Array `['Alex']` - // - функциональный компонент `i18n` (интерполяция в компоненте) - // - //

Alex

- //

how are you?

- //
- // -> переданные значения: Array (included VNode): - // `[VNode{ tag: 'p', text: 'Alex', ...}, VNode{ tag: 'p', text: 'how are you?', ...}]` - // - // @return {Array} - // интерполированные значения. Они необходимы чтобы вернуть следующее: - // - массив строк, когда используется `$t` или `$tc`. - // - массив, включая объект VNode, когда используется функциональный компонент `i18n`. - // - interpolate(message, values) { - // реализация логики интерполяции - // ... - - // возвращаем интерполированный массив - return ['resolved message string'] - } -} - -// Регистрация через опцию `formatter` -const i18n = new VueI18n({ - locale: 'en-US', - formatter: new CustomFormatter(/* опции конструктора */), - messages: { - 'en-US': { - // ... - }, - 'ru-RU': { - // ... - } - // ... - } -}) - -// Запускаем приложение! -new Vue({ i18n }).$mount('#app') -``` - -Также посмотрите [официальный пример пользовательского метода форматирования](https://github.com/kazupon/vue-i18n/tree/dev/examples/formatting/custom). diff --git a/docs-old/ru/guide/hot-reload.md b/docs-old/ru/guide/hot-reload.md deleted file mode 100644 index 56006ab00..000000000 --- a/docs-old/ru/guide/hot-reload.md +++ /dev/null @@ -1,99 +0,0 @@ -# Горячая перезагрузка переводов - -С помощью функции Webpack для [горячей перезагрузки модулей (HMR)](https://webpack.js.org/concepts/hot-module-replacement/) можно отслеживать изменения в файлах локализации и осуществлять их горячую перезагрузку в приложении. - -## Простой пример - -Для статичного набора локалей, можно явно указать горячую перезагрузку этих переводов: - -```js -import Vue from "vue" -import VueI18n from "vue-i18n" -import en from './en' -import ru from './ru' - -const messages = { - en, - ru -} - -// Экземпляр VueI18n -const i18n = new VueI18n({ - locale: 'en', - messages -}) - -// Запускаем приложение -const app = new Vue({ - i18n - // ... -}).$mount('#app') - -// Добавляем горячую перезагрузку сообщений локализации -if (module.hot) { - module.hot.accept(['./en', './ru'], function() { - i18n.setLocaleMessage('en', require('./en').default) - i18n.setLocaleMessage('ru', require('./ru').default) - // Или добавляем горячую перезагрузку через свойство $i18n - // app.$i18n.setLocaleMessage('en', require('./en').default) - // app.$i18n.setLocaleMessage('ru', require('./ru').default) - }) -} -``` - -## Продвинутый пример - -Если требуется поддержка изменяющегося набор переводов, можно реализовать горячую перезагрузку для всех локалей динамически через `require.context`: - -```js -import Vue from "vue"; -import VueI18n from "vue-i18n"; - -Vue.use(VueI18n); - -// Загрузка всех локалей и сохранение контекста -function loadMessages() { - const context = require.context("./locales", true, /[a-z0-9-_]+\.json$/i); - - const messages = context - .keys() - .map((key) => ({ key, locale: key.match(/[a-z0-9-_]+/i)[0] })) - .reduce( - (messages, { key, locale }) => ({ - ...messages, - [locale]: context(key), - }), - {} - ); - - return { context, messages }; -} - -const { context, messages } = loadMessages(); - -// Экземпляр VueI18n -const i18n = new VueI18n({ - locale: "en", - messages, -}); - -// Запускаем приложение -const app = new Vue({ - i18n, - // ... -}).$mount('#app'); - -// Добавляем горячую перезагрузку сообщений локализации -if (module.hot) { - module.hot.accept(context.id, () => { - const { messages: newMessages } = loadMessages(); - - Object.keys(newMessages) - .filter((locale) => messages[locale] !== newMessages[locale]) - .forEach((locale) => { - messages[locale] = newMessages[locale]; - i18n.setLocaleMessage(locale, messages[locale]); - }); - }); -} -``` diff --git a/docs-old/ru/guide/interpolation.md b/docs-old/ru/guide/interpolation.md deleted file mode 100644 index 0978fda99..000000000 --- a/docs-old/ru/guide/interpolation.md +++ /dev/null @@ -1,275 +0,0 @@ -# Интерполяция компонента - -## Базовое использование - -:::tip Поддержка с версии -:new: 7.0+ -::: - -Иногда требуется перевести сообщения в которых есть HTML теги или компоненты. Например: - -```html -

I accept xxx Terms of Service Agreement

-``` - -Для такого сообщения, если хотим использовать `$t`, то, вероятно, попробуем достичь скомпоновав из следующих сообщений локализации: - -```js -const messages = { - en: { - term1: "I Accept xxx's", - term2: 'Terms of Service Agreement' - } -} -``` - -И в итоге шаблон станет выглядеть так: - -```html -

{{ $t('term1') }}{{ $t('term2') }}

-``` - -Результат: - -```html -

I accept xxx Terms of Service Agreement

-``` - -Это выглядит очень громоздко, но если перенести тег `` в сообщение локализации, то добавится вероятность XSS-уязвимости из-за применения `v-html="$t('term')"`. - -Этого можно избежать воспользовавшись функциональным компонентом `i18n`. Например: - -```html - -``` - -```js -const messages = { - en: { - tos: 'Term of Service', - term: 'I accept xxx {0}.' - }, - ru: { - tos: 'Условия обслуживания', - term: 'Я соглашаюсь с xxx {0}.' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) -new Vue({ - i18n, - data: { - url: '/term' - } -}).$mount('#app') -``` - -Результат: - -```html -
- - - -
-``` - -Подробнее о примере можно изучить [здесь](https://github.com/kazupon/vue-i18n/tree/dev/examples/interpolation/places) - -Потомки функционального компонента `i18n` интерполируют сообщения локализации по входному параметру `path`. - -В примере выше: -:::v-pre -`{{ $t('tos') }}` -::: -интерполируется с сообщением локализации `term`. - -В примере выше интерполяция компонента использует **формат в виде списка**. Потомки функционального компонента `i18n` интерполируются по порядку их появления. - -Определить тип корневого элемента можно указать с помощью входного параметра `tag`. Если входной параметр не указан, то по умолчанию будет `'span'`. Также можно указать значение `false`, чтобы вставлять дочерние элементы без создания и оборачивания в корневой. - -## Использование синтаксиса слотов - -:::tip Поддержка с версии -:new: 8.14+ -::: - -Гораздо удобнее использовать синтаксис именованных слотов. Например: - -```html -
- - - - - - -
-``` - -```js -const messages = { - en: { - info: 'You can {action} until {limit} minutes from departure.', - change: 'change your flight', - refund: 'refund the ticket' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) - -new Vue({ - i18n, - data: { - changeUrl: '/change', - refundUrl: '/refund', - changeLimit: 15, - refundLimit: 30 - } -}).$mount('#app') -``` - -Результат: - -```html -
- -

- You can change your flight until - 15 minutes from departure. -

- -
-``` - -С версии Vue 2.6 можно использовать сокращённый синтаксис слотов в шаблонах: - -```html -
- - - - - - -
-``` - -:::warning Ограничение -:warning: В компоненте `i18n` входные параметры слота не поддерживаются. -::: - -## Использование синтаксиса places - -:::danger Внимание! -В следующей мажорной версии входные параметры `place` и `places` будут объявлены устаревшими. Рекомендуем использовать синтаксис слотов. -::: - -:::tip Поддержка с версии -:new: 7.2+ -::: - -:::warning Обратите внимание -:warning: В компоненте `i18n` содержимое, состоящее только из пробелов, будет опущено. -::: - -Именованное форматирование поддерживается с помощью атрибута `place`. Например: - -```html -
- - - {{ changeLimit }} - {{ $t('change') }} - - -
-``` - -```js -const messages = { - en: { - info: 'You can {action} until {limit} minutes from departure.', - change: 'change your flight', - refund: 'refund the ticket' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) -new Vue({ - i18n, - data: { - changeUrl: '/change', - refundUrl: '/refund', - changeLimit: 15, - refundLimit: 30 - } -}).$mount('#app') -``` - -Результат: - -```html -
- -

- You can change your flight until - 15 minutes from departure. -

- -
-``` - -:::warning Обратите внимание -:warning: Для использования именованного форматирования все потомки компонента `i18n` должны иметь установленный атрибут `place`. В противном случае будет использовано форматирование списком. -::: - -Если всё же необходимо интерполировать текстовое содержимое с помощью именованного форматирования, можно определить свойство `places` на компоненте `i18n`. Например: - -```html -
- - - {{ $t('refund') }} - - -
-``` - -Результат: - -```html -
- -

- You can refund your ticket until 30 minutes from - departure. -

- -
-``` diff --git a/docs-old/ru/guide/lazy-loading.md b/docs-old/ru/guide/lazy-loading.md deleted file mode 100644 index d63ff0332..000000000 --- a/docs-old/ru/guide/lazy-loading.md +++ /dev/null @@ -1,85 +0,0 @@ -# Ленивая загрузка переводов - -Одновременная загрузка всех файлов переводов может быть излишней и ненужной. - -Ленивая или асинхронная загрузка файлов переводов очень просто реализуется при использовании Webpack. - -Предположим, что у нас есть каталог проекта следующей структуры: - -``` -наш-проект-отлично --dist --src ---routes ---store ---setup ----i18n-setup.js ---lang ----en.js ----it.js -``` - -В каталоге `lang` располагаются все файлы переводов. В каталоге `setup` сгруппированы различные файлы настроек, например настройки i18n, регистрация глобальных компонентов, инициализации плагинов и другое. - -```js -// i18n-setup.js -import Vue from 'vue' -import VueI18n from 'vue-i18n' -import messages from '@/lang/en' -import axios from 'axios' - -Vue.use(VueI18n) - -export const i18n = new VueI18n({ - locale: 'en', // установка локализации - fallbackLocale: 'en', - messages // установка сообщений локализации -}) - -const loadedLanguages = ['en'] // список локализаций, которые пред-загружены - -function setI18nLanguage(lang) { - i18n.locale = lang - axios.defaults.headers.common['Accept-Language'] = lang - document.querySelector('html').setAttribute('lang', lang) - return lang -} - -export function loadLanguageAsync(lang) { - // Если локализация та же - if (i18n.locale === lang) { - return Promise.resolve(setI18nLanguage(lang)) - } - - // Если локализация уже была загружена - if (loadedLanguages.includes(lang)) { - return Promise.resolve(setI18nLanguage(lang)) - } - - // Если локализация ещё не была загружена - return import( - /* webpackChunkName: "lang-[request]" */ `@/i18n/messages/${lang}.js` - ).then(messages => { - i18n.setLocaleMessage(lang, messages.default) - loadedLanguages.push(lang) - return setI18nLanguage(lang) - }) -} -``` - -Для начала создаём новый экземпляр VueI18n как обычно. Затем определяем массив `loadedLanguages` в котором будем хранить список загруженных языков. Далее создаём функцию `setI18nLanguage`, которая будет переключать локализацию в экземпляре vueI18n, axios и где ещё это необходимо. - -Функция `loadLanguageAsync` будет использоваться для изменения языка. Загрузка новых файлов осуществляется функцией `import`, которую предоставляет Webpack и позволяет загружать файлы динамически, а поскольку она возвращает Promise, то можем легко дождаться окончания загрузки. - -Подробнее о динамических импортах можно изучить в [документации Webpack](https://webpack.js.org/guides/code-splitting/#dynamic-imports). - -Использовать `loadLanguageAsync` очень просто. Например, в хуке beforeEach vue-router. - -```js -router.beforeEach((to, from, next) => { - const lang = to.params.lang - loadLanguageAsync(lang).then(() => next()) -}) -``` - -Можно доработать реализацию, например добавив проверку поддерживается ли переданный `lang` или нет и вызывать `reject` чтобы отловить подобные случаи в хуке `beforeEach` и остановить навигацию. diff --git a/docs-old/ru/guide/locale.md b/docs-old/ru/guide/locale.md deleted file mode 100644 index 53aba5259..000000000 --- a/docs-old/ru/guide/locale.md +++ /dev/null @@ -1,54 +0,0 @@ -# Переключение локализации - -Обычно используют корневой экземпляр Vue в качестве точки истины, а все дочерние компоненты используют свойство `locale` от класса `VueI18n` передаваемого по ссылке. - -Иногда может потребоваться динамически переключать локализацию. Для этого нужно изменить значение свойства `locale` экземпляра `VueI18n`. - -```js -const i18n = new VueI18n({ - locale: 'ru', // устанавливаем локализацию по умолчанию - ... -}) - -// Создаём корневой экземпляр Vue -new Vue({ - i18n, - ... -}).$mount('#app') - -// Переключаем на другую локализацию -i18n.locale = 'en' -``` - -Каждый компонент содержит экземпляр `VueI18n`, ссылающийся на свойство `$i18n`, которое также можно использовать для переключения локализации. - -Пример: - -```vue - - - -``` - -:::warning Обратите внимание -:warning: Изменение локализации игнорируется компонентами с опцией `sync: false`. -::: - -:::warning Компонент vs. корневая область видимости -:warning: Изменение `$i18n.locale` внутри компонента не приводит к изменению корневой локализации. Если вы полагаетесь на корневую локализацию, например, при использовании [корневой запасной локализации](./fallback.html), используйте `$root.$i18n.locale` вместо `$i18n.locale`. -::: diff --git a/docs-old/ru/guide/messages.md b/docs-old/ru/guide/messages.md deleted file mode 100644 index 2c307b8c0..000000000 --- a/docs-old/ru/guide/messages.md +++ /dev/null @@ -1,318 +0,0 @@ -# Синтаксис сообщений локализации - -## Структура - -Синтаксис сообщений локализации: - -```typescript -// Как определение Flowtype, синтаксис сообщений перевода аналогичен аннотации BNF -type LocaleMessages = { [key: Locale]: LocaleMessageObject } -type LocaleMessageObject = { [key: Path]: LocaleMessage } -type LocaleMessageArray = LocaleMessage[] -type MessageContext = { - list: (index: number) => mixed, - named: (key: string) => mixed -}; -type MessageFunction = (ctx: MessageContext) => string; -type LocaleMessage = string | MessageFunction | LocaleMessageObject | LocaleMessageArray; -type Locale = string -type Path = string -``` - -Используя синтаксис выше, можно создать следующую структуру сообщений локализации: - -```json -{ - // локализация 'ru' - "ru": { - "key1": "это сообщение 1", // обычное использование - "nested": { - // вложенное - "message1": "это вложенное сообщение 1" - }, - "errors": [ - // массив - "это сообщение кода ошибки 0", - { - // объект в массиве - "internal1": "это внутреннее сообщение кода ошибки 1" - }, - [ - // массив в массиве - "это вложенный массив ошибки 1" - ] - ] - }, - // локализация 'en' - "en": { - // ... - } -} -``` - -Для такой структуры сообщений локализации, можно переводить сообщения используя ключи: - -```html -
- -

{{ $t('key1') }}

- -

{{ $t('nested.message1') }}

- -

{{ $t('errors[0]') }}

- -

{{ $t('errors[1].internal1') }}

- -

{{ $t('errors[2][0]') }}

-
-``` - -Результат: - -```html -
- -

это сообщение 1

- -

это вложенное сообщение 1

- -

это сообщение кода ошибки 0

- -

это внутреннее сообщение кода ошибки 1

- -

это вложенный массив ошибки 1

-
-``` - -## Связанные сообщения локализации - -Когда есть ключ с сообщением перевода, которое в точности повторяется в сообщении по другому ключу, то вместо дублирования можно поставить ссылку на него. Для этого к его содержимому нужно добавить префикс `@:` после которого указать полное имя ключа к сообщению перевода, включая пространство имён, к которому делаем ссылку. - -Сообщения локализации: - -```js -const messages = { - en: { - message: { - the_world: 'the world', - dio: 'DIO:', - linked: '@:message.dio @:message.the_world !!!!' - } - } -} -``` - -Шаблон: - -```html -

{{ $t('message.linked') }}

-``` - -Результат: - -```html -

DIO: the world !!!!

-``` - -### Форматирование связанных сообщений локализации - -Если важен регистр символов в переводе, то можно управлять регистром связанного сообщения локализации. Связанные сообщения можно отформатировать используя модификатор `@.modifier:key` - -Доступны следующие модификаторы: - -* `upper`: Форматирование в верхний регистр всех символов в связанном сообщении. -* `lower`: Форматирование в нижний регистр всех символов в связанном сообщении. -* `capitalize`: Форматирование заглавной первой буквы в связанном сообщении. - -Сообщения локализации: - -```js -const messages = { - en: { - message: { - homeAddress: 'Home address', - missingHomeAddress: 'Please provide @.lower:message.homeAddress' - } - }, - ru: { - message: { - homeAddress: 'Домашний адрес', - missingHomeAddress: 'Пожалуйста укажите @.lower:message.homeAddress' - } - } -} -``` - -```html - - -

{{ $t('message.missingHomeAddress') }}

-``` - -Результат: - -```html - - -

Пожалуйста укажите домашний адрес

-``` - -При необходимости можно добавлять новые модификаторы или перезаписывать существующие через опцию `modifiers` в конструкторе `VueI18n`. - -```js -const i18n = new VueI18n({ - locale: 'ru', - modifiers: { - // Добавление нового модификатора - snakeCase: str => str.split(' ').join('-') - }, - messages: { - // ... - }, -}) -``` - -### Группировка с помощью скобок - -Ключ связанного сообщения также можно указывать в виде `@:(message.foo.bar.baz)`, где ссылка на другой ключ перевода обрамляется в скобки `()`. - -Подобное может потребоваться, если за ссылкой на другое сообщение `@:message.something` требуется поставить точку `.`, которая в противном случае считалась бы частью ссылки. - -Сообщения локализации: - -```js -const messages = { - en: { - message: { - dio: 'DIO', - linked: "There's a reason, you lost, @:(message.dio)." - } - }, - ru: { - message: { - dio: 'DIO', - linked: "Есть причина по которой ты проиграл, @:(message.dio)." - } - } -} -``` - -Шаблон: - -```html -

{{ $t('message.linked') }}

-``` - -Результат: - -```html -

There's a reason, you lost, DIO.

-``` - -## Функция для сообщения - -vue-i18n рекомендует использовать строки для формата списком или именованного формата в качестве сообщения локализации при переводе сообщений. - -Однако бывают ситуации, когда из-за сложного синтаксиса языка, необходима полная мощь возможностей JavaScript. В таком случае, вместо строковых сообщений можно использовать **функцию для сообщения**. - -Функция ниже просто возвращает приветствие: - -```js -const messages = { - en: { - greeting: (ctx) => 'hello!' - }, - ru: { - greeting: (ctx) => 'привет!' - } -} -``` - -Использовать функцию для сообщения очень просто! Необходимо просто указать ключ с помощью `$t` или `t`: - -```html -

{{ $t('greeting') }}

-``` - -Результат будет таким: - -```html -

привет!

-``` - -Используется возвращаемый результат из функции для сообщения. - -### Именованный формат - -vue-i18n поддерживает [именованный формат](./formatting.md#именованный-формат) для строковых сообщений. vue-i18n интерполирует значения с помощью `$t` или `t` и выводит их. - -Тоже самое можно сделать и с функцией для сообщения, используя **контекст сообщения**: - -Пример приветствия: - -```js -const messages = { - en: { - greeting: (ctx) => `hello, ${ctx.named('name')}!` - }, - ru: { - greeting: (ctx) => `привет, ${ctx.named('name')}!` - } -} -``` - -Шаблон: - -```html -

{{ $t('greeting', { name: 'DIO' }) }}

-``` - -Результат: - -```html -

привет, DIO!

-``` - -Контекст сообщения предоставляет доступ к функции `named`. Необходимо указать ключ, указываемым для `$t` или `t`, который разрешится требуемым значением. - -### Формат списков - -Использование формата списков аналогично именованному формату, описанному выше. - -vue-i18n поддерживает [формат списков](./formatting.md#формат-списков) для строковых сообщений. vue-i18n интерполирует значения с помощью `$t` или `t` и выводит их. - -Тоже самое можно сделать и с функцией для сообщения, используя **контекст сообщения**: - -Пример приветствия: - -```js -const messages = { - en: { - greeting: (ctx) => `hello, ${ctx.list(0)}!` - }, - ru: { - greeting: (ctx) => `привет, ${ctx.list(0)}!` - } -} -``` - -Шаблон: - -```html -

{{ $t('greeting', ['DIO']) }}

-``` - -Результат: - -```html -

привет, DIO!

-``` - -Контекст сообщения предоставляет доступ к функции `list`. Необходимо указать ключ, указываемым для `$t` или `t`, который разрешится требуемым значением. - -### Ограничение - -В функции для сообщения следующие возможности, которые доступны в строковом варианте, не будут доступны через контекст сообщения: - -- Связанные сообщения локализации -- Плюрализация diff --git a/docs-old/ru/guide/number.md b/docs-old/ru/guide/number.md deleted file mode 100644 index b9bb04f1d..000000000 --- a/docs-old/ru/guide/number.md +++ /dev/null @@ -1,142 +0,0 @@ -# Локализация чисел - -:::tip Поддержка с версии -:new: 7.0+ -::: - -Можно выполнять локализацию чисел по соответствующему формату. - -Пример формата для чисел: - -```js -const numberFormats = { - 'en-US': { - currency: { - style: 'currency', - currency: 'USD' - } - }, - 'ru-RU': { - currency: { - style: 'currency', - currency: 'RUB', - currencyDisplay: 'symbol' - } - } -} -``` - -Как указано выше, можно задать числовые форматы (например, `currency` для валюты) используя [опции ECMA-402 Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat). - -После этого, для возможности использования данного формата в сообщениях локализации, необходимо задать опцию `numberFormats` конструктора `VueI18n`: - -```js -const i18n = new VueI18n({ - numberFormats -}) - -new Vue({ - i18n -}).$mount('#app') -``` - -Шаблон: - -```html -
-

{{ $n(100, 'currency') }}

-

{{ $n(100, 'currency', 'ru-RU') }}

-
-``` - -Результат: - -```html -
-

$100.00

-

100,00 ₽

-
-``` - -## Пользовательское форматирование - -:::tip Поддержка с версии -:new: 8.10+ -::: - -Метод `$n` возвращает результат в виде строки с полностью отформатированным числом, которую можно использовать лишь целиком. В случаях, когда нужно стилизовать некоторую часть отформатированного числа (например, дробную часть), `$n` будет недостаточно. В таких случаях необходимо использовать функциональный компонент ``. - -При минимальном наборе свойств `` генерирует тот же результат, что и `$n` обернутый в сконфигурированный DOM-элемент. - -Шаблон: - -```html -
- - - -
-``` - -Результат: - -```html -
- 100 - $100.00 - 100,00 ₽ -
-``` - -Но по-настоящему оценить удобство компонента можно лишь тогда, когда он применяется с использованием [слотов с ограниченной областью видимости](https://ru.vuejs.org/v2/guide/components-slots.html#%D0%A1%D0%BB%D0%BE%D1%82%D1%8B-%D1%81-%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9-%D0%BE%D0%B1%D0%BB%D0%B0%D1%81%D1%82%D1%8C%D1%8E-%D0%B2%D0%B8%D0%B4%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8). - -Допустим, есть требование выводить целую часть числа полужирным шрифтом. Реализовать это можно с помощью слота `integer`: - -```html - - - {{ slotProps.integer }} - - -``` - -Результат: - -```html -$100.00 -``` - -Можно использовать несколько слотов одновременно: - -```html - - - {{ slotProps.currency }} - - - {{ slotProps.integer }} - - - {{ slotProps.group }} - - - {{ slotProps.fraction }} - - -``` - -(Полученный HTML ниже отформатирован для лучшей читаемости) - -```html - - - 1 - , - 234 - 00 - -``` - -Определить тип корневого элемента можно указать с помощью входного параметра `tag`. Если входной параметр не указан, то по умолчанию будет `'span'`. Также можно указать значение `false`, чтобы вставлять дочерние элементы без создания и оборачивания в корневой. - -Полный список поддерживаемых слотов, а также другие свойства `` можно найти [на странице справочника API](../api/readme.md#i18n-n-functional-component). diff --git a/docs-old/ru/guide/pluralization.md b/docs-old/ru/guide/pluralization.md deleted file mode 100644 index cc1920c98..000000000 --- a/docs-old/ru/guide/pluralization.md +++ /dev/null @@ -1,174 +0,0 @@ -# Плюрализация - -Для переводимых сообщений есть возможность использовать плюрализацию. Для этого необходимо указывать строки переводов для различных случаев через разделитель `|`. - -*В шаблоне в таких случаях необходимо использовать метод `$tc()` вместо `$t()`.* - -Сообщения локализации: - -```js -const messages = { - en: { - car: 'car | cars', - apple: 'no apples | one apple | {count} apples' - }, - ru: { - car: 'машина | машины', - apple: 'нет яблок | одно яблоко | {count} яблок' - } -} -``` - -Шаблон: - -```html -

{{ $tc('car', 1) }}

-

{{ $tc('car', 2) }}

- -

{{ $tc('apple', 0) }}

-

{{ $tc('apple', 1) }}

-

{{ $tc('apple', 10, { count: 10 }) }}

-``` - -Результат: - -```html -

машина

-

машины

- -

нет яблок

-

одно яблоко

-

10 яблок

-``` - -## Аргумент для доступа к числу - -Нет необходимости явно передавать число для плюрализации. В сообщениях локализации число доступно через именованные аргументы `{count}` и/или `{n}`. При желании их можно переопределить. - -Сообщения локализации: - -```js -const messages = { - en: { - apple: 'no apples | one apple | {count} apples', - banana: 'no bananas | {n} banana | {n} bananas' - }, - ru: { - apple: 'нет яблок | одно яблоко | {count} яблок', - banana: 'нет бананов | {n} банан | {n} бананов' - } -} -``` - -Шаблон: - -```html -

{{ $tc('apple', 10, { count: 10 }) }}

-

{{ $tc('apple', 10) }}

- -

{{ $tc('banana', 1, { n: 1 }) }}

-

{{ $tc('banana', 1) }}

-

{{ $tc('banana', 100, { n: 'слишком много' }) }}

-``` - -Результат: - -```html -

10 яблок

-

10 яблок

- -

1 банан

-

1 банан

-

слишком много бананов

-``` - -## Пользовательская плюрализация - -Стандартная реализация плюрализации не подходит для некоторых языков (к примеру, в славянских языках другие правила множественности). - -Можно предоставить собственную реализацию, передав `pluralizationRules` в конструктор `VueI18n`. - -Упрощенный пример для славянских языков (Русский, Украинский и другие): -```js -new VueI18n({ - // Ключ - язык, для которого будет применяться правило, в этом примере - `'ru'` - // Value - функция плюрализации - pluralizationRules: { - /** - * @param choice {number} индекс выбора, переданный в $tc: `$tc('path.to.rule', choiceIndex)` - * @param choicesLength {number} общее количество доступных вариантов - * @returns финальный индекс для выбора соответственного варианта слова - */ - 'ru': function(choice, choicesLength) { - // this === VueI18n экземпляра, так что свойство locale также существует здесь - - if (choice === 0) { - return 0; - } - - const teen = choice > 10 && choice < 20; - const endsWithOne = choice % 10 === 1; - - if (choicesLength < 4) { - return (!teen && endsWithOne) ? 1 : 2; - } - if (!teen && endsWithOne) { - return 1; - } - if (!teen && choice % 10 >= 2 && choice % 10 <= 4) { - return 2; - } - - return (choicesLength < 4) ? 2 : 3; - } - } -}) -``` - -Такая реализация позволит использовать: - -```js -const messages = { - ru: { - car: '0 машин | {n} машина | {n} машины | {n} машин', - banana: 'нет бананов | {n} банан | {n} банана | {n} бананов' - } -} -``` - -Для такого формата вариантов `0 вещей | количество вещей заканчивается на 1 | количество вещей заканчивается на 2-4 | количество вещей заканчивается на 5-9, 0 и числа от 11 до 19`. -P.S. Славянское множественное число - сложное явление, подробнее о нем можно прочитать [здесь](http://www.russianlessons.net/lessons/lesson11_main.php). - -В шаблоне, по-прежнему, необходимо использовать `$tc()` вместо `$t()`: - -```html -

{{ $tc('car', 1) }}

-

{{ $tc('car', 2) }}

-

{{ $tc('car', 4) }}

-

{{ $tc('car', 12) }}

-

{{ $tc('car', 21) }}

- -

{{ $tc('banana', 0) }}

-

{{ $tc('banana', 4) }}

-

{{ $tc('banana', 11) }}

-

{{ $tc('banana', 31) }}

-``` - -Результат: - -```html -

1 машина

-

2 машины

-

4 машины

-

12 машин

-

21 машина

- -

нет бананов

-

4 банана

-

11 бананов

-

31 банан

-``` - -### Плюрализация по умолчанию - -Если для используемой локали не предоставить правило плюрализации, [по умолчанию](#плюрализация) будет использовано правило для английского языка diff --git a/docs-old/ru/guide/sfc.md b/docs-old/ru/guide/sfc.md deleted file mode 100644 index 321f84a94..000000000 --- a/docs-old/ru/guide/sfc.md +++ /dev/null @@ -1,408 +0,0 @@ -# Однофайловые компоненты - -## Базовое использование - -В компоненте Vue или приложении Vue с использованием однофайловых компонентов, можно управлять сообщениями локализации с помощью пользовательского блока `i18n`. - -Код компонента из [примера использования с однофайловыми компонентами](https://github.com/kazupon/vue-i18n/tree/dev/examples/sfc): - -```vue - -{ - "en": { - "hello": "hello world!" - }, - "ru": { - "hello": "Привет мир!" - } -} - - - - - -``` - -## Установка vue-i18n-loader - -Требуется установить `vue-loader` и `vue-i18n-loader` чтобы использовать пользовательские блоки ``. Скорее всего [vue-loader](https://github.com/vuejs/vue-loader) уже используется в проекте, если уже работаете с однофайловыми компонентами, но необходимо дополнительно установить [vue-i18n-loader](https://github.com/kazupon/vue-i18n-loader): - -```bash -npm i --save-dev @kazupon/vue-i18n-loader -``` - -## Webpack - -Для Webpack требуется следующая конфигурация: - -Для vue-loader v15 или более поздних версий: - -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader' - }, - { - resourceQuery: /blockType=i18n/, - type: 'javascript/auto', - loader: '@kazupon/vue-i18n-loader' - } - // ... - ] - } - // ... -} -``` - -Для vue-loader v14: - -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - loaders: { - // необходимо указать ключ `i18n` для загрузчика `vue-i18n-loader` - // (https://github.com/kazupon/vue-i18n-loader) - i18n: '@kazupon/vue-i18n-loader' - } - } - } - // ... - ] - } - // ... -} -``` - -## Vue CLI 3.0 - -[Vue CLI 3.0](https://github.com/vuejs/vue-cli) скрывает конфигурацию Webpack, поэтому для добавления поддержки тегов `` в однофайловых компонентах необходимо изменить существующую конфигурацию. - -Для этого нужно создать файл `vue.config.js` в корне проекта и добавить в него следующее: - -Для vue-loader v15 или более поздних версий: - -```js -module.exports = { - chainWebpack: config => { - config.module - .rule('i18n') - .resourceQuery(/blockType=i18n/) - .type('javascript/auto') - .use('i18n') - .loader('@kazupon/vue-i18n-loader') - .end() - } -} -``` - -Для vue-loader v14: - -```js -const merge = require('deepmerge') - -module.exports = { - chainWebpack: config => { - config.module - .rule('vue') - .use('vue-loader') - .tap(options => - merge(options, { - loaders: { - i18n: '@kazupon/vue-i18n-loader' - } - }) - ) - } -} -``` - -_Не забудьте установить [deepmerge](https://github.com/KyleAMathews/deepmerge)! (`npm i deepmerge -D` или `yarn add deepmerge -D`)_ - -Подробнее о возможностях изменения существующей конфигурации Webpack можно изучить [здесь](https://cli.vuejs.org/ru/guide/webpack.html). - -## Laravel-Mix - -Для Laravel-mix 4 с vue-loader v15 или более поздней версии: - -```js -// Расширяем Mix с помощью метода "i18n", который загрузит vue-i18n-loader -mix.extend( 'i18n', new class { - webpackRules() { - return [ - { - resourceQuery: /blockType=i18n/, - type: 'javascript/auto', - loader: '@kazupon/vue-i18n-loader', - }, - ]; - } - }(), -); - -// Убедитесь что вызвали .i18n() (для загрузки загрузчика) перед .js(..., ...) -mix.i18n() - .js( 'resources/js/App.js', 'public/js/app.js' ) - ... -``` - -Для Laravel-mix 2 с vue-loader v14: - -В Laravel-mix, начиная с версии [V2.1](https://github.com/JeffreyWay/laravel-mix/releases/tag/v2.1), можно добавлять пользовательские правила с помощью `mix.extend()`. Laravel-mix уже имеет собственные правила для обработки `.vue` файлов. Чтобы добавить `vue-i18n-loader`, нужно добавить в `webpack.mix.js` следующее: - -```js -// Код ниже внедрит загрузчик i18n (@kazupon/vue-i18n-loader) в качестве загрузчика .vue файлов. -mix.extend( 'i18n', function( webpackConfig, ...args ) { - webpackConfig.module.rules.forEach( ( module ) => { - // Поиск компонента "vue-loader", который обрабатывает .vue файлы. - if( module.loader !== 'vue-loader' ) { - return; - } - - // В этом модуле добавляем vue-i18n-loader для тега i18n. - module.options.loaders.i18n = '@kazupon/vue-i18n-loader'; - } ); -} ); - -// Убедитесь что вызвали .i18n() (для загрузки загрузчика) перед .js(..., ...) -mix.i18n() - .js( 'resources/assets/js/App.js', 'public/js/app.js' ) - ... -``` - -## Загрузка YAML - -Пользовательские блоки `i18n` можно указывать в формате `JSON` или `YAML` (используя функцию предварительного загрузчика `vue-loader`). - -Пользовательский блок `i18n` в формате `YAML`: - -```vue - - en: - hello: "hello world!" - ru: - hello: "привет мир!" - -``` - -Конфигурация Webpack: - -Для vue-loader v15 или более поздних версий: - -```js -// Vue CLI 3.0 -module.exports = { - chainWebpack: config => { - config.module - .rule('i18n') - .resourceQuery(/blockType=i18n/) - .type('javascript/auto') - .use('i18n') - .loader('@kazupon/vue-i18n-loader') - .end() - .use('yaml') - .loader('yaml-loader') - .end() - } -} -``` - -Для vue-loader v14: - -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - preLoaders: { - i18n: 'yaml-loader' - }, - loaders: { - i18n: '@kazupon/vue-i18n-loader' - } - } - } - // ... - ] - } - // ... -} -``` - -## Несколько пользовательских блоков - -Можно использовать сообщения локализации из нескольких пользовательских блоков `i18n`. - -```vue - - - { - "en": { - "hello": "hello world!" - }, - "ru": { - "hello": "Привет мир!" - } - } - -``` - -В примере выше, первый пользовательский блок загружает общие сообщения локализации с помощью атрибута `src`, второй пользовательский блок загружает сообщения локализации, которые определены только в этом однофайловом компоненте. Все они будут объединены в качестве сообщений локализации компонента. - -Несколько пользовательских блоков полезны, когда использовать их в качестве модулей. - -## Локальные стили - -При использовании `vue-i18n` с локальными стилями (`style scoped`) необходимо помнить и использовать [глубокий селектор](https://vue-loader.vuejs.org/ru/guide/scoped-css.html#%D0%BA%D0%BE%D1%80%D0%BD%D0%B5%D0%B2%D0%BE%D0%B9-%D1%8Dn%D0%B5%D0%BC%D0%B5%D0%BD%D1%82-%D0%B4%D0%BE%D1%87%D0%B5%D1%80%D0%BD%D0%B5%D0%B3%D0%BE-%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82%D0%B0) для стилизации элемента __*внутри*__ строки перевода. Например: - -__Когда перевод содержит только текст__ (работает без глубокого селектора) - -```vue - - { - "en": { - "hello": "hello world!" - }, - "ru": { - "hello": "Привет мир!" - } - } - - - - - - -``` - -__Когда перевод содержит HTML-элемент__ (необходимо использовать глубокий селектор) - -```vue - - { - "en": { - "hello": "helloworld!" - }, - "ru": { - "hello": "привет мир!" - } - } - - - - - - - - - - - - - - - -``` - -## Пользовательские блоки в функциональном компоненте - -Если в шаблоне однофайловых компонентов используется функциональный компонент и определены пользовательские блоки `i18n`, то обратите внимание что невозможно локализовать с помощью сообщений локализации. - -Например, следующий код не может использовать сообщения локализации из блока `i18n`. - -```vue - - { - "en": { - "hello": "hello world" - }, - "ru": { - "hello": "привет мир" - } - } - - - -``` diff --git a/docs-old/ru/guide/tooling.md b/docs-old/ru/guide/tooling.md deleted file mode 100644 index 92fa19a93..000000000 --- a/docs-old/ru/guide/tooling.md +++ /dev/null @@ -1,72 +0,0 @@ -# Инструментарий - -Для поддержки i18n приложений Vue некоторые инструменты предоставляются официально. - -Также есть инструменты от сторонних разработчиков, которые интегрируются в Vue I18n. - -## Официальный инструментарий - -### Плагин для Vue CLI - -[vue-cli-plugin-i18n](https://github.com/kazupon/vue-cli-plugin-i18n) — официальный плагин для Vue CLI. - -С помощью этого плагина можно настроить среду i18n для приложения Vue и поддерживать среду разработки i18n. - -### Модуль для Nuxt - -[nuxt-i18n](https://github.com/nuxt-community/nuxt-i18n/) — соответствующий модуль для Nuxt.js. - -### Загрузчик для Webpack - -[vue-i18n-loader](https://github.com/kazupon/vue-i18n-loader) — официальный загрузчик для webpack. - -С помощью этого загрузчика можно использовать пользовательские блоки `i18n` в однофайловых компонентах. - -Подробнее о пользовательских блоках `i18n` можно изучить в разделе [Однофайловых компонентов](./sfc.md) - -### Плагин для ESLint - -[eslint-plugin-vue-i18n](https://intlify.github.io/eslint-plugin-vue-i18n/) — ESLint-плагин для Vue I18n. - -Позволяет легко интегрировать функции проверки локализацией в ваше приложение Vue.js. - -### Расширения - -[vue-i18n-extensions](https://github.com/kazupon/vue-i18n-extensions) — предоставляет некоторые расширения дляVue I18n. - -Эти расширения позволяет использовать в рендеринге на стороне сервера (SSR) и улучшить производительность i18n. - -## Сторонние разработки - -### BabelEdit - -[BabelEdit](https://www.codeandweb.com/babeledit) — редактор переводов для веб-приложений. - -BabelEdit может переводить файлы `json`, а также умеет работать с пользовательскими блоками `i18n` однофайловых компонентов. - -Подробнее про BabelEdit можно узнать [на странице введения](https://www.codeandweb.com/babeledit/tutorials/how-to-translate-your-vue-app-with-vue-i18n). - -### i18n Ally - -[i18n Ally](https://marketplace.visualstudio.com/items?itemName=antfu.i18n-ally) — расширение i18n для VSCode. - -i18n Ally предоставляет потрясающий DX для разработки с использованием i18n. - -Подробнее о расширении i18n Ally можно изучить в [README](https://github.com/antfu/i18n-ally/blob/master/README.md). - -### i18nPlugin (платформа intellij) - -[i18nPlugin](https://github.com/nyavro/i18nPlugin) — плагин Intellij idea для поддержки i18next ([Jetbrains plugin page](https://plugins.jetbrains.com/plugin/12981-i18n-support)). - -Плагин для i18n typescript/javascript/PHP. Поддерживает vue-i18n. Для включения поддержки vue-i18n в настройках -> Tools -> i18n Plugin configuration выберите "Vue-i18n". Необходимо установить каталоги с файлами локализаций (по умолчанию locales). - -### vue-i18n-extract - -[vue-i18n-extract](https://github.com/pixari/vue-i18n-extract) выполняет статический анализ проекта Vue.js на основе vue-i18n и сообщает следующую информацию: - -- список всех **неиспользуемых ключей vue-i18n** (записи, найденные в файлах перевода, но не использованные в проекте) -- список всех **пропущенных ключей** (записи, найденные в проекте, но отсутствующие в файлах перевода) - -Имеется возможность отобразить результат в консоли или записать его в файл json. - -Пропущенные ключи также могут быть автоматически добавлены в заданные файлы переводов. diff --git a/docs-old/ru/installation.md b/docs-old/ru/installation.md deleted file mode 100644 index 2df4d851d..000000000 --- a/docs-old/ru/installation.md +++ /dev/null @@ -1,85 +0,0 @@ -# Установка - -## Примечание совместимости - -- Vue.js версии `2.0.0`+ - -## Загрузка файла / CDN - - - -Сервис [unpkg.com](https://unpkg.com) предоставляет CDN-ссылки на основе NPM-пакетов. Ссылка выше будет всегда указывать на последнюю версию на NPM. Можно использовать конкретную версию или тег с помощью URL следующего вида - -При подключении vue-i18n после Vue плагин установит себя автоматически: - -```html - - -``` - -## NPM - -```bash -npm install vue-i18n -``` - -## Yarn - -```bash -yarn add vue-i18n -``` - -При использовании системы модулей нужно явно устанавливать `vue-i18n` -через `Vue.use()`: - -```js -import Vue from 'vue' -import VueI18n from 'vue-i18n' - -Vue.use(VueI18n) -``` - -Подобного не требуется делать при подключении через глобальный тег ` - - -
-

{{ $t("message.hello") }}

-
-``` - -## JavaScript - -```js -// При использовании модульной системы (например, через vue-cli) -// нужно импортировать Vue и VueI18n и вызвать Vue.use(VueI18n). -// -// import Vue from 'vue' -// import VueI18n from 'vue-i18n' -// -// Vue.use(VueI18n) - -// Готовые переводы сообщений локализаций -const messages = { - en: { - message: { - hello: 'hello world' - } - }, - ru: { - message: { - hello: 'Привет мир' - } - } -} - -// Создание экземпляра VueI18n с настройками -const i18n = new VueI18n({ - locale: 'ru', // установка локализации по умолчанию - messages // установка сообщений локализаций -}) - -// Создание экземпляра Vue с опцией `i18n` -new Vue({ i18n }).$mount('#app') - -// Теперь можно запускать приложение! -``` - -Результат будет таким: - -```html -
-

Привет мир

-
-``` diff --git a/docs-old/started.md b/docs-old/started.md deleted file mode 100644 index 7b0256a4f..000000000 --- a/docs-old/started.md +++ /dev/null @@ -1,61 +0,0 @@ -# Getting started - -:::tip NOTE -We will be using [ES2015](https://github.com/lukehoban/es6features) in the -code samples in the guide. -::: - -## HTML - -```html - - - -
-

{{ $t("message.hello") }}

-
-``` - -## JavaScript - -```js -// If using a module system (e.g. via vue-cli), import Vue and VueI18n and then call Vue.use(VueI18n). -// import Vue from 'vue' -// import VueI18n from 'vue-i18n' -// -// Vue.use(VueI18n) - -// Ready translated locale messages -const messages = { - en: { - message: { - hello: 'hello world' - } - }, - ja: { - message: { - hello: 'こんにちは、世界' - } - } -} - -// Create VueI18n instance with options -const i18n = new VueI18n({ - locale: 'ja', // set locale - messages, // set locale messages -}) - - -// Create a Vue instance with `i18n` option -new Vue({ i18n }).$mount('#app') - -// Now the app has started! -``` - -Output the following: - -```html -
-

こんにちは、世界

-
-``` diff --git a/docs-old/zh/README.md b/docs-old/zh/README.md deleted file mode 100644 index e97282add..000000000 --- a/docs-old/zh/README.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -home: true -heroImage: ./../vue-i18n-logo.png -actionText: 快速上手 → -actionLink: introduction.md -footer: MIT Licensed | Copyright © 2020 kazuya kawaguchi ---- - -
-

🥇 金牌赞助商

- - Nuxt.js - -

🥈 白银赞助商

- - 适用于应用程序(Web应用程序)的BabelEdit翻译编辑器 - -

🥉 青铜赞助商

- - zenarchitects - - - sendcloud - -
- -
- -
- -
-
-

简单

-

通过简单的 API 将你的应用国际化

-
-
-

强大

-

除了简单的翻译外,还支持复数,数字,日期时间等本地化处理

-
-
-

面向组件

-

你可以在单文件组件上管理语言环境信息

-
-
diff --git a/docs-old/zh/api/README.md b/docs-old/zh/api/README.md deleted file mode 100755 index 05c65f357..000000000 --- a/docs-old/zh/api/README.md +++ /dev/null @@ -1,701 +0,0 @@ ---- -sidebar: auto ---- - -# API参考 - -## 扩展 Vue - -### Vue 构造函数选项 - -#### i18n - - * **类型:** `I18nOptions` - -基于组件的本地化选项 - - * **请参阅:** `VueI18n` 类构造函数选项 - -### Vue 注入方法 - -#### $t - - * **参数** - - * `{Path} key`:必填 - * `{Locale} locale`:可选 - * `{Array | Object} values`:可选 - - * **返回值:**`TranslateResult` - -本地化语言环境信息 `key`,在本地化时组件的语言环境信息优先于全局语言环境信息。如果未指定组件的语言环境信息,就使用全局语言环境信息进行本地化。如果你指定了 `locale` 参数,则使用 `locale` 提供的语言环境进行本地化。如果你为列表/格式化的语言环境信息指定了 `key`,就必须同时指定 `values`。有关 `values` 的详细信息,请参阅[格式化](../guide/formatting.md)。 - -:::danger 提示 -注意,你需要在生命周期方法中保证上下文是组件实例 (例如在 `data` 选项中,`const $t = this.$t.bind(this)`)。 -::: - -#### $tc - - * **参数:** - - * `{Path} key`:必填 - * `{number} choice`:可选,默认为 1 - * `{Locale} locale`:可选 - * `{string | Array | Object} values`:可选 - - * **返回值:**`TranslateResult` - -以复数形式将语言环境信息 `key` 本地化。在本地化时组件的语言环境信息优先于全局语言环境信息。如果未指定组件的语言环境信息,就使用全局语言环境信息进行本地化。如果你指定了 `locale` 参数,则使用 `locale` 提供的语言环境进行本地化。如果将 `values` 指定为字符串,则该字符串会作为语言环境信息进行本地化。如果将 `values` 指定为 Array 或 Object,则格式必须为 `$t` 的 `values`。 - -:::danger 提示 -注意,你需要在生命周期方法中保证上下文是组件实例 (例如在 `data` 选项中,`const $tc = this.$tc.bind(this)`) -::: - -#### $te - - * **参数:** - - * `{Path} key`:必填 - * `{Locale} locale`:可选 - - * **返回值:**`boolean` - -检查 key 是否存在。在 Vue 实例中,如果未指定组件语言环境信息,则使用全局语言环境信息。如果指定了 `locale`,则使用 `locale` 的语言环境。 - -:::danger 提示 -注意,你需要在生命周期方法中保证上下文是组件实例 (例如在 `data` 选项中,`const $te = this.$te.bind(this)`)。 -::: - -#### $d - -> :new: 7.0+ 新增 - - * **参数:** - - * `{number | Date} value`:必填 - * `{Path | Object} key`:可选 - * `{Locale | Object} locale`:可选 - - * **返回值:**`DateTimeFormatResult` - -将日期时间 `value` 以 `key` 的格式本地化。日期时间格式 `key` 需要注册到 `VueI18n` 类的 `dateTimeFormats` 选项,并依赖于 `VueI18n` 构造函数的 `locale` 选项。如果要指定 `locale` 参数,它将优先于 `VueI18n` 构造函数的 `locale` 选项。 - -如果 `dateTimeFormats` 选项中不存在日期时间格式的 `key`,则根据 `VueI18n` 构造函数的 `fallbackLocale` 选项回退。 - -:::danger 提示 -注意,你需要在生命周期方法中保证上下文是组件实例 (例如在 `data` 选项中,`const $d = this.$d.bind(this)`)。 -::: - -#### $n - -> :new: 7.0+ 新增 - - * **参数:** - - * `{number} value`:必填 - * `{Path | Object} key`:可选 - * `{Locale} locale`:可选 - - * **返回值:**`NumberFormatResult` - -将数字 `value` 以 `key` 的格式本地化。数字格式 `key` 需要注册到 `VueI18n` 类的 `numberFormats` 选项,并依赖于 `VueI18n` 构造函数的 `locale` 选项。如果要指定 `locale` 参数,它将优先于 `VueI18n` 构造函数的 `locale` 选项。 - -如果 `numberFormats` 选项中不存在用数字格式 `key`,则根据 `VueI18n` 构造函数的 `fallbackLocale` 选项回退。 - -如果第二个 `key` 参数指定为对象,则它应具有以下属性: - -* `key {Path}`:可选,数字格式 -* `locale {Locale}`:可选,语言环境 -* `style {string}`:可选,数字格式选项 -* `currency {string}`:可选,数字格式选项 -* `currencyDisplay {string}`:可选,数字格式选项 -* `useGrouping {string}`:可选,数字格式选项 -* `minimumIntegerDigits {string}`:可选,数字格式选项 -* `minimumFractionDigits {string}`:可选,数字格式选项 -* `maximumFractionDigits {string}`:可选,数字格式选项 -* `minimumSignificantDigits {string}`:可选,数字格式选项 -* `maximumSignificantDigits {string}`:可选,数字格式选项 -* `localeMatcher {string}`:可选,数字格式选项 -* `formatMatcher {string}`:可选,数字格式选项 - -任何指定数字的格式选项将优先于 `VueI18n` 构造函数的 `numberFormats`。 - -:::danger 提示 -注意,你需要在生命周期方法中保证上下文是组件实例 (例如在 `data` 选项中,`const $n = this.$n.bind(this)`)。 -::: - -### 注入属性 - -#### $i18n - - * **类型:**`I18n` - - * **只读** - -若已经指定了 `VueI18n` 实例,则将其返回。 - -如果在组件选项中指定了 `i18n` 选项,则可以在组件上获得 `VueI18n` 实例,否则,你将获得 `VueI18n` 的根实例。 - -## `VueI18n` 类 - -`Vuei18n` 类实现了 `I18n` [flowtype 接口](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -### 静态属性 - -#### 版本 - - * **类型:**`string` - -vue-i18n 版本 - -#### 可用性 - -> :new: 7.0+ 新增 - - * **类型:**`IntlAvailability` - -是否提供以下国际化功能: - - * `{boolean} dateTimeFormat`:环境敏感的时间格式 - - * `{boolean} numberFormat`:环境敏感的数字格式 - -由于使用 ECMAScript Internationalization API (ECMA-402) 实现,上述国际化功能取决于[浏览器环境](http://kangax.github.io/compat-table/esintl/)。 - -### 构造函数选项 - -你可以基于[flowtype 定义](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) 中的 `I18nOptions` 指定下列构造函数选项 - -#### locale - - * **类型:**`Locale` - - * **默认值:**`'en-US'` - -语言环境。 - -#### fallbackLocale - - * **类型:**`Locale` - - * **默认值:**`'en-US'` - -预设的语言环境。 - -#### messages - - * **类型:**`LocaleMessages` - - * **默认值:**`{}` - -本地化的语言环境信息。 - -#### dateTimeFormats - -> :new: 7.0+ 新增 - - * **类型:**`DateTimeFormats` - - * **默认值:**`{}` - -本地化的日期时间格式。 - - * **请参阅:**`DateTimeFormats` 类型的[flowtype 接口](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -#### numberFormats - -> :new: 7.0+ 新增 - - * **类型:**`NumberFormats` - - * **默认值:**`{}` - -本地化的数字格式。 - - * **请参阅:**`NumberFormats` 类型的[flowtype 接口](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js) - -#### availableLocales - -> :new: 8.9.0+ 新增 - - * **类型:**`Locale[]` - - * **默认值:**`[]` - - * **示例:**`["en", "ja"]` - -以词法顺序排列的 `messages` 中的可用语言环境列表。 - -#### formatter - - * **类型:**`Formatter` - - * **默认值:** Built in formatter - -使用 `Formatter` 接口实现的格式化。 - -#### missing - - * **类型:**`MissingHandler` - - * **默认值:**`null` - -缺少本地化时的处理函数。该处理函数在被调用时会使用本地化目标语言环境,本地化路径关键字和 Vue 实例。 - -如果设置了该函数,则本地化信息未定义时不会产生警告。 - -#### fallbackRoot - - * **类型:**`Boolean` - - * **默认值:**`true` - -在组件本地化中,当本地化失败时是否回退到根级别 (全局) 本地化。 - -如果为 `false`,则会发出警告,并返回 key。 - -#### sync - - * **类型:**`Boolean` - - * **默认值:**`true` - -是否将根级别语言环境与组件本地化语言环境同步。 - -如果为 `false`,则无论根级别语言环境如何,都要为每个组件语言环境进行本地化。 - -#### silentTranslationWarn - -> 6.1+ 新增 - - * **类型:**`Boolean` - - * **默认值:**`false` - -是否取消本地化失败时输出的警告。 - -如果为 `true`,则禁止本地化失败警告。 - -#### silentFallbackWarn - -> :new: 8.8 新增 - - * **类型:**`Boolean` - * **默认值:**`false` - -是否在回退到 `fallbackLocale` 或 `root` 时取消警告。 - -如果为 `true`,则仅在根本没有可用的转换时生成警告,而不是在回退时。 - -#### pluralizationRules - -> 8.5+ - - * **Type:** `PluralizationRules` - - * **Default:** `{}` - - A set of rules for word pluralization in a following format: - ```js - { - // Key - locale for the rule to be applied to. - // Value - mapping function that maps a choice index from `$tc` to the actual choice of the plural word. (See getChoiceIndex for details) - 'pt': function(choice, choiceIndex) => Number/* index of the plural word */; - 'ru': function(choice, choiceIndex) => Number/* index of the plural word */; - 'en': function(choice, choiceIndex) => Number/* index of the plural word */; - 'jp': function(choice, choiceIndex) => Number/* index of the plural word */; - } - ``` - -#### preserveDirectiveContent - -> 8.7+ 新增 - - * **类型:**`Boolean` - - * **默认值:**`false` - -在指令解除绑定后,`v-t` 指令的元素是否应该保留 `textContent`。 - -### Properties - -#### locale - - * **类型:**`Locale` - - * **可读/可写** - -语言环境。 - -#### fallbackLocale - - * **类型:**`Locale` - - * **可读/可写** - -预设的语言环境。 - -#### messages - - * **类型:**`LocaleMessages` - - * **只读** - -本地化的语言环境信息。 - -#### dateTimeFormats - -> :new: 7.0+ 新增 - - * **类型:**`DateTimeFormats` - - * **只读** - -本地化的日期时间格式。 - -#### numberFormats - -> :new: 7.0+ 新增 - - * **类型:**`NumberFormats` - - * **只读** - -本地化的数字格式。 - -#### missing - - * **类型:**`MissingHandler` - - * **可读/可写** - -缺少本地化时的处理函数。 - -#### formatter - - * **类型:**`Formatter` - - * **可读/可写** - -使用 `Formatter` 接口实现的格式化。 - -#### silentTranslationWarn - -> 6.1 新增 - - * **类型:**`boolean` - - * **可读/可写** - -是否取消本地化失败时输出的警告。 - -#### pluralizationRules - -> 8.5+ - - * **Type:** `PluralizationRules` - - * **Read/Write** - -A set of locale-dependent rules for word pluralization. - -#### preserveDirectiveContent - -> 8.7+ 新增 - - * **类型:**`boolean` - - * **可读/可写** - -在指令解除绑定后,`v-t` 指令的元素是否应该保留 `textContent`。 - -### 方法 - -#### getChoiceIndex - - * **参数:** - - * `{number} choice` - * `{number} choicesLength` - - * **返回值:**`finalChoice {number}` - -根据当前的数字和一组给定的选项,获取其复数索引,可以通过原型变更覆盖: - -```js -VueI18n.prototype.getChoiceIndex = /* 自定义实现 */ -``` - -However, for most usages [pluralizationRules constructor option](#pluralizationrules) should be enough. - -#### getLocaleMessage( locale ) - - * **参数:** - - * `{Locale} locale` - - * **返回值:**`LocaleMessageObject` - -获取语言环境的 `locale` 信息。 - -#### setLocaleMessage( locale, message ) - - * **参数:** - - * `{Locale} locale` - * `{LocaleMessageObject} message` - -设置语言环境的 `locale` 信息。 - -#### mergeLocaleMessage( locale, message ) - -> 6.1+ 新增 - - * **参数:** - - * `{Locale} locale` - * `{LocaleMessageObject} message` - -将语言环境信息 `locale` 合并到已注册的语言环境信息中。 - -#### t( key, [locale], [values] ) - - * **参数:** - - * `{Path} key`:必填 - * `{Locale} locale`:可选 - * `{Array | Object} values`:可选 - - * **返回值:**:`TranslateResult` - -这与 `$t` 方法返回的 `Function` 相同。更多细节见[$t](#t)。 - -#### tc( key, [choice], [values] ) - - * **参数:** - - * `{Path} key`:必填 - * `{number} choice`:可选,默认为 1 - * `{string | Array | Object} values`:可选 - - * **返回值:**`TranslateResult` - -这与 `$tc` 方法返回的 `Function` 相同。更多细节见[$tc](#tc)。 - -#### te( key, [locale] ) - - * **参数:** - - * `{string} key`:必填 - * `{Locale} locale`:可选 - - * **返回值:**`boolean` - -检查全局语言环境信息中是否存在键名路径。如果指定了 `locale`,请检查语言环境信息 `locale`。 - -#### getDateTimeFormat ( locale ) - -> :new: 7.0+ 新增 - - * **参数:** - - * `{Locale} locale` - - * **返回值:**`DateTimeFormat` - -获取语言环境的日期时间格式。 - -#### setDateTimeFormat ( locale, format ) - -> :new: 7.0+ 新增 - - * **参数:** - - * `{Locale} locale` - * `{DateTimeFormat} format` - -设置语言环境的日期时间格式。 - -#### mergeDateTimeFormat ( locale, format ) - -> :new: 7.0+ 新增 - - * **参数:** - - * `{Locale} locale` - * `{DateTimeFormat} format` - -将已注册的日期时间格式与语言环境的日期时间格式合并。 - -#### d( value, [key], [locale] ) - -> :new: 7.0+ 新增 - - * **参数:** - - * `{number | Date} value`:必填 - * `{Path | Object} key`:可选 - * `{Locale | Object} locale`:可选 - - * **返回值:**`DateTimeFormatResult` - -这与 Vue 实例方法的 `$d` 方法相同。更多细节见[$d](#d)。 - -#### getNumberFormat ( locale ) - -> :new: 7.0+ 新增 - - * **参数:** - - * `{Locale} locale` - - * **返回值:**`NumberFormat` - -获取语言环境的数字格式。 - -#### setNumberFormat ( locale, format ) - -> :new: 7.0+ 新增 - - * **参数:** - - * `{Locale} locale` - * `{NumberFormat} format` - -设置语言环境的数字格式。 - -#### mergeNumberFormat ( locale, format ) - -> :new: 7.0+ 新增 - - * **参数:** - - * `{Locale} locale` - * `{NumberFormat} format` - -将已注册的数字格式与语言环境的数字格式合并。 - -#### n( value, [key], [locale] ) - -> :new: 7.0+ 新增 - - * **参数:** - - * `{number} value`:必填 - * `{Path | Object} key`:可选 - * `{Locale} locale`:可选 - - * **返回值:**`NumberFormatResult` - -这与 Vue 实例方法的 `$n` 方法相同。更多细节见[$n](#n)。 - -## 指令 - -> :new: 7.3+ 新增 - -### v-t - - * **预期:**`string | Object` - - * **修饰符:** - - * `.preserve`:(8.7.0 新增) 当指令解除绑定时,保留元素 `textContent`。 - - * **详细:** - -更新使用语言环境信息进行本地化的元素 `textContent`。你可以使用字符串语法或对象语法。字符串语法可以指定为语言环境信息的关键字路径。如果可以使用对象语法,则需要将以下参数指定为对象键: - - * `path`:必填,语言环境信息的关键字 - * `locale`:可选,语言环境 - * `args`:可选,用于列表或命名格式 - -::::tip 注意 -当 `v-t` 指令解除绑定时,默认情况下将清除元素 `textContent`。在[过渡动画](https://cn.vuejs.org/v2/guide/transitions.html)内部使用的时候,可能出现不合预期的情况。为了在指令解除绑定之后保留 `textContent` 数据,可使用 `.preserve` 修饰符或全局的 [`preserveDirectiveContent` 选项](#preservedirectivecontent)。 -:::: - * **示例:** -```html - -

- - -

- - -

- - -

- - -

-``` - - * **请参阅:**[自定义指令本地化](../guide/directive.md) - -## 组件 - -### i18n 函数式组件 - -> :new: 7.0+ 新增 - -#### 参数: - - * `path {Path}`:必填,关于语言环境信息的键名路径 - * `locale {Locale}`:可选,语言环境 - * `tag {string}`:可选,默认值 `span` - * `places {Array | Object}`:可选 (7.2 新增) - -#### 用法: - -```html -
- - - {{ $t('tos') }} - - -
-``` -```js -const messages = { - en: { - tos: 'Term of Service', - term: 'I accept xxx {0}.' - }, - ja: { - tos: '利用規約', - term: '私は xxx の{0}に同意します。' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) -new Vue({ - i18n, - data: { - url: '/term' - } -}).$mount('#app') -``` - -#### 请参阅: - -[组件插值](../guide/interpolation.md) - -## 特殊属性 - -### place - -> :new: 7.2+ 新增 - -#### 预期:`{number | string}` - -用于组件插槽,指示格式列表的索引值或具名格式的关键字。 - -有关详细用法,请参阅下面链接的指南部分。 - -#### 请参阅: - -[组件插值](../guide/interpolation.md) diff --git a/docs-old/zh/guide/component.md b/docs-old/zh/guide/component.md deleted file mode 100644 index 119b49fee..000000000 --- a/docs-old/zh/guide/component.md +++ /dev/null @@ -1,151 +0,0 @@ -# 基于组件的本地化 - -通常语言环境信息 (例如:`locale`、`messages` 等) 会被设置为 `VueI18n` 实例的构造函数选项,并且该实例会被作为 `i18n` 选项设置在 Vue 的根实例上。 - -因此你可以全局地在 Vue 的根实例以及任何被组合的组件中使用 `$t` 或者 `$tc` 进行翻译。当然面向 Vue 组件的设计,你也可以更方便的分别控制每个组件的语言环境信息。 - -基于组件的本地化示例: - -```js -// 为 Vue 的根实例设置语言环境信息 -const i18n = new VueI18n({ - locale: 'ja', - messages: { - en: { - message: { - hello: 'hello world', - greeting: 'good morning' - } - }, - ja: { - message: { - hello: 'こんにちは、世界', - greeting: 'おはようございます' - } - } - } -}) - -// 定义组件 -const Component1 = { - template: ` -
-

Component1 locale messages: {{ $t("message.hello") }}

-

Fallback global locale messages: {{ $t("message.greeting") }}

-
`, - i18n: { // `i18n` 选项,为组件设置语言环境信息 - messages: { - en: { message: { hello: 'hello component1' } }, - ja: { message: { hello: 'こんにちは、component1' } } - } - } -} - -new Vue({ - i18n, - components: { - Component1 - } -}).$mount('#app') -``` - -模板: - - -```html -
-

{{ $t("message.hello") }}

- -
-``` - -输出如下: - -```html -
-

こんにちは、世界

-
-

Component1 locale messages: こんにちは、component1

-

Fallback global locale messages: おはようございます

-
-
-``` - -在上面的例子中,如果组件没有语言环境信息,它将回退到全局定义的本地化信息。组件使用根实例中设置的语言 (在上面的例子中:`locale: 'ja'`)。 - -注意,在默认情况下,回退到根语言环境会在控制台中生成两个警告: - -``` -[vue-i18n] Value of key 'message.greeting' is not a string! -[vue-i18n] Fall back to translate the keypath 'message.greeting' with root locale. -``` - -为避免以上警告 (同时保留那些完全没有翻译给定关键字的警告) 需初始化 `VueI18n` 实例时设置 `silentFallbackWarn:true`。 - -如果你希望在组件语言环境中进行本地化,可以在 `i18n` 选项中用 `sync: false` 和 `locale`。 - -## 组件的共享语言环境消息 - -有时您可能想为某些组件导入共享的语言环境消息,而不是从全局语言环境消息(例如,组件某些功能的常用消息)回退。 - -您可以使用 `i18n` 的 `sharedMessages` 选项。 - -通用语言环境消息示例: - -```js -export default { - en: { - buttons: { - save: "Save", - // ... - } - }, - ja: { - buttons: { - save: "保存", - // ... - } - } -} -``` - -Components: -```js -import commonMessage from './locales/common' // 导入通用语言环境消息 - -export default { - name: 'ServiceModal', - template: ` - - `, - i18n: { - messages: { ... }, - sharedMessages: commonMessages - } -} -``` - -如果将 `sharedMessages` 选项与 `messages` 选项一起指定,则这些消息将被合并为语言环境消息,并进入目标组件的VueI18n实例。 - -## 函数式组件的翻译 - -使用函数式组件时,所有数据 (包括 prop、子内容、插槽、父级内容等) 都通过包含属性的 `context` 传递,并且它无法识别 `this` 的范围,因此在函数式组件上使用 vue-i18n 时,你必须将 `$t` 称为 `parent.$t`,请查看以下示例: - -```html -... - -... -``` diff --git a/docs-old/zh/guide/datetime.md b/docs-old/zh/guide/datetime.md deleted file mode 100644 index 7f51a1c9d..000000000 --- a/docs-old/zh/guide/datetime.md +++ /dev/null @@ -1,77 +0,0 @@ -# 日期时间本地化 - -:::tip 支持版本 -:new: 7.0+ 新增 -::: - -你可以使用你定义的格式来本地化日期时间。 - -日期时间格式如下: - -```js -const dateTimeFormats = { - 'en-US': { - short: { - year: 'numeric', - month: 'short', - day: 'numeric' - }, - long: { - year: 'numeric', - month: 'long', - day: 'numeric', - weekday: 'long', - hour: 'numeric', - minute: 'numeric' - } - }, - 'ja-JP': { - short: { - year: 'numeric', - month: 'short', - day: 'numeric' - }, - long: { - year: 'numeric', - month: 'long', - day: 'numeric', - weekday: 'long', - hour: 'numeric', - minute: 'numeric', - hour12: true - } - } -} -``` - -如上,你可以定义具名的 (例如:`short`、`long` 等) 日期时间格式,并需要使用 [ECMA-402 Intl.DateTimeFormat 的选项](http://www.ecma-international.org/ecma-402/2.0/#sec-intl-datetimeformat-constructor)。 - -之后就像语言环境信息一样,你需要指定 `VueI18n` 构造函数的 `dateTimeFormats` 选项: - -```js -const i18n = new VueI18n({ - dateTimeFormats -}) - -new Vue({ - i18n -}).$mount('#app') -``` - -模板如下: - -```html -
-

{{ $d(new Date(), 'short') }}

-

{{ $d(new Date(), 'long', 'ja-JP') }}

-
-``` - -输出如下: - -```html -
-

Jan 18, 2021

-

2021年1月18日日曜日 午前5:47

-
-``` diff --git a/docs-old/zh/guide/directive.md b/docs-old/zh/guide/directive.md deleted file mode 100644 index 9556c5d86..000000000 --- a/docs-old/zh/guide/directive.md +++ /dev/null @@ -1,181 +0,0 @@ -# 自定义指令本地化 - -:::tip 支持的版本 -:new: 7.3+ 新增 -::: - -你不仅可以使用 `$t` 方法进行翻译,还可以使用 `v-t` 自定义指令。 - -## 字符串语法 - -你可以使用字符串语法传递语言环境信息的键名路径。 - -JavaScript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { hello: 'hi there!' }, - ja: { hello: 'こんにちは!' } - } - }), - data: { path: 'hello' } -}).$mount('#string-syntax') -``` - -模板: - -```html -
- -

- -

-
-``` - -输出: - -```html -
-

hi there!

-

hi there!

-
-``` - -## 对象语法 - -你可以使用对象语法。 - -Javascript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { hello: 'hi {name}!' }, - ja: { hello: 'こんにちは、{name}!' } - } - }), - computed: { - nickName () { return 'kazupon' } - }, - data: { path: 'hello' } -}).$mount('#object-syntax') -``` - -模板: - -```html -
- -

- -

-
-``` - -输出: - -```html -
-

こんにちは、kazupon!

-

hi kazupon!

-
-``` - -## 使用翻译 - -:::tip 支持版本 -:new: 8.7+ 新增 -::: - -当 `v-t` 指令应用于 [`` 组件](https://cn.vuejs.org/v2/api/#transition)内的元素时,你可能会注意到过渡动画之后的翻译过的信息会消失。这与 `` 组件实现的方式有关——**在过渡开始之前** ,`` 组件内消失元素中的所有指令都将被销毁。此行为可能导致内容在短过渡时闪烁,但在长过渡时最明显。 - -为了确保在转换期间指令内容不会被触及,只需将[`.preserve` 修饰符](../api/#v-t)添加到 `v-t` 指令定义中。 - -Javascript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { preserve: 'with preserve' }, - } - }), - data: { toggle: true } -}).$mount('#in-transitions') -``` - -模板: - -```html -
- - - - -
-``` - -也可以在 `VueI18n` 实例本身设置全局设置,这将对没有修饰符的所有 `v-t` 指令产生影响。 - -Javascript: - -```js -new Vue({ - i18n: new VueI18n({ - locale: 'en', - messages: { - en: { preserve: 'with preserve' }, - }, - preserveDirectiveContent: true - }), - data: { toggle: true } -}).$mount('#in-transitions') -``` - -模板: - -```html -
- - - - -
-``` - -关于上面的例子,请参阅[示例](https://github.com/kazupon/vue-i18n/tree/dev/examples/directive) - -## `$t` vs `v-t` - -### `$t` - -`$t` 是扩展的 Vue 实例方法, 它有以下优点和缺点: - -#### 优点 - -你可以**灵活地**在模板以及 Vue 实例的计算属性和方法中使用 mustash 语法 `{{}}`。 - -#### 缺点 - -`$t` 在**每次**重新渲染时都会被执行,因此它确实有翻译成本。 - -### `v-t` - -`v-t` 是一个自定义指令,它有以下优点和缺点: - -#### 优点 - -`v-t` 比 `$t` 方法具有**更好的**性能,因为在一次翻译时自定义指令会进行缓存。此外可以使用由 [`vue-i18n-extensions`](https://github.com/kazupon/vue-i18n-extensions) 提供的 Vue 编译器模块进行预翻译。 - -因此,可以进行**更多性能优化**。 - -#### 缺点 - -`v-t` 不能像 `$t` 一样灵活使用,它更**复杂**。带有 `v-t` 的翻译内容会被插入到元素的 `textContent` 中。此外,当你使用服务器渲染时,你需要设置[自定义指令](https://github.com/kazupon/vue-i18n-extensions#directive-v-t-custom-directive-for-server-side)到 `createRenderer` 函数的 `directives` 选项。 diff --git a/docs-old/zh/guide/fallback.md b/docs-old/zh/guide/fallback.md deleted file mode 100644 index 06305a68f..000000000 --- a/docs-old/zh/guide/fallback.md +++ /dev/null @@ -1,111 +0,0 @@ -# 回退本地化 - -*总结:使用`fallbackLocale:''`选择首选语言缺少翻译时要使用的语言。* - -## 使用语言环境的隐式回退 - -如果给出的 `locale` 包含领土和可选的方言,则隐式回退将自动激活。 - -例如,对于 `de-DE-bavarian`,以下内容将被视为备用: -1. `de-DE-Bavarian` -2. `de-DE` -3. `de` - -要禁止自动回退,请添加后缀感叹号 `!`,例如 `de-DE!`。 - -# 具有一个语言环境的显式回退 - -以下语言环境信息的 `ja` 语言环境中不存在 `message` 键: - -```js -const messages = { - en: { - message: 'hello world' - }, - ja: { - // 没有翻译的本地化 `hello` - } -} -``` - -当为 VueI18n 构造函数选项指定 `fallbackLocale` 选项时,`message` 键使用 `en` 语言环境进行本地化: - -```js -const i18n = new VueI18n({ - locale: 'ja', - fallbackLocale: 'en', - messages -}) -``` - -模板如下: - -```html -

{{ $t('message') }}

-``` - -输出如下: - -```html -

hello world

-``` - -注意,默认情况下回退到 `fallbackLocale` 会产生两个控制台警告: - -``` -[vue-i18n] Value of key 'message' is not a string! -[vue-i18n] Fall back to translate the keypath 'message' with 'en' locale. -``` - -为了避免这些警告 (同时保留那些完全没有翻译给定关键字的警告),需初始化 `VueI18n` 实例时设置 `silentFallbackWarn:true`。 - -## 回退插值 - -由于翻译的键值是字符串,因此也可以作为翻译的值: - -```javascript -const messages = { - ja: { - 'Hello world': 'こんにちは、世界' - } -} -``` - -这是一种很自然的书写方式,如果在`message`中找不到相应的键值将回退到原本的语言: - -*注意: `fallbackRoot`的优先级高于`formatFallbackMessages`* - -```html -

{{ $t('Hello world') }}

-``` - -为了实现此功能,可以通过设置`formatFallbackMessages`为`true`: - -```javascript -const messages = { - ru: { - 'Hello {name}': 'Здравствуйте {name}' - } -} - -const i18n = new VueI18n({ - locale: 'ru', - fallbackLocale: 'en', - formatFallbackMessages: true, - messages -}) -``` - -模板如下: - -```html -

{{ $t('Hello {name}', { name: 'John' }}) }}

-

{{ $t('The weather today is {condition}!', { condition: 'sunny' }) }}

-``` - -将会输出: - -```html -

Здравствуйте John

-

The weather today is sunny!

-``` diff --git a/docs-old/zh/guide/formatting.md b/docs-old/zh/guide/formatting.md deleted file mode 100644 index a3e3d1105..000000000 --- a/docs-old/zh/guide/formatting.md +++ /dev/null @@ -1,200 +0,0 @@ -# 格式化 - -## 具名格式 - -语言环境信息如下: - -```js -const messages = { - en: { - message: { - hello: '{msg} world' - } - } -} -``` - -模板如下: - -```html -

{{ $t('message.hello', { msg: 'hello' }) }}

-``` - -输出如下: - -```html -

hello world

-``` - -## 列表格式 - -语言环境信息如下: - -```js -const messages = { - en: { - message: { - hello: '{0} world' - } - } -} -``` - -模板如下: - -```html -

{{ $t('message.hello', ['hello']) }}

-``` - -输出如下: - -```html -

hello world

-``` - -列表格式也接受类似数组的对象: - - -```html -

{{ $t('message.hello', {'0': 'hello'}) }}

-``` - -输出如下: - -```html -

hello world

-``` - -## HTML 格式化 - -:::warning 提示 -:warning: 在你的网站上动态插入任意 HTML 可能非常危险,因为它很容易导致 XSS 攻击。仅对可信内容使用 HTML 插值,而不对用户提供的内容使用。 - -我们建议使用[组件插值](interpolation.md) 功能。 -::: - -在某些情况下,你可能希望将翻译呈现为 HTML 信息而不是静态字符串。 - - -```js -const messages = { - en: { - message: { - hello: 'hello
world' - } - } -} -``` - -模板如下: - - -```html -

-``` - -输出如下 (取代预先格式化的信息) - - -```html -

hello - -world

-``` - - -## 支持 ruby on rails 的 i18n 格式 - -语言环境信息如下: - -```js -const messages = { - en: { - message: { - hello: '%{msg} world' - } - } -} -``` - -模板如下: - -```html -

{{ $t('message.hello', { msg: 'hello' }) }}

-``` - -输出如下: - -```html -

hello world

-``` - -## 自定义格式 - -有时,你可能需要使用自定义格式进行翻译 (例如:[ICU 信息语法](http://userguide.icu-project.org/formatparse/messages))。 - -你可以使用实现[格式化接口](https://github.com/kazupon/vue-i18n/blob/dev/decls/i18n.js#L41-L43) 的自定义格式化函数来实现。 - -以下使用 ES2015 class 语法的自定义格式化函数: - -```js -// 实现自定义格式 -class CustomFormatter { - constructor (options) { - // ... - } - - // - // 插值 - // - // @param {string} 信息 - // 列表或具名格式的字符串。 - // 例如: - // - 具名格式:'Hi {name}' - // - 列表格式:'Hi {0}' - // - // @param {Object | Array} 值 - // `message` 插值的值 - // 使用 `$t`, `$tc` 和 `i18n` 函数式组件传递值。 - // e.g. - // - $t('hello', { name: 'kazupon' }) -> 传递值:Object `{ name: 'kazupon' }` - // - $t('hello', ['kazupon']) -> 传递值:Array `['kazupon']` - // - `i18n` 函数式组件 (组件插值) - // - //

kazupon

- //

how are you?

- //
- // -> 传递值:Array (included VNode): - // `[VNode{ tag: 'p', text: 'kazupon', ...}, VNode{ tag: 'p', text: 'how are you?', ...}]` - // - // @return {Array} - // 插值,你需要返回以下内容: - // - 当使用 `$t` 或 `$tc` 数组中应该是字符串。 - // - 当使用 `i18n` 函数式组件时 数组中应包含 VNode 对象。 - // - interpolate (message, values) { - // 在这里实现插值逻辑 - // ... - - // 返回插值数组 - return ['resolved message string'] - } -} - -// 注册 `formatter` 选项 -const i18n = new VueI18n({ - locale: 'en-US', - formatter: new CustomFormatter(/* 这里是构造函数选项 */), - messages: { - 'en-US': { - // ... - }, - // ... - } -}) - -// 启动! -new Vue({ i18n }).$mount('#app') -``` - -你可以查看[自定义格式化函数的官方示例](https://github.com/kazupon/vue-i18n/tree/dev/examples/formatting/custom)。 diff --git a/docs-old/zh/guide/hot-reload.md b/docs-old/zh/guide/hot-reload.md deleted file mode 100644 index 55c55f4a1..000000000 --- a/docs-old/zh/guide/hot-reload.md +++ /dev/null @@ -1,102 +0,0 @@ -# 热重载 - -您可以使用Webpack的 [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/) (HMR) 功能来监视本地化文件中的更改以及将热更改重新加载到您的应用程序中。 - -你可以监视本地化文件中的更改,并将更改热重载到应用程序中。 - -## 基本例子 - -如果仅使用静态语言环境集,则可以显式热加载这些语言环境: - -```js -import Vue from "vue" -import VueI18n from "vue-i18n" -import en from './en' -import ja from './ja' - -// 语言环境信息 -const messages = { - en, - ja -} - -// VueI18n 实例 -const i18n = new VueI18n({ - locale: 'en', - messages -}) - -// 运行程序 -const app = new Vue({ - i18n, - // ... -}).$mount('#app') - -// 热更新 -if (module.hot) { - module.hot.accept(['./en', './ja'], function () { - i18n.setLocaleMessage('en', require('./en').default) - i18n.setLocaleMessage('ja', require('./ja').default) - // 同样可以通过 $i18n 属性进行热更新 - // app.$i18n.setLocaleMessage('en', require('./en').default) - // app.$i18n.setLocaleMessage('ja', require('./ja').default) - }) -} -``` - -## 进阶范例 - -如果您想支持一组不断变化的语言环境,则可以使用 `require.context` 动态地重新加载这些语言环境: - -```js -import Vue from "vue"; -import VueI18n from "vue-i18n"; - -Vue.use(VueI18n); - -// 加载所有语言环境并记住上下文 -function loadMessages() { - const context = require.context("./locales", true, /[a-z0-9-_]+\.json$/i); - - const messages = context - .keys() - .map((key) => ({ key, locale: key.match(/[a-z0-9-_]+/i)[0] })) - .reduce( - (messages, { key, locale }) => ({ - ...messages, - [locale]: context(key), - }), - {} - ); - - return { context, messages }; -} - -const { context, messages } = loadMessages(); - -// VueI18n 实例 -const i18n = new VueI18n({ - locale: "en", - messages, -}); - -// 运行程序 -const app = new Vue({ - i18n, - // ... -}).$mount('#app'); - -// 热更新 -if (module.hot) { - module.hot.accept(context.id, () => { - const { messages: newMessages } = loadMessages(); - - Object.keys(newMessages) - .filter((locale) => messages[locale] !== newMessages[locale]) - .forEach((locale) => { - messages[locale] = newMessages[locale]; - i18n.setLocaleMessage(locale, messages[locale]); - }); - }); -} -``` diff --git a/docs-old/zh/guide/interpolation.md b/docs-old/zh/guide/interpolation.md deleted file mode 100644 index 24aa82d6f..000000000 --- a/docs-old/zh/guide/interpolation.md +++ /dev/null @@ -1,183 +0,0 @@ -# 组件插值 - -## 基本用法 - -:::tip 支持版本 -:new: 7.0+ 新增 -::: - -有时,我们需要使用包含 HTML 标签或组件的语言环境信息进行本地化。例如: - -```html -

I accept xxx Terms of Service Agreement

-``` - -在上面的信息中,如果你使用 `$t`,可能你会尝试编写以下语言环境信息: - -```js -const messages = { - en: { - term1: 'I Accept xxx\'s', - term2: 'Terms of Service Agreement' - } -} -``` - -你可能会尝试在以下模板中实现: - -```html -

{{ $t('term1') }}{{ $t('term2') }}

-``` - -输出: - -```html -

I accept xxx Terms of Service Agreement

-``` - -这是非常麻烦的,如果在语言环境信息中配置 `` 标签,则可能由于使用了 `v-html="$t('term')"` 进行本地化而存在被 XSS 攻击的可能性。 - -你可以使用 `i18n` 函数式组件来避免它。例如: - -```html - -``` -```js -const messages = { - en: { - tos: 'Term of Service', - term: 'I accept xxx {0}.' - }, - ja: { - tos: '利用規約', - term: '私は xxx の{0}に同意します。' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) -new Vue({ - i18n, - data: { - url: '/term' - } -}).$mount('#app') -``` - -输出如下: - -```html -
- - - -
-``` - -关于上面的例子,见[示例](https://github.com/kazupon/vue-i18n/tree/dev/examples/interpolation) - -`i18n` 函数式组件的子元素用 `path` 属性的语言环境信息进行插值。 - -在上面的例子中: -:::v-pre -`{{ $t('tos') }}` -::: -被插入了语言环境信息 `term`。 - -在上面的示例中,组件插值遵循**列表格式**。`i18n` 函数式组件的子项按其出现顺序进行插值。 - -## 高级用法 - -:::tip 支持版本 -:new: 7.2+ 新增 -::: -:::warning 提示 -:warning: 在 `i18n` 组件中,仅包含空格的文本内容将被省略。 -::: - -在 `place` 特性的帮助下支持具名格式。例如: - -```html -
- - - {{ changeLimit }} - {{ $t('change') }} - - -
-``` -```js -const messages = { - en: { - info: 'You can {action} until {limit} minutes from departure.', - change: 'change your flight', - refund: 'refund the ticket' - } -} - -const i18n = new VueI18n({ - locale: 'en', - messages -}) -new Vue({ - i18n, - data: { - changeUrl: '/change', - refundUrl: '/refund', - changeLimit: 15, - refundLimit: 30 - } -}).$mount('#app') -``` - -输出: - -```html -
- -

- You can change your flight until 15 minutes from departure. -

- -
-``` - -:::warning 提示 -:warning: `i18n` 组件的所有子项都必须设置 `place` 属性。否则它将回退到列表格式。 -::: - - -如果你仍想在命名格式中插入文本内容,可以在 `i18n` 组件上定义 `places` 属性。例如: - -```html -
- - - {{ $t('refund') }} - - -
-``` - -输出: - -```html -
- -

- You can refund your ticket until 30 minutes from departure. -

- -
-``` diff --git a/docs-old/zh/guide/lazy-loading.md b/docs-old/zh/guide/lazy-loading.md deleted file mode 100644 index 85c994d75..000000000 --- a/docs-old/zh/guide/lazy-loading.md +++ /dev/null @@ -1,85 +0,0 @@ -# 延迟加载翻译 - -一次加载所有翻译文件是过度和不必要的。 - -使用 Webpack 时,延迟加载或异步加载转换文件非常简单。 - -让我们假设我们有一个类似于下面的项目目录 - -``` -our-cool-project --dist --src ---routes ---store ---setup ----i18n-setup.js ---lang ----en.js ----it.js -``` - -`lang` 文件夹是我们所有翻译文件所在的位置。`setup` 文件夹是我们的任意设置的文件,如 i18n-setup,全局组件 inits,插件 inits 和其他位置。 - -```js -//i18n-setup.js -import Vue from 'vue' -import VueI18n from 'vue-i18n' -import messages from '@/lang/en' -import axios from 'axios' - -Vue.use(VueI18n) - -export const i18n = new VueI18n({ - locale: 'en', // 设置语言环境 - fallbackLocale: 'en', - messages // 设置语言环境信息 -}) - -const loadedLanguages = ['en'] // 我们的预装默认语言 - -function setI18nLanguage (lang) { - i18n.locale = lang - axios.defaults.headers.common['Accept-Language'] = lang - document.querySelector('html').setAttribute('lang', lang) - return lang -} - -export function loadLanguageAsync(lang) { - // 如果语言相同 - if (i18n.locale === lang) { - return Promise.resolve(setI18nLanguage(lang)) - } - - // 如果语言已经加载 - if (loadedLanguages.includes(lang)) { - return Promise.resolve(setI18nLanguage(lang)) - } - - // 如果尚未加载语言 - return import(/* webpackChunkName: "lang-[request]" */ `@/i18n/messages/${lang}.js`).then( - messages => { - i18n.setLocaleMessage(lang, messages.default) - loadedLanguages.push(lang) - return setI18nLanguage(lang) - } - ) -} -``` - -简而言之,我们正在创建一个新的 VueI18n 实例。然后我们创建一个 `loadedLanguages` 数组,它将跟踪我们加载的语言。接下来是 `setI18nLanguage` 函数,它将实际更改 vueI18n 实例、axios 以及其它需要本地化的地方。 - -`loadLanguageAsync` 是实际用于更改语言的函数。加载新文件是通过import功能完成的,`import` 功能由 Webpack 慷慨提供,它允许我们动态加载文件,并且因为它使用 promise,我们可以轻松地等待加载完成。 - -你可以在 [Webpack 文档](https://webpack.js.org/guides/code-splitting/#dynamic-imports) 中了解有关导入功能的更多信息。 - -使用 `loadLanguageAsync` 函数很简单。一个常见的用例是在 vue-router beforeEach 钩子里面。 - -```js -router.beforeEach((to, from, next) => { - const lang = to.params.lang - loadLanguageAsync(lang).then(() => next()) -}) -``` - -我们可以通过检查 `lang` 实际上是否支持来改进这一点,调用 `reject` 这样我们就可以在 beforeEach 捕获路由转换。 diff --git a/docs-old/zh/guide/locale.md b/docs-old/zh/guide/locale.md deleted file mode 100644 index 72b0233f6..000000000 --- a/docs-old/zh/guide/locale.md +++ /dev/null @@ -1,55 +0,0 @@ -# 语言环境变更 - -通常,使用 Vue 根实例作为起点,使用 `VueI18n` 类的 `locale` 属性作为参考来本地化所有子组件。 - -有时你可能希望动态更改语言环境。在这种情况下,你可以更改 `VueI18n` 实例的 `locale` 属性的值。 - -```js -const i18n = new VueI18n({ - locale: 'ja', // 设置语言环境 - ... -}) - -// 创建 Vue 根实例 -new Vue({ - i18n, - ... -}).$mount('#app') - -// 更改为其它的 locale -i18n.locale = 'en' -``` - -每个组件都包含一个引用为 `$i18n` 属性的 `VueI18n` 实例,该实例也可用于更改语言环境。 - -示例: - -```vue - - - -``` - -:::warning 警告 -:warning: 对于使用了 `sync: false` 的组件,语言环境的更改将被忽略。 -::: - -:::warning 组件与根范围 -:warning: 在组件内更改 `$i18n.locale` 不会更新根语言环境。 -如果您依靠根语言环境,例如在使用 [root fallbacks](./fallback.html) 时,请使用 `$root.$i18n.locale` 而不是$ `i18n.locale`。 -::: diff --git a/docs-old/zh/guide/messages.md b/docs-old/zh/guide/messages.md deleted file mode 100644 index 25067c21c..000000000 --- a/docs-old/zh/guide/messages.md +++ /dev/null @@ -1,290 +0,0 @@ -# 语言环境信息的语法 - -## 结构 - -语言环境信息的语法如下: - -```typescript -// 作为 Flowtype 定义,语言环境信息的语法类似于 BNF 注释 -type LocaleMessages = { [key: Locale]: LocaleMessageObject }; -type LocaleMessageObject = { [key: Path]: LocaleMessage }; -type LocaleMessageArray = LocaleMessage[]; -type MessageContext = { - list: (index: number) => mixed, - named: (key: string) => mixed -}; -type MessageFunction = (ctx: MessageContext) => string; -type LocaleMessage = string | MessageFunction | LocaleMessageObject | LocaleMessageArray; -type Locale = string; -type Path = string; -``` - -基于以上语法,你可以配置以下结构的 Locale 信息: - -```json -{ - "en": { // 'en' Locale - "key1": "this is message1", // 基本的 - "nested": { // 嵌套 - "message1": "this is nested message1" - }, - "errors": [ // 数组 - "this is 0 error code message", - { // 数组嵌套对象 - "internal1": "this is internal 1 error message" - }, - [ // 数组嵌套数组 - "this is nested array error 1" - ] - ] - }, - "ja": { // 'ja' Locale - // ... - } -} -``` - -在上面的语言环境信息的结构中,你可以使用以下键名路径进行翻译。 - -```html -
- -

{{ $t('key1') }}

- -

{{ $t('nested.message1') }}

- -

{{ $t('errors[0]') }}

- -

{{ $t('errors[1].internal1') }}

- -

{{ $t('errors[2][0]') }}

-
-``` - -输出以下内容: - -```html -
- -

this is message1

- -

this is nested message1

- -

this is 0 error code message

- -

this is internal 1 error message

- -

this is nested array error 1

-
-``` - -## Linked locale messages - -如果有一个翻译关键字总是与另一个具有相同的具体文本,你可以链接到它。要链接到另一个翻译关键字,你所要做的就是在其内容前加上一个 `@:` 符号后跟完整的翻译键名,包括你要链接到的命名空间。 - -语言环境信息如下: - -```js -const messages = { - en: { - message: { - the_world: 'the world', - dio: 'DIO:', - linked: '@:message.dio @:message.the_world !!!!' - } - } -} -``` - -模板如下: - -```html -

{{ $t('message.linked') }}

-``` - -输出如下: - -```html -

DIO: the world !!!!

-``` -### 格式化链接的语言环境消息 - -如果语言区分字符大小写,则可能需要控制链接的语言环境消息的大小写。 -链接的消息可以用修饰符 `@.modifier:key` 格式化。 - -以下修饰符当前可用。 - -* `upper`: 链接消息中的所有字符均大写 -* `lower`: 小写链接消息中的所有字符 -* `capitalize`: 大写链接消息中的第一个字符 - -语言环境消息如下: - -```javascript -const messages = { - en: { - message: { - homeAddress: 'Home address', - missingHomeAddress: 'Please provide @.lower:message.homeAddress' - } - } -} -``` - -```html - - -

{{ $t('message.missingHomeAddress') }}

-``` - -输出以下内容: - -```html - - -

Please provide home address

-``` - -您可以添加修饰符或覆盖将 `modifiers` 选项传递给 `VueI18n` 构造函数的现有修饰符。 - -```javascript -const i18n = new VueI18n({ - locale: 'en', - modifiers: { - snakeCase: (str) => str.split(' ').join('-') - }, - messages: { - // ... - }, -}) -``` - -### 按括号分组 - -链接到的语言环境信息的键名也可以形如 `@:(message.foo.bar.baz)`,其中链接到另一段翻译的键名在括号 `()` 里。 - -如果链接 `@:message.something` 后紧跟着一个点 `.`,则此选项非常有用,因为它本不该成为但却成为了链接的一部分。 - -语言环境信息如下: - -```js -const messages = { - en: { - message: { - dio: 'DIO', - linked: 'There\'s a reason, you lost, @:(message.dio).' - } - } -} -``` - -模板如下: - -```html -

{{ $t('message.linked') }}

-``` - -输出如下: - -```html -

There's a reason, you lost, DIO.

-``` - -## 留言功能 - -vue-i18n 建议在翻译消息时使用基于列表的字符串或命名格式作为语言环境消息。 - -但是,在某些情况下,由于复杂的语言语法,您确实需要JavaScript的全部编程功能。 因此,您可以使用 **message function** 来代替基于字符串的消息。 - -以下是一个返回简单问候语的消息函数: - -```js -const messages = { - en: { - greeting: (ctx) => 'hello!' - } -} -``` - -使用消息功能非常容易! 您只需使用 `$t` 或 `t` 指定消息功能的键: - -```html -

{{ $t('greeting') }}

-``` - -输出如下: - -```html -

hello!

-``` - -消息功能输出消息,该消息具有消息功能的返回值。 - -### 命名格式 - -vue-i18n 支持[命名格式](./formatting.md#named-formatting) 作为基于字符串的消息格式。 vue-i18n用$ t或t插值参数值,并可以将其输出。 - -使用 **消息上下文** 的消息功能可以完成以下操作: - -这是问候的示例: - -```js -const messages = { - en: { - greeting: (ctx) => `hello, ${ctx.named('name')}!` - } -} -``` - -模板: - -```html -

{{ $t('greeting', { name: 'DIO' }) }}

-``` - -输出如下: - -```html -

hello, DIO!

-``` - -消息上下文具有命名函数。 您需要指定键来解析以 `$t` 或 `t` 命名的值。 - -### 清单格式 - -列表格式的使用类似于上述命名格式。 - -vue-i18n 支持 [列表格式](./formatting.md#list-formatting) 作为基于字符串的消息格式。 vue-i18n用$ t或t插值参数值,并可以将其输出。 - -您可以通过使用消息上下文对消息函数执行相同的操作: - -这是问候的示例: - -```js -const messages = { - en: { - greeting: (ctx) => `hello, ${ctx.list(0)}!` - } -} -``` - -模板: - -```html -

{{ $t('greeting', ['DIO']) }}

-``` - -输出如下: - -```html -

hello, DIO!

-``` - -消息上下文具有列表功能。 您需要指定索引来解析由 `$t` 或 `t` 列表指定的值。 - -### 局限性 - -在消息功能中,以下基于字符串提供的功能无法通过消息上下文使用: - -- 链接的区域设置消息 -- 复数 diff --git a/docs-old/zh/guide/number.md b/docs-old/zh/guide/number.md deleted file mode 100644 index 8efbd0052..000000000 --- a/docs-old/zh/guide/number.md +++ /dev/null @@ -1,133 +0,0 @@ -# 数字本地化 - -:::tip 支持版本 -:new: 7.0+ 新增 -::: - -你可以使用你定义的格式来本地化数字。 - -数字格式如下: - -```js -const numberFormats = { - 'en-US': { - currency: { - style: 'currency', - currency: 'USD' - } - }, - 'ja-JP': { - currency: { - style: 'currency', - currency: 'JPY', - currencyDisplay: 'symbol' - } - } -} -``` - -如上,你可以指定具名的 (例如:`currency` 等) 的数字格式,并且需要使用 [ECMA-402 Intl.NumberFormat 的选项](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat)。 - -之后就像语言环境信息一样,你需要指定 `VueI18n` 构造函数的 `numberFormats` 选项: - -```js -const i18n = new VueI18n({ - numberFormats -}) - -new Vue({ - i18n -}).$mount('#app') -``` - -模板如下: - -```html -
-

{{ $n(100, 'currency') }}

-

{{ $n(100, 'currency', 'ja-JP') }}

-
-``` - - -输出如下: - -```html -
-

$100.00

-

¥100

-
-``` - -## 自定义格式 - -:::tip 支持版本 -:new: 8.10+ 新增 -::: - -`$n` 方法返回的结果字符串带有完全格式化的数字,该数字只能作为整体使用。 在需要格式化格式化数字的某些部分(例如小数位)的情况下,`$n` 是不够的。 在这种情况下,`` 功能组件将有所帮助。 - -有了最少的一组属性,`` 产生的输出与 `$n` 相同,并包装到已配置的DOM元素中。 - -以下模板: - -```html -
- - - -
-``` - -将产生以下输出: - -```html -
- 100 - $100.00 - ¥100 -
-``` - -但是,当与[范围内的插槽](https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots) 一起使用时,该组件的真正功能就会发挥作用。 - -假设需要用较粗的字体呈现数字的整数部分。 这可以通过指定 `integer` 作用域的插槽元素来实现: - -```html - - {{ slotProps.integer }} - -``` - -上面的模板将产生以下 HTML: - -```html -$100.00 -``` - -可以同时指定多个作用域插槽: - -```html - - {{ slotProps.currency }} - {{ slotProps.integer }} - {{ slotProps.group }} - {{ slotProps.fraction }} - -``` - -(此结果 HTML 进行了格式化,以提高可读性) - -```html - - - 1 - , - 234 - 00 - -``` - -您可以通过指定 `tag` 属性来选择根容器的节点类型。 如果省略,则默认为 `'span'`。 您也可以将其设置为布尔值 `false` 以直接插入子节点,而无需创建根元素。 - -可以在 [API 页面](../api/readme.md#i18n-n-functional-component) 中找到受支持的作用域插槽以及其他 `` 属性的完整列表。 diff --git a/docs-old/zh/guide/pluralization.md b/docs-old/zh/guide/pluralization.md deleted file mode 100644 index 68b997a9a..000000000 --- a/docs-old/zh/guide/pluralization.md +++ /dev/null @@ -1,166 +0,0 @@ -# 复数 - -你可以使用复数进行翻译。你必须定义具有管道 `|` 分隔符的语言环境,并在管道分隔符中定义复数。 - -*您的模板将需要使用 `$tc()` 而不是 `$t()`。 - -语言环境信息如下: - -```js -const messages = { - en: { - car: 'car | cars', - apple: 'no apples | one apple | {count} apples' - } -} -``` - -模板如下: - -```html -

{{ $tc('car', 1) }}

-

{{ $tc('car', 2) }}

- -

{{ $tc('apple', 0) }}

-

{{ $tc('apple', 1) }}

-

{{ $tc('apple', 10, { count: 10 }) }}

-``` - -输出如下: - -```html -

car

-

cars

- -

no apples

-

one apple

-

10 apples

-``` - -## 通过预定义的参数访问该数字 - -你无需明确指定复数的数字。可以通过预定义的命名参数 `{count}` 和/或 `{n}` 在语言环境信息中访问该数字。如有必要,你可以覆盖这些预定义的命名参数。 - -语言环境信息如下: - -```js -const messages = { - en: { - apple: 'no apples | one apple | {count} apples', - banana: 'no bananas | {n} banana | {n} bananas' - } -} -``` - -模板如下: - -```html -

{{ $tc('apple', 10, { count: 10 }) }}

-

{{ $tc('apple', 10) }}

- -

{{ $tc('banana', 1, { n: 1 }) }}

-

{{ $tc('banana', 1) }}

-

{{ $tc('banana', 100, { n: 'too many' }) }}

-``` - -输出如下: - -```html -

10 apples

-

10 apples

- -

1 banana

-

1 banana

-

too many bananas

-``` - - -## 自定义复数 - -但是,这种多元化并不适用于所有语言(例如,斯拉夫语言具有不同的多元化规则)。 - -为了实现这些规则,您可以将可选的 `pluralizationRules` 对象传递给`VueI18n` 构造函数选项。 - -使用针对斯拉夫语言(俄语,乌克兰语等)的规则的非常简化的示例: -```js -new VueI18n({ - // Key - 在这种情况下,用于规则 `'ru'` 的语言 - // Value - 选择正确的复数形式的功能 - pluralizationRules: { - /** - * @param choice {number} 输入给$的选择索引 $tc:`$tc('path.to.rule', choiceIndex)` - * @param choicesLength {number} 可用选择总数 - * @returns 最终选择索引以选择复数单词 - */ - 'ru': function(choice, choicesLength) { - // this === VueI18n 实例,因此本地属性也存在于此 - - if (choice === 0) { - return 0; - } - - const teen = choice > 10 && choice < 20; - const endsWithOne = choice % 10 === 1; - - if (choicesLength < 4) { - return (!teen && endsWithOne) ? 1 : 2; - } - if (!teen && endsWithOne) { - return 1; - } - if (!teen && choice % 10 >= 2 && choice % 10 <= 4) { - return 2; - } - - return (choicesLength < 4) ? 2 : 3; - } - } -}) -``` - -这将有效地实现以下目的: - -```javascript -const messages = { - ru: { - car: '0 машин | {n} машина | {n} машины | {n} машин', - banana: 'нет бананов | {n} банан | {n} банана | {n} бананов' - } -} -``` -格式在哪里 `0 东西 | 事情以结尾结束 1 | 事情以结尾结束 2-4 | 事情以结尾结束 5-9, 0 和青少年 (10-19)`. -附言 斯拉夫多元化是困难的,您可以阅读有关它的更多信息 [这里](http://www.russianlessons.net/lessons/lesson11_main.php). - -你的模板仍然需要使用 `$tc()`,而不是 `$t()` : - -```html -

{{ $tc('car', 1) }}

-

{{ $tc('car', 2) }}

-

{{ $tc('car', 4) }}

-

{{ $tc('car', 12) }}

-

{{ $tc('car', 21) }}

- -

{{ $tc('banana', 0) }}

-

{{ $tc('banana', 4) }}

-

{{ $tc('banana', 11) }}

-

{{ $tc('banana', 31) }}

-``` - -结果如下: - -```html -

1 машина

-

2 машины

-

4 машины

-

12 машин

-

21 машина

- -

нет бананов

-

4 банана

-

11 бананов

-

31 банан

-``` - -### 默认多元 - -如果在多元化地图中找不到您当前的语言环境,则将使用英语的 [默认](#复数) 规则。 diff --git a/docs-old/zh/guide/sfc.md b/docs-old/zh/guide/sfc.md deleted file mode 100644 index d796bb94a..000000000 --- a/docs-old/zh/guide/sfc.md +++ /dev/null @@ -1,397 +0,0 @@ -# 单文件组件 - -## 基本用法 - -如果使用单文件组件构建 Vue 组件或 Vue 应用程序,则可以管理 `i18n` 自定义块的语言环境信息。 - -以下是[单文件组件示例](https://github.com/kazupon/vue-i18n/tree/dev/examples/sfc): - -```vue - -{ - "en": { - "hello": "hello world!" - }, - "ja": { - "hello": "こんにちは、世界!" - } -} - - - - - -``` - -## 安装 vue-i18n-loader - -为了使用 `` 自定义块,你需要安装 `vue-loader` 和 `vue-i18n-loader`。如果你使用了单文件组件,[vue-loader](https://github.com/vuejs/vue-loader) 很可能已在项目中使用了,那么 [vue-i18n-loader](https://github.com/kazupon/vue-i18n-loader) 必须另外安装: - -```sh -npm i --save-dev @kazupon/vue-i18n-loader -``` - -## Webpack - -需要对 Webpack 进行以下配置: - -对于 vue-loader v15 或更高版本: -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - }, - { - resourceQuery: /blockType=i18n/, - type: 'javascript/auto', - loader: '@kazupon/vue-i18n-loader' - } - // ... - ] - }, - // ... -} -``` - -对于 vue-loader v14: -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - loaders: { - // 你需要指定 `i18n` 的值为 `vue-i18n-loader` - i18n: '@kazupon/vue-i18n-loader' - } - } - }, - // ... - ] - }, - // ... -} -``` - -## Vue CLI 3.0 - -[Vue CLI 3.0](https://github.com/vuejs/vue-cli) 隐藏了 webpack 配置,因此,如果我们想在单文件组件中添加对 `` 标记的支持,我们需要修改现有配置。 - -为此,我们必须在项目的根目录下创建一个 `vue.config.js`。完成后,我们必须包括以下内容: - -对于 vue-loader v15 或更高版本: -```js -module.exports = { - chainWebpack: config => { - config.module - .rule("i18n") - .resourceQuery(/blockType=i18n/) - .type('javascript/auto') - .use("i18n") - .loader("@kazupon/vue-i18n-loader") - .end(); - } -} -``` - -对于 vue-loader v14: -```js -const merge = require('deepmerge') - -module.exports = { - chainWebpack: config => { - config.module - .rule('vue') - .use('vue-loader') - .tap(options => - merge(options, { - loaders: { - i18n: '@kazupon/vue-i18n-loader' - } - }) - ) - } -} -``` -_别忘了安装[deepmerge](https://github.com/KyleAMathews/deepmerge)! (`npm i deepmerge -D` 或 `yarn add deepmerge -D`)_ - -如果你想了解有关修改现有配置的更多信息[点击这里](https://cli.vuejs.org/guide/webpack.html)。 - -## Laravel-Mix - -对于带有 vue-loader v15 或更高版本的 Laravel-mix 4: -```js -// 使用 “i18n” 方法扩展 Mix ,加载 vue-i18n-loader -mix.extend( 'i18n', new class { - webpackRules() { - return [ - { - resourceQuery: /blockType=i18n/, - type: 'javascript/auto', - loader: '@kazupon/vue-i18n-loader', - }, - ]; - } - }(), -); - -// 确保在 `.js(..., ...)` 之前调用 `.i18n()` (来加载加载器) -mix.i18n() - .js( 'resources/js/App.js', 'public/js/app.js' ) - ... -``` - -对于带有 vue-loader v14 的 Laravel-mix 2: - -从 Laravel-mix 的 [V2.1](https://github.com/JeffreyWay/laravel-mix/releases/tag/v2.1) 开始,你可以通过 `mix.extend()` 添加自定义规则。Laravel mix 已经有了处理 .vue 文件的规则。要添加 `vue-i18n-loader`,请将以下内容添加到 `webpack.mix.js`: - -```js -// 下面的代码将注入 i18n Kazupon/vue-18-loader 作为 .vue 文件的加载器。 -mix.extend( 'i18n', function( webpackConfig, ...args ) { - webpackConfig.module.rules.forEach( ( module ) => { - // 搜索处理 .vue 文件的 “vue-loader” 组件。 - if( module.loader !== 'vue-loader' ) { - return; - } - - // 在此模块中,为 i18n 标记添加 vue-i18n-loader。 - module.options.loaders.i18n = '@kazupon/vue-i18n-loader'; - } ); -} ); - -// 确保在 `.js(...,...)` 之前调用 `.i18n()` -mix.i18n() - .js( 'resources/assets/js/App.js', 'public/js/app.js' ) - ... -``` - -## 加载 YAML - -`i18n` 自定义块需要指定为 JSON 格式,你也可以通过使用 `vue-loader` 预加载器功能来使用 `YAML` 格式。 - -以下是 `YAML` 格式的 `i18n` 自定义块: - -```vue - -en: - hello: "hello world!" -ja: - hello: "こんにちは、世界!" - -``` - - -Webpack 配置如下: - -对于 vue-loader v15 或更高版本: -```js -// Vue CLI 3.0 -module.exports = { - chainWebpack: config => { - config.module - .rule("i18n") - .resourceQuery(/blockType=i18n/) - .type('javascript/auto') - .use("i18n") - .loader("@kazupon/vue-i18n-loader") - .end() - .use('yaml') - .loader('yaml-loader') - .end() - } -} -``` - -对于 vue-loader v14: -```js -module.exports = { - // ... - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - preLoaders: { - i18n: 'yaml-loader' - }, - loaders: { - i18n: '@kazupon/vue-i18n-loader' - } - } - }, - // ... - ] - }, - // ... -} -``` - -## 多个自定义块 - -你可以使用具有多个 `i18n` 自定义块的语言环境信息。 - -```vue - - - { - "en": { - "hello": "hello world!" - }, - "ja": { - "hello": "こんにちは、世界!" - } - } - -``` - -如上所见,第一个自定义块使用 `src` 特性加载常用的语言环境信息,第二个自定义块加载仅在该单文件组件中定义的语言环境信息。这些语言环境信息将合并为组件的语言环境信息。 - -这样,多个自定义块在想要用作模块时非常有用。 - -## Scoped 风格 - -当使用带有 `scoped style` `vue-i18n` 时,重要的是要记住使用[深度选择器](https://vue-loader.vuejs.org/zh/guide/scoped-css.html#深度作用选择器) 来设置嵌套转换的样式。例如: - -__翻译仅包含文本__(不使用深层选择器) - -```vue - -{ - "en": { - "hello": "hello world!" - }, - "ja": { - "hello": "こんにちは、世界" - } -} - - - - - - -``` - -__使用 HTML 元素翻译__(必须使用深度选择器) - -```vue - -{ - "en": { - "hello": "helloworld!" - }, - "ja": { - "hello": "こんにちは、世界!" - } -} - - - - - - - - - - - - - - - -``` - -## 函数式组件中的自定义块 - -如果单个文件组件具有使用函数式组件的模板,并且你已经定义了 `i18n` 自定义块,请注意你无法使用语言环境信息进行本地化。 - -例如,以下代码无法使用 `i18n` 自定义块的语言环境信息进行本地化。 - -```vue - -{ - "en": { - "hello": "hello world" - }, - "ja": { - "hello": "こんにちは、世界" - } -} - - - -``` diff --git a/docs-old/zh/guide/tooling.md b/docs-old/zh/guide/tooling.md deleted file mode 100644 index 36eded149..000000000 --- a/docs-old/zh/guide/tooling.md +++ /dev/null @@ -1,67 +0,0 @@ -# 工具 - -为了支持开发,我们官方提供了一些工具。 - -此外,还有第三方供应商提供的集成了 Vue I18n 的工具。 - -## 官方工具 - -### Vue Cli 插件 - -[vue-cli-plugin-i18n](https://github.com/kazupon/vue-cli-plugin-i18n) 是官方提供的 Vue Cli 插件。 - -使用此插件,您可以为Vue应用程序设置 i18n 环境,并支持 i18n 开发环境。 - -### Webpack Loader - -[vue-i18n-loader](https://github.com/kazupon/vue-i18n-loader) 是官方提供的 Webpack Loader。 -使用此加载程序,您可以在单个文件组件中使用 `i18n` 自定义块。 - -关于 `i18n` 自定义块,请参见 [单文件组件](./sfc.md) - -### ESLint 插件 - -[eslint-plugin-vue-i18n](https://intlify.github.io/eslint-plugin-vue-i18n/) 是为 Vue I18n 编写的 ESLint 插件。 - -它可以轻松地将一些本地化 lint 功能集成到 Vue.js 应用程序中。 - -### Extensions - -在[vue-i18n-extensions](https://github.com/kazupon/vue-i18n-extensions) 你可以找到为 Vue I18n 编写的插件。 - -您可以使用此扩展来启用 SSR 并提高 Vue I18n 的性能。 - -## 第三方工具 - -### BabelEdit - -[BabelEdit](https://www.codeandweb.com/babeledit) 是 Web 应用程序的翻译编辑器。 - -BabelEdit可以翻译 `json` 文件,也可以翻译单文件组件的 `i18n` 自定义块。 - -欲了解更多,请看[教程](https://www.codeandweb.com/babeledit/tutorials/how-to-translate-your-vue-app-with-vue-i18n) - -### i18n Ally - -[i18n Ally](https://marketplace.visualstudio.com/items?itemName=antfu.i18n-ally) 是 VSCode 的 i18n 扩展。 - -i18n Ally 为您的 i18n 开发提供了出色的 DX。 - -在[自述文件](https://github.com/antfu/i18n-ally/blob/master/README.md)中了解有关 i18n Ally 的更多信息。 - -### i18nPlugin (intellij 平台) - -[i18nPlugin](https://github.com/nyavro/i18nPlugin) Intellij idea i18next 支持插件([Jetbrains 插件页面](https://plugins.jetbrains.com/plugin/12981-i18n-support))。 - -适用于 i18n typescript/javascript/PHP 的插件。 支持 vue-i18n。 要启用 vue-i18n 支持,请转到 设置- > 工具 -> i18n 插件配置,然后选中 "Vue-i18n"。 您需要设置您的语言环境目录(默认为语言环境)。 - -### vue-i18n-extract - -[vue-i18n-extract](https://github.com/pixari/vue-i18n-extract) 对基于 vue-i18n 的 Vue.js 项目执行静态分析,并报告以下信息: - -- 所有 **未使用的 vue-i18n 键**的列表(在语言文件中找到但在项目中未使用的条目) -- 所有 **缺失键** 的列表(在项目中使用但在语言文件中不存在的条目) - -可以在控制台中显示输出或将其写入json文件 - -丢失的键也可以自动添加到给定的语言文件中 diff --git a/docs-old/zh/installation.md b/docs-old/zh/installation.md deleted file mode 100644 index 426e4e107..000000000 --- a/docs-old/zh/installation.md +++ /dev/null @@ -1,66 +0,0 @@ -# 安装 - -## 兼容性说明 - -- Vue.js `2.0.0`+ - -## 直接下载 / CDN - - - -[unpkg.com](https://unpkg.com) 提供了基于 NPM 的 CDN 链接。上面的链接会一直指向在 NPM 发布的最新版本。你也可以通过 这样的 URL 指定版本号或者 tag。 - -在 Vue 之后引入 vue-i18n,它会自动安装: - - -```html - - -``` - -## NPM - -```sh -npm install vue-i18n -``` - -## Yarn - -```sh -yarn add vue-i18n -``` - -如果在一个模块系统中使用它,你必须通过 `Vue.use()` 明确地安装 `vue-i18n`: - - -```javascript -import Vue from 'vue' -import VueI18n from 'vue-i18n' - -Vue.use(VueI18n) -``` - -如果使用全局的 script 标签,则无须如此 (手动安装) ` - - -
-

{{ $t("message.hello") }}

-
-``` - -## JavaScript - -```js -// 如果使用模块系统 (例如通过 vue-cli),则需要导入 Vue 和 VueI18n ,然后调用 Vue.use(VueI18n)。 -// import Vue from 'vue' -// import VueI18n from 'vue-i18n' -// -// Vue.use(VueI18n) - -// 准备翻译的语言环境信息 -const messages = { - en: { - message: { - hello: 'hello world' - } - }, - ja: { - message: { - hello: 'こんにちは、世界' - } - } -} - -// 通过选项创建 VueI18n 实例 -const i18n = new VueI18n({ - locale: 'ja', // 设置地区 - messages, // 设置地区信息 -}) - - -// 通过 `i18n` 选项创建 Vue 实例 -new Vue({ i18n }).$mount('#app') - -// 现在应用程序已经准备好了! -``` - -输出如下: - -```html -
-

こんにちは、世界

-
-``` diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 662190b6e..bfcdda720 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -218,10 +218,6 @@ function sidebarGuide() { text: 'New Features in v9', link: '/guide/migration/features' }, - { - text: 'Migration from Vue 2', - link: '/guide/migration/vue2' - }, { text: 'Migration in Vue 3', link: '/guide/migration/vue3' @@ -237,8 +233,8 @@ function sidebarGuide() { link: '/guide/extra/dist' }, { - text: 'Documentation for v8.x', - link: '/guide/extra/v8-docs' + text: 'Migration from Vue 2', + link: '/guide/migration/vue2' } ] } diff --git a/docs/guide/maintenance.md b/docs/guide/maintenance.md index 4943df068..145f6a8ee 100644 --- a/docs/guide/maintenance.md +++ b/docs/guide/maintenance.md @@ -4,7 +4,8 @@ Vue I18n and related intlify packages has a lifecycle. The following is the maintenance status for each version: -Vue I18n Maintenance Status +Vue I18n Maintenance Status > [!IMPORTANT] -Vue I18n v8 is no longer supported after 2025. Vue I18n v9 and Vue I18n v10 is in maintenance mode after 2025 July. + +Vue I18n v8 has reached EOL and is no longer actively maintained. Vue I18n v9 and Vue I18n v10 is in maintenance mode after 2025 July. diff --git a/docs/guide/v8-docs.md b/docs/guide/v8-docs.md deleted file mode 100644 index 9c908bf66..000000000 --- a/docs/guide/v8-docs.md +++ /dev/null @@ -1,22 +0,0 @@ -# Documentation for v8.x - -- [Introduction](https://github.com/intlify/vue-i18n/blob/master/docs-old/introduction.md) -- [Getting started](https://github.com/intlify/vue-i18n/blob/master/docs-old/started.md) -- [Installation](https://github.com/intlify/vue-i18n/blob/master/docs-old/installation.md) -- Guide - - [Formatting](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/formatting.md) - - [Pluralization](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/pluralization.md) - - [DateTime localization](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/datetime.md) - - [Number localization](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/number.md) - - [Locale messages syntax](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/messages.md) - - [Fallback localization](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/fallback.md) - - [Component based localization](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/component.md) - - [Custom directive localization](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/directive.md) - - [Component interpolation](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/interpolation.md) - - [Single file components](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/sfc.md) - - [Hot reloading](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/hot-reload.md) - - [Locale changing](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/locale.md) - - [Lazy loading translations](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/lazy-loading.md) - - [Tooling](https://github.com/intlify/vue-i18n/blob/master/docs-old/guide/tooling.md) -- [API references](https://github.com/intlify/vue-i18n/blob/master/docs-old/api/README.md) - diff --git a/docs/public/lifecycle2025-1.excalidraw b/docs/public/lifecycle2025-1.excalidraw new file mode 100644 index 000000000..921724341 --- /dev/null +++ b/docs/public/lifecycle2025-1.excalidraw @@ -0,0 +1,1189 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "YbPbE3iYZmV_3J4aIrZ0v", + "type": "text", + "x": 1128.2236916124564, + "y": 361.74584105795753, + "width": 77, + "height": 25, + "angle": 0, + "strokeColor": "white", + "backgroundColor": "#e64980", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1767348146, + "version": 219, + "versionNonce": 1477768050, + "isDeleted": false, + "boundElementIds": null, + "text": "Team 2", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "a3", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1733211872168, + "link": null, + "locked": false, + "containerId": null, + "originalText": "Team 2", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "KaaUzvllAfwSp4xX5xNzx", + "type": "line", + "x": 350.62500000000006, + "y": 162.2170718013658, + "width": 0, + "height": 323.1526724873608, + "angle": 0, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 30, + "groupIds": [], + "strokeSharpness": "round", + "seed": 203664754, + "version": 411, + "versionNonce": 666349204, + "isDeleted": false, + "boundElementIds": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 323.1526724873608 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "index": "aK", + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1735049936982, + "link": null, + "locked": false + }, + { + "id": "DZZZ6ZgVkIprA06jL-kCX", + "type": "line", + "x": 696.0750992057751, + "y": 164.1835924161148, + "width": 0, + "height": 311.12990190977405, + "angle": 0, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 30, + "groupIds": [], + "strokeSharpness": "round", + "seed": 1576087346, + "version": 352, + "versionNonce": 332346540, + "isDeleted": false, + "boundElementIds": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 311.12990190977405 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "index": "aL", + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1735049936982, + "link": null, + "locked": false + }, + { + "id": "9Zyu12Lh8d99PVFP35teh", + "type": "line", + "x": 869.3749999999998, + "y": 164.1124071733318, + "width": 0, + "height": 313.0937365643726, + "angle": 0, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 30, + "groupIds": [], + "strokeSharpness": "round", + "seed": 640186610, + "version": 379, + "versionNonce": 996981780, + "isDeleted": false, + "boundElementIds": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 313.0937365643726 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "index": "aM", + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1735049936982, + "link": null, + "locked": false + }, + { + "id": "15nEBpxKWh7RahGfZNtxI", + "type": "line", + "x": 534.375, + "y": 163.5207405140126, + "width": 0, + "height": 314.31628636096366, + "angle": 0, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 30, + "groupIds": [], + "strokeSharpness": "round", + "seed": 252732530, + "version": 298, + "versionNonce": 198950700, + "isDeleted": false, + "boundElementIds": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 314.31628636096366 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "index": "aO", + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1735049936982, + "link": null, + "locked": false + }, + { + "id": "3yvHCU_SIZ1dlBTsp-oQb", + "type": "rectangle", + "x": 295.04291083627874, + "y": 188.29490724404621, + "width": 400.8352374286324, + "height": 38.75, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1682219442, + "version": 425, + "versionNonce": 105635405, + "isDeleted": false, + "boundElementIds": null, + "index": "aR", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false + }, + { + "id": "8mOWQ0Sn_Bhr5PuIx4AkT", + "type": "text", + "x": 468.48231432901616, + "y": 196.65481162471866, + "width": 60.85995787382126, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1863551794, + "version": 455, + "versionNonce": 322210989, + "isDeleted": false, + "boundElementIds": null, + "text": "Active", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "ab", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false, + "containerId": null, + "originalText": "Active", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "GzHn2uxkuMw6EAYG_1X4A", + "type": "rectangle", + "x": 171.33199398964427, + "y": 504.1467804793542, + "width": 31.25, + "height": 31.25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#fa5252", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 2, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1153190898, + "version": 455, + "versionNonce": 976054828, + "isDeleted": false, + "boundElementIds": null, + "index": "ag", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735049864166, + "link": null, + "locked": false + }, + { + "id": "ZF0_TKIDDzFADtju8oXdG", + "type": "text", + "x": 221.33199398964427, + "y": 511.3967804793542, + "width": 246.81979978084564, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#fa5252", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 2, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1727135154, + "version": 479, + "versionNonce": 64439468, + "isDeleted": false, + "boundElementIds": null, + "text": "Maintenance (Hotfix only)", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "ah", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735049864166, + "link": null, + "locked": false, + "containerId": null, + "originalText": "Maintenance (Hotfix only)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 647, + "versionNonce": 1617022764, + "isDeleted": false, + "id": "tHx1CyVsgH2d2dkgpbIZn", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 170.70699398964427, + "y": 568.5217804793542, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "width": 28.74999999999998, + "height": 27.50000000000002, + "seed": 587954034, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElementIds": [], + "index": "ai", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735049864166, + "link": null, + "locked": false + }, + { + "id": "dHNxYCpsffyHkh_LlLILR", + "type": "text", + "x": 221.33199398964427, + "y": 570.1467804793542, + "width": 60.85995787382126, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#fa5252", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 2, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 424655154, + "version": 469, + "versionNonce": 272042412, + "isDeleted": false, + "boundElementIds": null, + "text": "Active", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "aj", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735049864166, + "link": null, + "locked": false, + "containerId": null, + "originalText": "Active", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "dBir_bIRB1stHdb-oF-hN", + "type": "text", + "x": 295.47037121881516, + "y": 131.006502505325, + "width": 115.27991855144501, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 963486322, + "version": 299, + "versionNonce": 1187159790, + "isDeleted": false, + "boundElementIds": null, + "text": "2024-07-01", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "ap", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1733211475536, + "link": null, + "locked": false, + "containerId": null, + "originalText": "2024-07-01", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "3I5lYgO0QCJSbgRxRLTPm", + "type": "text", + "x": 479.7708621160903, + "y": 131.35900116040705, + "width": 109.49991977214813, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1472541550, + "version": 390, + "versionNonce": 2126006766, + "isDeleted": false, + "boundElementIds": null, + "text": "2025-01-01", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "aq", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1733211463249, + "link": null, + "locked": false, + "containerId": null, + "originalText": "2025-01-01", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "lSGvI5WivRLgRuHb_pqUm", + "type": "text", + "x": 642.7282219798635, + "y": 130.3964086792214, + "width": 114.83991611003876, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 444106994, + "version": 511, + "versionNonce": 19267502, + "isDeleted": false, + "boundElementIds": null, + "text": "2025-07-01", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "ar", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1733211467468, + "link": null, + "locked": false, + "containerId": null, + "originalText": "2025-07-01", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "KaXp0RpQyl81ul_cSHCiV", + "type": "text", + "x": 811.6663190600316, + "y": 130.9432335159513, + "width": 109.93992221355438, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 761725230, + "version": 539, + "versionNonce": 398021614, + "isDeleted": false, + "boundElementIds": null, + "text": "2026-01-01", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "as", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1733211472936, + "link": null, + "locked": false, + "containerId": null, + "originalText": "2026-01-01", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "Zl0Yw_XDHJ9iqVEZk5PqL", + "type": "rectangle", + "x": 699.2705127967365, + "y": 187.91427656489464, + "width": 168.42112417786478, + "height": 38.75, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#fa5252", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 471807790, + "version": 619, + "versionNonce": 800616205, + "isDeleted": false, + "boundElementIds": null, + "index": "at", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false + }, + { + "id": "Yga-sG8cZZFBhIGv9ZJ77", + "type": "text", + "x": 727.7747972891052, + "y": 194.88869926248185, + "width": 118.4399322271347, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 793064494, + "version": 348, + "versionNonce": 709952877, + "isDeleted": false, + "boundElementIds": null, + "text": "Maintenance", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "au", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false, + "containerId": null, + "originalText": "Maintenance", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "iCre7vT6D1qTq2qjWTgWh", + "type": "rectangle", + "x": 295.52623592874687, + "y": 254.7439101687541, + "width": 481.4457781823576, + "height": 38.75, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 2101267246, + "version": 936, + "versionNonce": 1179111373, + "isDeleted": false, + "boundElementIds": null, + "index": "av", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false + }, + { + "id": "c8fb3Iwg_p7uGfg-3-atm", + "type": "line", + "x": 955.9773524320833, + "y": 345.1350868969375, + "width": 69.05358268786904, + "height": 0.347979441555367, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aw", + "roundness": { + "type": 2 + }, + "seed": 1697289010, + "version": 330, + "versionNonce": 565595693, + "isDeleted": false, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 69.05358268786904, + 0.347979441555367 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "id": "CIq_PLwyQmd8qYWoEmtMA", + "type": "text", + "x": 442.53017813626025, + "y": 263.86393401754776, + "width": 262.0598022341728, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 222507826, + "version": 898, + "versionNonce": 1535508621, + "isDeleted": false, + "boundElementIds": null, + "text": "Active (until 2025-06-30)", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "ay", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false, + "containerId": null, + "originalText": "Active (until 2025-06-30)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "1-a1B88njz8X7CQ9T2Q1f", + "type": "text", + "x": 162.89090833540598, + "y": 197.37878591568966, + "width": 106.23992919921875, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 18151022, + "version": 332, + "versionNonce": 2037409517, + "isDeleted": false, + "boundElementIds": null, + "text": "VueI18n v9", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "b00", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false, + "containerId": null, + "originalText": "VueI18n v9", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "-6rj3sguQAgFE0FsnivSK", + "type": "text", + "x": 163.08457274115682, + "y": 260.41679937065373, + "width": 113.23992919921875, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 311348338, + "version": 393, + "versionNonce": 234815821, + "isDeleted": false, + "boundElementIds": null, + "text": "VueI18n v10", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "b01", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false, + "containerId": null, + "originalText": "VueI18n v10", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "rAlNxSvfI6_AJg3LtOBPF", + "type": "line", + "x": 1040.9107029563916, + "y": 154.736566890844, + "width": 0, + "height": 319.7277923075103, + "angle": 0, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 30, + "groupIds": [], + "strokeSharpness": "round", + "seed": 1470226286, + "version": 456, + "versionNonce": 2365844, + "isDeleted": false, + "boundElementIds": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 319.7277923075103 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null, + "index": "b05", + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1735049936982, + "link": null, + "locked": false + }, + { + "id": "-KaaHGdRmpp28fKgNzy7F", + "type": "text", + "x": 984.364127985853, + "y": 127.88824517190653, + "width": 115.27991855144501, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1260307886, + "version": 615, + "versionNonce": 144256302, + "isDeleted": false, + "boundElementIds": null, + "text": "2026-07-01", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "b06", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1733211724257, + "link": null, + "locked": false, + "containerId": null, + "originalText": "2026-07-01", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "zhnxHeTa7Zt3eSYRsgNmr", + "type": "rectangle", + "x": 689.1258721820029, + "y": 323.8752929690932, + "width": 247.4418719323578, + "height": 38.75, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1446955948, + "version": 1466, + "versionNonce": 512446381, + "isDeleted": false, + "boundElementIds": null, + "index": "b07", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false + }, + { + "id": "E7k3rB2n8YGDcvHcDG7y6", + "type": "text", + "x": 783.1863604612711, + "y": 329.63310546909315, + "width": 60.85995787382126, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 569137556, + "version": 692, + "versionNonce": 1228853773, + "isDeleted": false, + "boundElementIds": null, + "text": "Active", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "b08", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false, + "containerId": null, + "originalText": "Active", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "lDNs8aJUE9LvIQukNh_ib", + "type": "rectangle", + "x": 780.3354648092493, + "y": 255.5510742190932, + "width": 88.03440542786478, + "height": 38.75, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#fa5252", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 1189482156, + "version": 788, + "versionNonce": 722667629, + "isDeleted": false, + "boundElementIds": null, + "index": "b0A", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false + }, + { + "id": "1KHQmnwxK23ZG_-X_F-I4", + "type": "text", + "x": 903.3221545346144, + "y": 263.9924804690932, + "width": 118.4399322271347, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 685807276, + "version": 887, + "versionNonce": 97612493, + "isDeleted": false, + "boundElementIds": null, + "text": "Maintenance", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "b0B", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false, + "containerId": null, + "originalText": "Maintenance", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "469Ub5AUlLrEvUVkcttlm", + "type": "line", + "x": 832.2145227900735, + "y": 277.89838884247985, + "width": 57.24889518786904, + "height": 0.581708058444633, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "b0C", + "roundness": { + "type": 2 + }, + "seed": 1795179412, + "version": 559, + "versionNonce": 638816557, + "isDeleted": false, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 57.24889518786904, + -0.581708058444633 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "id": "e_BP_JEw5PPSVhTP4MSUg", + "type": "text", + "x": 163.68387479857233, + "y": 328.46513671909315, + "width": 104.89993286132812, + "height": 25, + "angle": 0, + "strokeColor": "#343a40", + "backgroundColor": "#82c91e", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 411179924, + "version": 476, + "versionNonce": 155378573, + "isDeleted": false, + "boundElementIds": null, + "text": "VueI18n v11", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "index": "b0D", + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1735626077833, + "link": null, + "locked": false, + "containerId": null, + "originalText": "VueI18n v11", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": 20, + "gridStep": 5, + "gridModeEnabled": false, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/docs/public/lifecycle2025-1.png b/docs/public/lifecycle2025-1.png new file mode 100644 index 0000000000000000000000000000000000000000..700cd01b8d0b2a3c612544fc05dd6bedf0dcc615 GIT binary patch literal 147298 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�i?P!@?gj?E8*%q8O$-$| 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 Kx + + + + + + + Team 2ActiveMaintenance (Hotfix only)Active2024-07-012025-01-012025-07-012026-01-01MaintenanceActive (until 2025-06-30)VueI18n v9VueI18n v102026-07-01ActiveMaintenanceVueI18n v11 \ No newline at end of file