feat: add vue-i18n
This commit is contained in:
parent
7e7c7969fb
commit
b93c6c8314
8
.vscode/extensions.json
vendored
Normal file
8
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"octref.vetur",
|
||||||
|
"antfu.i18n-ally",
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"bradlc.vscode-tailwindcss"
|
||||||
|
]
|
||||||
|
}
|
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"i18n-ally.localesPaths": "locales",
|
||||||
|
"i18n-ally.keystyle": "nested",
|
||||||
|
"i18n-ally.sortKeys": true,
|
||||||
|
|
||||||
|
"vetur.experimental.templateInterpolationService": true
|
||||||
|
}
|
19
README.md
19
README.md
@ -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
10
locales/en.json
Normal 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
10
locales/fr.json
Normal 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
10
locales/zh-CN.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"button": {
|
||||||
|
"back": "返回",
|
||||||
|
"go": "确定"
|
||||||
|
},
|
||||||
|
"intro": {
|
||||||
|
"hi": "你好,{name}!",
|
||||||
|
"whats-your-name": "输入你的名字"
|
||||||
|
}
|
||||||
|
}
|
@ -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": {
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
}
|
11
src/main.ts
11
src/main.ts
@ -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
11
src/messages.ts
Normal 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)
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user