feat: add vue-i18n

This commit is contained in:
Anthony Fu 2020-08-10 11:17:26 +08:00
parent 7e7c7969fb
commit b93c6c8314
14 changed files with 135 additions and 18 deletions

8
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"recommendations": [
"octref.vetur",
"antfu.i18n-ally",
"dbaeumer.vscode-eslint",
"bradlc.vscode-tailwindcss"
]
}

7
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"i18n-ally.localesPaths": "locales",
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"vetur.experimental.templateInterpolationService": true
}

View File

@ -11,7 +11,7 @@
<br> <br>
<p align='center'> <p align='center'>
<a href="https://vitesse.netilfy.app">Live Example</a> <a href="https://vitesse.netilfy.app">Live Demo</a>
</p> </p>
<br> <br>
@ -32,6 +32,7 @@
### Utils ### Utils
- [vue-i18n](https://github.com/intlify/vue-i18n-next)
- [VueUse](https://github.com/antfu/vueuse) - [VueUse](https://github.com/antfu/vueuse)
### Misc ### Misc
@ -44,16 +45,22 @@
- [pnpm](https://pnpm.js.org/) - [pnpm](https://pnpm.js.org/)
- [Netlify](https://www.netlify.com/) - [Netlify](https://www.netlify.com/)
- [ESLint](https://eslint.org/) with [@antfu/eslint-config-vue](https://github.com/antfu/eslint-config) - [ESLint](https://eslint.org/) with [@antfu/eslint-config-vue](https://github.com/antfu/eslint-config)
- [VS Code Extensions](./.vscode/extensions.json)
## Use It! ## Try it now!
[Create a repo from this template on Github](https://github.com/antfu/vitesse/generate).
Or if you prefers do to manually with cleaner git history
```bash ```bash
npx degit antfu/vitesse my-vitesse-app \ npx degit antfu/vitesse my-vitesse-app
cd my-vitesse-app \ cd my-vitesse-app
git init \
pnpm i # If you don't have pnpm installed, run: npm install -g pnpm pnpm i # If you don't have pnpm installed, run: npm install -g pnpm
``` ```
## Why ## Why
I have created several Vite apps recently. Setting the configs up is kinda the bottleneck for me to make the idea simply comes true in very a short time. So I made this starter template for myself to create apps more easily, along with some good practices that I have learned during making those apps. It's strongly opinionated, but feel free to tweak it or even maintains your own forks. I have created several Vite apps recently. Setting the configs up is kinda the bottleneck for me to make the idea simply comes true in a very short time.
So I made this starter template for myself to create apps more easily, along with some good practices that I have learned from making those apps. It's strongly opinionated, but feel free to tweak it or even maintains your own forks.

10
locales/en.json Normal file
View File

@ -0,0 +1,10 @@
{
"intro": {
"whats-your-name": "What's your name?",
"hi": "Hi, {name}!"
},
"button": {
"go": "GO",
"back": "Back"
}
}

10
locales/fr.json Normal file
View File

@ -0,0 +1,10 @@
{
"button": {
"back": "Arrière",
"go": "ALLER"
},
"intro": {
"hi": "Salut, {name}!",
"whats-your-name": "Quel est ton nom?"
}
}

10
locales/zh-CN.json Normal file
View File

@ -0,0 +1,10 @@
{
"button": {
"back": "返回",
"go": "确定"
},
"intro": {
"hi": "你好,{name}",
"whats-your-name": "输入你的名字"
}
}

View File

@ -11,6 +11,7 @@
"@vueuse/core": "^4.0.0-beta.4", "@vueuse/core": "^4.0.0-beta.4",
"variantwind": "^0.3.4", "variantwind": "^0.3.4",
"vue": "^3.0.0-rc.1", "vue": "^3.0.0-rc.1",
"vue-i18n": "^9.0.0-alpha.13",
"vue-router": "^4.0.0-beta.6" "vue-router": "^4.0.0-beta.6"
}, },
"devDependencies": { "devDependencies": {

View File

@ -3,6 +3,7 @@ dependencies:
'@vueuse/core': 4.0.0-beta.4_vue@3.0.0-rc.5 '@vueuse/core': 4.0.0-beta.4_vue@3.0.0-rc.5
variantwind: 0.3.4 variantwind: 0.3.4
vue: 3.0.0-rc.5 vue: 3.0.0-rc.5
vue-i18n: 9.0.0-alpha.13_vue@3.0.0-rc.5
vue-router: 4.0.0-beta.6_vue@3.0.0-rc.5 vue-router: 4.0.0-beta.6_vue@3.0.0-rc.5
devDependencies: devDependencies:
'@antfu/eslint-config-vue': 0.2.14_eslint@7.6.0+typescript@3.9.7 '@antfu/eslint-config-vue': 0.2.14_eslint@7.6.0+typescript@3.9.7
@ -3817,10 +3818,20 @@ packages:
eslint: '>=5.0.0' eslint: '>=5.0.0'
resolution: resolution:
integrity: sha512-Kr21uPfthDc63nDl27AGQEhtt9VrZ9nkYk/NTftJ2ws9XiJwzJJCnCr3AITQ2jpRMA0XPGDECxYH8E027qMK9Q== integrity: sha512-Kr21uPfthDc63nDl27AGQEhtt9VrZ9nkYk/NTftJ2ws9XiJwzJJCnCr3AITQ2jpRMA0XPGDECxYH8E027qMK9Q==
/vue-router/4.0.0-beta.6_vue@3.0.0-rc.5: /vue-i18n/9.0.0-alpha.13_vue@3.0.0-rc.5:
dependencies: dependencies:
vue: 3.0.0-rc.5 vue: 3.0.0-rc.5
dev: false dev: false
engines:
node: '>= 10'
peerDependencies:
vue: ^3.0.0-rc.5
resolution:
integrity: sha1-Y1SRXPruZumXOyFmnIvLbPge6rI=
tarball: vue-i18n/download/vue-i18n-9.0.0-alpha.13.tgz
/vue-router/4.0.0-beta.6_vue@3.0.0-rc.5:
dependencies:
vue: 3.0.0-rc.5
peerDependencies: peerDependencies:
vue: ^3.0.0-beta.20 vue: ^3.0.0-beta.20
resolution: resolution:
@ -3910,4 +3921,5 @@ specifiers:
vite: ^1.0.0-rc.1 vite: ^1.0.0-rc.1
vite-plugin-voie: ^0.2.0 vite-plugin-voie: ^0.2.0
vue: ^3.0.0-rc.1 vue: ^3.0.0-rc.1
vue-i18n: ^9.0.0-alpha.13
vue-router: ^4.0.0-beta.6 vue-router: ^4.0.0-beta.6

View File

@ -1,10 +1,7 @@
<template> <template>
<div class="text-xl mt-6">
<div <div
class="text-xl mt-4" class="icon-btn mx-2"
>
<div
class="inline-block mx-2 cursor-pointer select-none"
@click="isDark = !isDark" @click="isDark = !isDark"
> >
<Icon <Icon
@ -14,7 +11,7 @@
</div> </div>
<a <a
class="mx-2" class="icon-btn mx-2"
href="https://github.com/antfu/vitesse" href="https://github.com/antfu/vitesse"
target="_blank" target="_blank"
> >
@ -23,9 +20,28 @@
icon="carbon:code" icon="carbon:code"
/> />
</a> </a>
<div
class="icon-btn mx-2"
@click="toggleLocales"
>
<Icon
class="inline-block"
icon="carbon:globe"
/>
</div>
</div> </div>
</template> </template>
<script setup lang='ts'> <script setup lang='ts'>
import { useI18n } from 'vue-i18n'
import { locales } from '../messages'
export { isDark } from '../utils/dark' export { isDark } from '../utils/dark'
const i18n = useI18n()
export const toggleLocales = () => {
// change to some real logic
i18n.locale.value = locales[(locales.indexOf(i18n.locale.value) + 1) % locales.length]
}
</script> </script>

View File

@ -24,3 +24,11 @@ html, body, #app {
.btn[disabled] { .btn[disabled] {
@apply cursor-default bg-gray-600 opacity-50; @apply cursor-default bg-gray-600 opacity-50;
} }
.icon-btn {
@apply opacity-75 transition duration-200 ease-in-out cursor-pointer inline-block select-none;
}
.icon-btn:hover {
@apply opacity-100;
}

View File

@ -1,10 +1,13 @@
import './main.postcss' import './main.postcss'
import { createApp } from 'vue' import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
// @ts-ignore import { createI18n } from 'vue-i18n'
// @ts-ignore: this is generated from voie, which TypeScript is not able to infer types correctly
import routes from '/@voie/pages' import routes from '/@voie/pages'
import { registerComponents } from './components' import { registerComponents } from './components'
import App from './App.vue' import App from './App.vue'
import { messages } from './messages'
const app = createApp(App) const app = createApp(App)
const router = createRouter({ const router = createRouter({
@ -12,6 +15,12 @@ const router = createRouter({
routes, routes,
}) })
const i18n = createI18n({
locale: 'en',
messages,
})
app.use(i18n)
app.use(router) app.use(router)
app.use(registerComponents) app.use(registerComponents)

11
src/messages.ts Normal file
View File

@ -0,0 +1,11 @@
import en from '../locales/en.json'
import zhCN from '../locales/zh-CN.json'
import fr from '../locales/fr.json'
export const messages = {
en,
'zh-CN': zhCN,
fr,
}
export const locales = Object.keys(messages)

View File

@ -5,7 +5,7 @@
<Icon class="iconify inline-block" icon="carbon:pedestrian" /> <Icon class="iconify inline-block" icon="carbon:pedestrian" />
</p> </p>
<p> <p>
Hi, {{ name }}! {{ t('intro.hi', {name}) }}
</p> </p>
<div> <div>
@ -13,7 +13,7 @@
class="btn m-3 text-sm mt-8" class="btn m-3 text-sm mt-8"
@click="back" @click="back"
> >
Back {{ t('button.back') }}
</button> </button>
</div> </div>
</div> </div>
@ -21,6 +21,7 @@
<script setup='props' lang='ts'> <script setup='props' lang='ts'>
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
declare const props: { declare const props: {
name: string name: string
@ -28,4 +29,7 @@ declare const props: {
const router = useRouter() const router = useRouter()
export const back = () => router.push('/') export const back = () => router.push('/')
const { t } = useI18n()
export { t }
</script> </script>

View File

@ -12,7 +12,7 @@
<input <input
v-model="name" v-model="name"
placeholder="What's your name?" :placeholder="t('intro.whats-your-name')"
class="px-4 py-2 border border-gray-200 rounded text-center outline-none active:outline-none bg-transparent dark:border-gray-700" class="px-4 py-2 border border-gray-200 rounded text-center outline-none active:outline-none bg-transparent dark:border-gray-700"
@keydown.enter="go" @keydown.enter="go"
> >
@ -23,7 +23,7 @@
:disabled="!name" :disabled="!name"
@click="go" @click="go"
> >
GO {{ t('button.go') }}
</button> </button>
</div> </div>
</div> </div>
@ -32,6 +32,7 @@
<script setup='props' lang='ts'> <script setup='props' lang='ts'>
import { ref } from 'vue' import { ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
export const name = ref('') export const name = ref('')
@ -40,4 +41,7 @@ export const go = () => {
if (name.value) if (name.value)
router.push(`/hi/${name.value}`) router.push(`/hi/${name.value}`)
} }
const { t } = useI18n()
export { t }
</script> </script>