feat: add pinia stores (#170)

This commit is contained in:
Eduardo San Martin Morote 2021-08-19 07:53:52 +02:00 committed by GitHub
parent 423b506d70
commit 4a412acc9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 96 additions and 88 deletions

View File

@ -9,5 +9,6 @@ intro:
desc: Opinionated Vite Starter Template
dynamic-route: Demo of dynamic route
hi: Hi, {name}!
aka: Also known as
whats-your-name: What's your name?
not-found: Not found

View File

@ -9,5 +9,6 @@ intro:
desc: Plantilla de Inicio de Vite Dogmática
dynamic-route: Demo de ruta dinámica
hi: ¡Hola, {name}!
aka: También conocido como
whats-your-name: ¿Cómo te llamas?
not-found: No se ha encontrado

View File

@ -9,5 +9,6 @@ intro:
desc: Exemple d'application Vite
dynamic-route: Démo de route dynamique
hi: Salut, {name}!
aka: Aussi connu sous le nom de
whats-your-name: Comment t'appelles-tu ?
not-found: Page non trouvée

View File

@ -9,5 +9,6 @@ intro:
desc: Modelo Opinativo de Partida de Vite
dynamic-route: Demonstração de rota dinâmica
hi: Olá, {name}!
aka: Também conhecido como
whats-your-name: Qual é o seu nome?
not-found: Não encontrado

View File

@ -9,5 +9,6 @@ intro:
desc: 固执己见的 Vite 项目模板
dynamic-route: 动态路由演示
hi: 你好,{name}
aka: 也叫
whats-your-name: 输入你的名字
not-found: 未找到页面

View File

@ -10,6 +10,7 @@
"@vueuse/core": "^6.0.0",
"@vueuse/head": "^0.6.0",
"nprogress": "^0.2.0",
"pinia": "^2.0.0-0",
"prism-theme-vars": "^0.2.2",
"vue": "^3.2.2",
"vue-demi": "^0.11.3",
@ -22,7 +23,6 @@
"@iconify/json": "^1.1.387",
"@intlify/vite-plugin-vue-i18n": "^2.4.0",
"@types/nprogress": "^0.2.0",
"@typescript-eslint/eslint-plugin": "^4.29.1",
"@vitejs/plugin-vue": "^1.4.0",
"@vue/compiler-sfc": "^3.2.2",
"@vue/server-renderer": "^3.2.2",

View File

@ -5,7 +5,6 @@ specifiers:
'@iconify/json': ^1.1.387
'@intlify/vite-plugin-vue-i18n': ^2.4.0
'@types/nprogress': ^0.2.0
'@typescript-eslint/eslint-plugin': ^4.29.1
'@vitejs/plugin-vue': ^1.4.0
'@vue/compiler-sfc': ^3.2.2
'@vue/server-renderer': ^3.2.2
@ -18,6 +17,7 @@ specifiers:
markdown-it-link-attributes: ^3.0.0
markdown-it-prism: ^2.1.8
nprogress: ^0.2.0
pinia: ^2.0.0-0
pnpm: ^6.13.0
prism-theme-vars: ^0.2.2
typescript: ^4.3.5
@ -41,6 +41,7 @@ dependencies:
'@vueuse/core': 6.0.0_vue@3.2.2
'@vueuse/head': 0.6.0_vue@3.2.2
nprogress: 0.2.0
pinia: 2.0.0-rc.4_typescript@4.3.5+vue@3.2.2
prism-theme-vars: 0.2.2
vue: 3.2.2
vue-demi: 0.11.3_vue@3.2.2
@ -53,7 +54,6 @@ devDependencies:
'@iconify/json': 1.1.387
'@intlify/vite-plugin-vue-i18n': 2.4.0_bdfaf14c5541fb1bd751e193a94ac007
'@types/nprogress': 0.2.0
'@typescript-eslint/eslint-plugin': 4.29.1_eslint@7.32.0+typescript@4.3.5
'@vitejs/plugin-vue': 1.4.0_@vue+compiler-sfc@3.2.2
'@vue/compiler-sfc': 3.2.2
'@vue/server-renderer': 3.2.2_vue@3.2.2
@ -1615,30 +1615,6 @@ packages:
- supports-color
dev: true
/@typescript-eslint/eslint-plugin/4.29.1_eslint@7.32.0+typescript@4.3.5:
resolution: {integrity: sha512-AHqIU+SqZZgBEiWOrtN94ldR3ZUABV5dUG94j8Nms9rQnHFc8fvDOue/58K4CFz6r8OtDDc35Pw9NQPWo0Ayrw==}
engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies:
'@typescript-eslint/parser': ^4.0.0
eslint: ^5.0.0 || ^6.0.0 || ^7.0.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/experimental-utils': 4.29.1_eslint@7.32.0+typescript@4.3.5
'@typescript-eslint/scope-manager': 4.29.1
debug: 4.3.2
eslint: 7.32.0
functional-red-black-tree: 1.0.1
regexpp: 3.2.0
semver: 7.3.5
tsutils: 3.21.0_typescript@4.3.5
typescript: 4.3.5
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/experimental-utils/4.28.4_eslint@7.32.0+typescript@4.3.5:
resolution: {integrity: sha512-OglKWOQRWTCoqMSy6pm/kpinEIgdcXYceIcH3EKWUl4S8xhFtN34GQRaAvTIZB9DD94rW7d/U7tUg3SYeDFNHA==}
engines: {node: ^10.12.0 || >=12.0.0}
@ -1657,24 +1633,6 @@ packages:
- typescript
dev: true
/@typescript-eslint/experimental-utils/4.29.1_eslint@7.32.0+typescript@4.3.5:
resolution: {integrity: sha512-kl6QG6qpzZthfd2bzPNSJB2YcZpNOrP6r9jueXupcZHnL74WiuSjaft7WSu17J9+ae9zTlk0KJMXPUj0daBxMw==}
engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies:
eslint: '*'
dependencies:
'@types/json-schema': 7.0.8
'@typescript-eslint/scope-manager': 4.29.1
'@typescript-eslint/types': 4.29.1
'@typescript-eslint/typescript-estree': 4.29.1_typescript@4.3.5
eslint: 7.32.0
eslint-scope: 5.1.1
eslint-utils: 3.0.0_eslint@7.32.0
transitivePeerDependencies:
- supports-color
- typescript
dev: true
/@typescript-eslint/parser/4.28.4_eslint@7.32.0+typescript@4.3.5:
resolution: {integrity: sha512-4i0jq3C6n+og7/uCHiE6q5ssw87zVdpUj1k6VlVYMonE3ILdFApEzTWgppSRG4kVNB/5jxnH+gTeKLMNfUelQA==}
engines: {node: ^10.12.0 || >=12.0.0}
@ -1703,24 +1661,11 @@ packages:
'@typescript-eslint/visitor-keys': 4.28.4
dev: true
/@typescript-eslint/scope-manager/4.29.1:
resolution: {integrity: sha512-Hzv/uZOa9zrD/W5mftZa54Jd5Fed3tL6b4HeaOpwVSabJK8CJ+2MkDasnX/XK4rqP5ZTWngK1ZDeCi6EnxPQ7A==}
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
dependencies:
'@typescript-eslint/types': 4.29.1
'@typescript-eslint/visitor-keys': 4.29.1
dev: true
/@typescript-eslint/types/4.28.4:
resolution: {integrity: sha512-3eap4QWxGqkYuEmVebUGULMskR6Cuoc/Wii0oSOddleP4EGx1tjLnZQ0ZP33YRoMDCs5O3j56RBV4g14T4jvww==}
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
dev: true
/@typescript-eslint/types/4.29.1:
resolution: {integrity: sha512-Jj2yu78IRfw4nlaLtKjVaGaxh/6FhofmQ/j8v3NXmAiKafbIqtAPnKYrf0sbGjKdj0hS316J8WhnGnErbJ4RCA==}
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
dev: true
/@typescript-eslint/typescript-estree/4.28.4_typescript@4.3.5:
resolution: {integrity: sha512-z7d8HK8XvCRyN2SNp+OXC2iZaF+O2BTquGhEYLKLx5k6p0r05ureUtgEfo5f6anLkhCxdHtCf6rPM1p4efHYDQ==}
engines: {node: ^10.12.0 || >=12.0.0}
@ -1742,27 +1687,6 @@ packages:
- supports-color
dev: true
/@typescript-eslint/typescript-estree/4.29.1_typescript@4.3.5:
resolution: {integrity: sha512-lIkkrR9E4lwZkzPiRDNq0xdC3f2iVCUjw/7WPJ4S2Sl6C3nRWkeE1YXCQ0+KsiaQRbpY16jNaokdWnm9aUIsfw==}
engines: {node: ^10.12.0 || >=12.0.0}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
'@typescript-eslint/types': 4.29.1
'@typescript-eslint/visitor-keys': 4.29.1
debug: 4.3.2
globby: 11.0.4
is-glob: 4.0.1
semver: 7.3.5
tsutils: 3.21.0_typescript@4.3.5
typescript: 4.3.5
transitivePeerDependencies:
- supports-color
dev: true
/@typescript-eslint/visitor-keys/4.28.4:
resolution: {integrity: sha512-NIAXAdbz1XdOuzqkJHjNKXKj8QQ4cv5cxR/g0uQhCYf/6//XrmfpaYsM7PnBcNbfvTDLUkqQ5TPNm1sozDdTWg==}
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
@ -1771,14 +1695,6 @@ packages:
eslint-visitor-keys: 2.1.0
dev: true
/@typescript-eslint/visitor-keys/4.29.1:
resolution: {integrity: sha512-zLqtjMoXvgdZY/PG6gqA73V8BjqPs4af1v2kiiETBObp+uC6gRYnJLmJHxC0QyUrrHDLJPIWNYxoBV3wbcRlag==}
engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1}
dependencies:
'@typescript-eslint/types': 4.29.1
eslint-visitor-keys: 2.1.0
dev: true
/@vitejs/plugin-vue/1.4.0_@vue+compiler-sfc@3.2.2:
resolution: {integrity: sha512-RkqfJHz9wdLKBp5Yi+kQL8BAljdrvPoccQm2PTZc/UcL4EjD11xsv2PPCduYx2oV1a/bpSKA3sD5sxOHFhz+LA==}
engines: {node: '>=12.0.0'}
@ -4633,6 +4549,24 @@ packages:
engines: {node: '>=4'}
dev: true
/pinia/2.0.0-rc.4_typescript@4.3.5+vue@3.2.2:
resolution: {integrity: sha512-I43V1TIFyDWT4UTi1CPLQXQZYXGQHQMKpDPI+oxC2fv0c+ej0fQBoKCn4WbfRWB+Vf5chhWM97GFLI+OWmUQEQ==}
peerDependencies:
'@vue/composition-api': ^1.1.0
typescript: ^4.3.5
vue: ^2.6.14 || ^3.2.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
typescript:
optional: true
dependencies:
'@vue/devtools-api': 6.0.0-beta.15
typescript: 4.3.5
vue: 3.2.2
vue-demi: 0.11.3_vue@3.2.2
dev: false
/pkg-dir/2.0.0:
resolution: {integrity: sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=}
engines: {node: '>=4'}

15
src/modules/pinia.ts Normal file
View File

@ -0,0 +1,15 @@
import { createPinia } from 'pinia'
import { UserModule } from '~/types'
export const install: UserModule = ({ isClient, initialState, app }) => {
const pinia = createPinia()
app.use(pinia)
// Refer to
// https://github.com/antfu/vite-ssg/blob/main/README.md#state-serialization
// for other serialization strategies.
if (isClient)
pinia.state.value = (initialState.pinia) || {}
else
initialState.pinia = pinia.state.value
}

View File

@ -1,10 +1,17 @@
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useUserStore } from '~/stores/user'
const props = defineProps<{ name: string }>()
const router = useRouter()
const { t } = useI18n()
const user = useUserStore()
watch(() => props.name, (name) => {
user.setNewName(name)
}, { immediate: true })
</script>
<template>
@ -15,6 +22,17 @@ const { t } = useI18n()
<p>
{{ t('intro.hi', { name: props.name }) }}
</p>
<template v-if="user.otherNames.length">
<p class="text-sm">
{{ t('intro.aka') }}:
<ul>
<li v-for="name in user.otherNames">
{{ name }}
</li>
</ul>
</p>
</template>
<p class="text-sm opacity-50">
<em>{{ t('intro.dynamic-route') }}</em>
</p>

View File

@ -1,8 +1,10 @@
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { useUserStore } from '~/stores/user'
const name = ref('')
const user = useUserStore()
const name = ref(user.savedName)
const router = useRouter()
const go = () => {

34
src/stores/user.ts Normal file
View File

@ -0,0 +1,34 @@
import { acceptHMRUpdate, defineStore } from 'pinia'
export const useUserStore = defineStore('user', () => {
/**
* Current named of the user.
*/
const savedName = ref('')
const previousNames = ref(new Set<string>())
const usedNames = computed(() => Array.from(previousNames.value))
const otherNames = computed(() => usedNames.value.filter(name => name !== savedName.value))
/**
* Changes the current name of the user and saves the one that was used
* before.
*
* @param name - new name to set
*/
function setNewName(name: string) {
if (savedName.value)
previousNames.value.add(savedName.value)
savedName.value = name
}
return {
setNewName,
otherNames,
savedName,
}
})
if (import.meta.hot)
import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot))