<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>🍍 Pinia playground</title>
+
+ <link
+ rel="stylesheet"
+ href="https://cdn.jsdelivr.net/npm/@exampledev/new.css@1/new.min.css"
+ />
+ <link rel="stylesheet" href="https://fonts.xz.style/serve/inter.css" />
</head>
<body>
<div id="app"></div>
+
<script type="module" src="/playground/src/main.ts"></script>
</body>
</html>
"@rollup/plugin-replace": "^3.0.0",
"@sucrase/jest-plugin": "^2.1.0",
"@types/jest": "^26.0.24",
+ "@types/lodash.kebabcase": "^4.1.6",
"@types/node": "^16.0.1",
"@vue/server-renderer": "^3.1.5",
"@vue/test-utils": "^2.0.0-rc.10",
"jest": "^26.6.3",
"jest-mock-warn": "^1.1.0",
"lint-staged": "^11.0.1",
+ "lodash.kebabcase": "^4.1.1",
"pascalcase": "^1.0.0",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"vite": "^2.4.1",
"vitepress": "^0.15.6",
"vue": "^3.1.5",
+ "vue-router": "^4.0.10",
"yorkie": "^2.0.0"
},
"dependencies": {
<template>
- <button @click="n++">Increment {{ n }}</button>
- <button @click="counter.changeMe()"><code>counter.changeMe()</code></button>
- <pre>{{ counter.$state }}</pre>
- <!-- <button @click="counter.newOne()">Click me</button> -->
- <TestStore />
+ <header>
+ <h1>🍍 Pinia playground</h1>
+ <nav>
+ <template v-for="(page, i) in pages" :key="page.name">
+ <router-link :to="page" v-slot="{ route }">{{
+ route.fullPath
+ }}</router-link>
+ <template v-if="i < pages.length - 1"> · </template>
+ </template>
+ </nav>
+ </header>
+
+ <router-view />
</template>
<script lang="ts" setup>
import { ref } from 'vue'
-import TestStore from './components/TestStore.vue'
+import { useRouter } from 'vue-router'
import { useCounter } from './stores/counter'
-const counter = useCounter()
+const router = useRouter()
-const n = ref(4)
+const pages = router
+ .getRoutes()
+ .filter((route) => !route.meta.hide)
+ .map((route) => ({ name: route.name }))
</script>
<style>
-#app {
- font-family: Avenir, Helvetica, Arial, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- color: #2c3e50;
- margin-top: 60px;
+button {
+ margin-right: 0.5rem;
}
</style>
+++ /dev/null
-<template>
- <p>Counter :{{ counterStore.n }}</p>
-
- <button @click="counterStore.increment">Increment</button>
- <button @click="counterStore.n++">Direct Increment</button>
- <button
- @click="
- counterStore.$patch((state) => {
- state.n++
- state.incrementedTimes++
- })
- "
- >
- Direct patch
- </button>
- <button @click="counterStore.fail">Fail</button>
- <button @click="counterStore.decrementToZero(300, true)">To ZERO</button>
-</template>
-
-<script setup>
-import { useCartStore } from '../stores/cart'
-import { useCounter } from '../stores/counter'
-
-const counterStore = useCounter()
-const cartStore = useCartStore()
-</script>
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from '../../src'
+import { router } from './router'
const pinia = createPinia()
// TODO: HMR for plugins
-createApp(App).use(pinia).mount('#app')
+createApp(App).use(router).use(pinia).mount('#app')
--- /dev/null
+import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
+import kebabcase from 'lodash.kebabcase'
+
+const viewModules = import.meta.glob('./views/*.vue')
+
+const nameFromPath = (path: string) => path.replace(/^.*\/(\w+)\.vue$/, '$1')
+
+const pages: RouteRecordRaw[] = Object.keys(viewModules).map((path) => {
+ const name = nameFromPath(path)
+ return {
+ name,
+ path: name === '404' ? '/:patchMatch(.*)*' : '/' + kebabcase(name),
+ component: viewModules[path],
+ meta: {
+ hide: name === '404',
+ },
+ }
+})
+
+export const router = createRouter({
+ history: createWebHistory(),
+ routes: [...pages],
+})
id: 'counter',
state: () => ({
- n: 8,
+ n: 0,
incrementedTimes: 0,
decrementedTimes: 0,
numbers: [] as number[],
import.meta.hot.data.pinia || oldUseStore._pinia
if (!pinia) {
- console.warn(`Missing the pinia instance for "${oldUseStore.$id}".`)
- return import.meta.hot.invalidate()
+ // this store is still not used
+ return
}
// preserve the pinia instance across loads
import.meta.hot.data.pinia = pinia
- console.log('got data', newStore)
+ // console.log('got data', newStore)
for (const exportName in newStore) {
const useStore = newStore[exportName]
- console.log('checking for', exportName)
+ // console.log('checking for', exportName)
if (isUseStore(useStore) && pinia._s.has(useStore.$id)) {
- console.log('Accepting update for', useStore.$id)
+ // console.log('Accepting update for', useStore.$id)
const id = useStore.$id
if (id !== oldUseStore.$id) {
const existingStore: Store = pinia._s.get(id)!
if (!existingStore) {
console.log(`skipping hmr because store doesn't exist yet`)
- // TODO: replace the useCounter var???
return
}
useStore(pinia, existingStore)
- // remove the existing store from the cache to force a new one
- // pinia._s.delete(id)
- // this adds any new state to pinia and then runs the `hydrate` function
- // which, by default, will reuse the existing state in pinia
- // const newStore = useStore(pinia)
- // console.log('going there', newStore._hmrPayload)
- // pinia._s.set(id, existingStore)
}
}
})
--- /dev/null
+export const ha = 3
--- /dev/null
+<template>
+ <p>Select one of the pages ⤵️</p>
+
+ <ul>
+ <li v-for="page in pages">
+ <router-link v-for="page in pages" :to="page">{{
+ page.name
+ }}</router-link>
+ </li>
+ </ul>
+</template>
+
+<script lang="ts" setup>
+import { useRouter } from 'vue-router'
+
+const router = useRouter()
+
+const pages = router
+ .getRoutes()
+ .filter((route) => !route.meta.hide)
+ .map((route) => ({ name: route.name }))
+</script>
--- /dev/null
+<template>
+ <h2>About</h2>
+
+ <p>A simple about page that does not use any store.</p>
+</template>
--- /dev/null
+<template>
+ <h2>Local variables</h2>
+
+ <button @click="n++">Increment local: {{ n }}</button>
+
+ <h2>Counter Store</h2>
+
+ <p>Counter :{{ counter.n }}</p>
+
+ <p>
+ Increment the Store <br />
+
+ <button @click="counter.increment()">+1</button>
+ <button @click="counter.increment(10)">+10</button>
+ <button @click="counter.increment(100)">+100</button>
+ <button @click="counter.n++">Direct Increment</button>
+ <button
+ @click="
+ counter.$patch((state) => {
+ state.n++
+ state.incrementedTimes++
+ })
+ "
+ >
+ Direct patch
+ </button>
+ </p>
+
+ <p>
+ Other actions <br />
+
+ <label>
+ <input type="checkbox" v-model="usePatch" /> Use Patch when decrementing
+ </label>
+ <br />
+
+ <button @click="counter.fail">Fail</button>
+ <button @click="counter.decrementToZero(300, usePatch)">
+ Decrement to zero
+ </button>
+ <button @click="counter.changeMe()"><code>counter.changeMe()</code></button>
+ </p>
+
+ <hr />
+
+ <p><code>counter.$state</code>:</p>
+
+ <pre>{{ counter.$state }}</pre>
+</template>
+
+<script lang="ts" setup>
+import { ref } from 'vue'
+import { useCounter } from '../stores/counter'
+
+const counter = useCounter()
+const usePatch = ref(true)
+const n = ref(0)
+</script>
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9"
integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==
+"@types/lodash.kebabcase@^4.1.6":
+ version "4.1.6"
+ resolved "https://registry.yarnpkg.com/@types/lodash.kebabcase/-/lodash.kebabcase-4.1.6.tgz#07b07aeca6c0647836de46f87a3cdfff72166c8e"
+ integrity sha512-+RAD9pCAa8kuVyCYTeDNiwBXwD/0u0p+hos3NSqD+tXTjJextbfF3farfYB+ssAKgEssoewXEtBsfwBpsI7gsA==
+ dependencies:
+ "@types/lodash" "*"
+
+"@types/lodash@*":
+ version "4.14.171"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.171.tgz#f01b3a5fe3499e34b622c362a46a609fdb23573b"
+ integrity sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==
+
"@types/markdown-it@^12.0.1":
version "12.0.3"
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.0.3.tgz#60a09363bebbd780fac815442b47d80f1a17bef1"
"@vue/compiler-dom" "npm:@knightly/vue__compiler-dom@3.1.4-knightly-3-2.202107080810"
"@vue/shared" "npm:@knightly/vue__shared@3.1.4-knightly-3-2.202107080810"
-"@vue/devtools-api@^6.0.0-beta.15":
+"@vue/devtools-api@^6.0.0-beta.14", "@vue/devtools-api@^6.0.0-beta.15":
version "6.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.15.tgz#ad7cb384e062f165bcf9c83732125bffbc2ad83d"
integrity sha512-quBx4Jjpexo6KDiNUGFr/zF/2A4srKM9S9v2uHgMXSU//hjgq1eGzqkIFql8T9gfX5ZaVOUzYBP3jIdIR3PKIA==
resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37"
integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=
+lodash.kebabcase@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
+ integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY=
+
lodash@^4.17.15, lodash@^4.7.0, lodash@~4.17.15:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.10.0.tgz#e21cad49e4aee210093de658684f0ba49ae404f1"
integrity sha512-SlVtIkcCVwbSVAiWTk3ixcDF6bRjgPP5nKGjSx4HXmieEUDi2oVQJUQxoFmEOV21js7TKvclzEUhInDEkg0NDQ==
+vue-router@^4.0.10:
+ version "4.0.10"
+ resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.10.tgz#ec8fda032949b2a31d3273170f8f376e86eb52ac"
+ integrity sha512-YbPf6QnZpyyWfnk7CUt2Bme+vo7TLfg1nGZNkvYqKYh4vLaFw6Gn8bPGdmt5m4qrGnKoXLqc4htAsd3dIukICA==
+ dependencies:
+ "@vue/devtools-api" "^6.0.0-beta.14"
+
vue@^3.1.1, "vue@npm:@knightly/vue@3-2":
version "3.1.4-knightly-3-2.202107080810"
resolved "https://registry.yarnpkg.com/@knightly/vue/-/vue-3.1.4-knightly-3-2.202107080810.tgz#ab5818365805d003238df3dce739b5d720663954"