Skip to content

Commit

Permalink
add Multiple store support, add js-cookie support, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
l-x-f committed Mar 31, 2022
1 parent ecb144b commit 6e606ca
Show file tree
Hide file tree
Showing 21 changed files with 2,155 additions and 26 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ app.use(store).mount('#app')
export interface Options {
/**
* storage, default is `window.localStorage`
*
* support `js-cookie` `window.localStorage` `window.sessionStorage`
*/
storage: Storage
storage?: Storage | Cookies
/**
* storage key, default is `pinia`
* storage key prefix, default is `pinia`
*/
key: string
/**
Expand Down
6 changes: 4 additions & 2 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ app.use(store).mount('#app')
export interface Options {
/**
* 存储类型,默认为 `window.localStorage`
*
* 支持 `js-cookie` `window.localStorage` `window.sessionStorage`
*/
storage: Storage
storage?: Storage | Cookies
/**
* 存储的key值,默认为 `pinia`
* 存储的key值前缀,默认为 `pinia`
*/
key: string
/**
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pinia-persistedstate-plugin",
"version": "0.0.8",
"version": "0.0.9",
"description": "A pinia plugin like vuex-persistedstate.",
"types": "dist/index.d.ts",
"license": "MIT",
Expand Down Expand Up @@ -36,6 +36,7 @@
"vite-plugin-dts": "^0.9.4"
},
"dependencies": {
"pinia": "^2.0.3"
"@types/js-cookie": "^3.0.1",
"pinia": "^2.0.12"
}
}
32 changes: 22 additions & 10 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
StateTree
} from 'pinia'

import jsCookies from 'js-cookie'

/**
* Storage类型
*/
Expand All @@ -14,14 +16,15 @@ export interface Storage {
removeItem: (key: string) => void
}

type Cookies = typeof jsCookies
/**
* 配置类型
*/
export interface Options {
/**
* 存储类型,默认为 `window.localStorage`
*/
storage?: Storage
storage?: Storage | Cookies
/**
* 存储的key值,默认为 `pinia`
*/
Expand Down Expand Up @@ -64,8 +67,10 @@ export function createPersistedState(options?: Options): PiniaPlugin {
const logger = options?.logger || false

// 获取state的值
const getState = (key: string, storage: Storage) => {
const value = storage.getItem(key)
const getState = (key: string, storage: Options['storage']) => {
const value = (storage as Storage).getItem
? (storage as Storage).getItem(key)
: (storage as Cookies).get(key)
try {
return typeof value === 'string'
? JSON.parse(value)
Expand All @@ -78,24 +83,31 @@ export function createPersistedState(options?: Options): PiniaPlugin {
}

// 设置state的值
const setState = (key: string, state: StateTree, storage: Storage) =>
storage.setItem(key, JSON.stringify(state))
const setState = (
key: string,
state: StateTree,
storage: Options['storage']
) => {
return (storage as Storage).setItem
? (storage as Storage).setItem(key, JSON.stringify(state))
: (storage as Cookies).set(key, JSON.stringify(state))
}

return (Context: PiniaPluginContext) => {
const store: PiniaPluginContext['store'] = Context.store

// 初始化时获取数据,如果有的话,把原来的pinia的state替换掉
const data = getState(key, storage)
if (data) {
store.$state = data
}
const tempKey = `${key}-${store.$id}`
const data = getState(tempKey, storage)
data && store.$patch(data)

// $subscribe()一个 store的方法来观察 state 和它的变化,类似于 Vuex 的subscribe 方法
store.$subscribe(
(mutation: SubscriptionCallbackMutation<any>, state: StateTree) => {
// 记录日志
logger && logGroup(mutation.storeId, mutation, state)
setState(key, state, storage)
const tempKey = `${key}-${mutation.storeId}`
setState(tempKey, state, storage)
}
)
}
Expand Down
14 changes: 14 additions & 0 deletions tests/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')

module.exports = {
root: true,
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript/recommended'
],
env: {
'vue/setup-compiler-macros': true
}
}
28 changes: 28 additions & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
.DS_Store
dist
dist-ssr
coverage
*.local

/cypress/videos/
/cypress/screenshots/

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
46 changes: 46 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# vue-project

This template should help get you started developing with Vue 3 in Vite.

## Recommended IDE Setup

[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-typescript-vue-plugin).

## Type Support for `.vue` Imports in TS

TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.

If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:

1. Disable the built-in TypeScript Extension
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.

## Customize configuration

See [Vite Configuration Reference](https://vitejs.dev/config/).

## Project Setup

```sh
npm install
```

### Compile and Hot-Reload for Development

```sh
npm run dev
```

### Type-Check, Compile and Minify for Production

```sh
npm run build
```

### Lint with [ESLint](https://eslint.org/)

```sh
npm run lint
```
1 change: 1 addition & 0 deletions tests/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
13 changes: 13 additions & 0 deletions tests/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
31 changes: 31 additions & 0 deletions tests/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "test-pinia-persistedstate-plugin",
"version": "0.0.9",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview --port 5050",
"typecheck": "vue-tsc --noEmit",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
},
"dependencies": {
"js-cookie": "^3.0.1",
"pinia": "^2.0.12",
"vue": "^3.2.31"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.1.0",
"@types/js-cookie": "^3.0.1",
"@types/node": "^16.11.25",
"@vitejs/plugin-vue": "^2.2.2",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^10.0.0",
"@vue/tsconfig": "^0.1.3",
"eslint": "^8.5.0",
"eslint-plugin-vue": "^8.2.0",
"prettier": "^2.5.1",
"typescript": "~4.5.5",
"vite": "^2.8.4",
"vue-tsc": "^0.31.4"
}
}
Binary file added tests/public/favicon.ico
Binary file not shown.
48 changes: 48 additions & 0 deletions tests/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script setup lang="ts">
import { useCounterStore } from './stores/counter'
import { useUserStore } from './stores/user'
const counterStore = useCounterStore()
const userStore = useUserStore()
const add = () => {
counterStore.counter++
}
const add1 = () => {
counterStore.$patch({
counter: counterStore.counter + 1
})
}
const add2 = () => {
counterStore.increment()
}
const addUser = () => {
userStore.data++
}
const addUser1 = () => {
userStore.$patch({
data: userStore.data + 1
})
}
const addUser2 = () => {
userStore.increment()
}
</script>

<template>
<div>
{{ counterStore.counter }}
<button @click="add">add</button>
<button @click="add1">add1</button>
<button @click="add2">add2</button>
</div>

<div style="margin: 100px">
{{ userStore.data }}

<button @click="addUser">add</button>
<button @click="addUser1">addUser1</button>
<button @click="addUser2">addUser</button>
</div>
</template>
18 changes: 18 additions & 0 deletions tests/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { createPersistedState } from '../../src/main'
import App from './App.vue'
import Cookies from 'js-cookie'

const app = createApp(App)
const store = createPinia()

store.use(
createPersistedState({
logger: true,
key: 'my-store',
storage: Cookies
})
)

app.use(store).mount('#app')
16 changes: 16 additions & 0 deletions tests/src/stores/counter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { defineStore } from 'pinia'

export const useCounterStore = defineStore({
id: 'counter',
state: () => ({
counter: 0
}),
getters: {
doubleCount: state => state.counter * 2
},
actions: {
increment() {
this.counter++
}
}
})
13 changes: 13 additions & 0 deletions tests/src/stores/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineStore } from 'pinia'

export const useUserStore = defineStore({
id: 'user',
state: () => ({
data: 100
}),
actions: {
increment() {
this.data++
}
}
})
16 changes: 16 additions & 0 deletions tests/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "@vue/tsconfig/tsconfig.web.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},

"references": [
{
"path": "./tsconfig.vite-config.json"
}
]
}
8 changes: 8 additions & 0 deletions tests/tsconfig.vite-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "@vue/tsconfig/tsconfig.node.json",
"include": ["vite.config.*"],
"compilerOptions": {
"composite": true,
"types": ["node"]
}
}
7 changes: 7 additions & 0 deletions tests/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()]
})
Loading

0 comments on commit 6e606ca

Please sign in to comment.