# yll_vuex_cache
**Repository Path**: yll10243/yll_vuex_cache
## Basic Information
- **Project Name**: yll_vuex_cache
- **Description**: vuex4.0的缓存的插件,vue3.x+vite2.x+ts的版本
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-02-17
- **Last Updated**: 2022-02-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 基于vuex-persist的二次修改,ts的版版本
兼容vite-vue3.x的ts的strict为true
### 使用步骤
- 安装依赖包
```
npm install yll_vuex_cache --save
```
- 在store中配置插
```ts
# src/store/index.ts
import { createStore, createLogger } from 'vuex'
import VuexPersistence from "yll_vuex_cache"
const vuexLocal = new VuexPersistence({
storage: window.localStorage
})
const store = createStore({
state() {
return {
count: 0
}
},
mutations: {
increment(state: any) {
state.count++
}
},
plugins: [vuexLocal.plugin]
})
export default store
```
- 在main.js中引入
```ts
import { createApp } from 'vue'
import App from './App.vue'
import Store from "./store/index" //vuex的引入并挂载
const app = createApp(App)
app.use(Store)
app.mount('#app')
```
- 在vue中使用
```ts
```
### Constructor Parameters -
When creating the VuexPersistence object, we pass an `options` object
of type `PersistOptions`.
Here are the properties, and what they mean -
| Property | Type | Description |
| --------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| key | string | The key to store the state in the storage
_**Default: 'vuex'**_ |
| storage | Storage (Web API) | localStorage, sessionStorage, localforage or your custom Storage object.
Must implement getItem, setItem, clear etc.
_**Default: window.localStorage**_ |
| saveState | function
(key, state[, storage]) | If not using storage, this custom function handles
saving state to persistence |
| restoreState | function
(key[, storage]) => state | If not using storage, this custom function handles
retrieving state from storage |
| reducer | function
(state) => object | State reducer. reduces state to only those values you want to save.
By default, saves entire state |
| filter | function
(mutation) => boolean | Mutation filter. Look at `mutation.type` and return true
for only those ones which you want a persistence write to be triggered for.
Default returns true for all mutations |
| modules | string[] | List of modules you want to persist. (Do not write your own reducer if you want to use this) |
| asyncStorage | boolean | Denotes if the store uses Promises (like localforage) or not (you must set this to true when using something like localforage)
_**Default: false**_ |
| supportCircular | boolean | Denotes if the state has any circular references to itself (state.x === state)
_**Default: false**_ |
### Usage Notes
#### Reducer
Your reducer should not change the shape of the state.
```javascript
const persist = new VuexPersistence({
reducer: (state) => state.products,
...
})
```
Above code is **wrong**
You intend to do this instead
```js
const persist = new VuexPersistence({
reducer: (state) => ({products: state.products}),
...
})
```
#### Circular States
If you have circular structures in your state
```js
let x = { a: 10 }
x.x = x
x.x === x.x.x // true
x.x.x.a === x.x.x.x.a //true
```
`JSON.parse()` and `JSON.stringify()` will not work.
You'll need to install `flatted`
```
npm install yll_jsonparser
```
And when constructing the store, add `supportCircular` flag
```js
new VuexPersistence({
supportCircular: true,
...
})
```
## Examples
### Simple
Quick example -
```typescript
import { createApp } from "vue";
import { createStore } from "vuex";
import VuexPersistence from 'vuex-persist'
const App = createApp({});
const store = createStore({
state: {
user: { name: 'Arnav' },
navigation: { path: '/home' }
},
plugins: [new VuexPersistence().plugin]
})
App.use(store)
export default store
```
### Detailed
Here is an example store that has 2 modules, `user` and `navigation`
We are going to save user details into a Cookie _(using js-cookie)_
And, we will save the navigation state into _localStorage_ whenever
a new item is added to nav items.
So you can use multiple VuexPersistence instances to store different
parts of your Vuex store into different storage providers.
**Warning:** when working with modules these should be registered in
the Vuex constructor. When using `store.registerModule` you risk the
(restored) persisted state being overwritten with the default state
defined in the module itself.
```typescript
import { createApp } from "vue";
import { createStore, Payload } from 'vuex'
import VuexPersistence from 'vuex-persist'
import Cookies from 'js-cookie'
import { module as userModule, UserState } from './user'
import navModule, { NavigationState } from './navigation'
export interface State {
user: UserState
navigation: NavigationState
}
const App = createApp({});
const vuexCookie = new VuexPersistence({
restoreState: (key, storage) => Cookies.getJSON(key),
saveState: (key, state, storage) =>
Cookies.set(key, state, {
expires: 3
}),
modules: ['user'], //only save user module
filter: (mutation) => mutation.type == 'logIn' || mutation.type == 'logOut'
})
const vuexLocal = new VuexPersistence({
storage: window.localStorage,
reducer: (state) => ({ navigation: state.navigation }), //only save navigation module
filter: (mutation) => mutation.type == 'addNavItem'
})
const store = createStore({
modules: {
user: userModule,
navigation: navModule
},
plugins: [vuexCookie.plugin, vuexLocal.plugin]
})
App.use(store)
export default store
```
### Support Strict Mode
This now supports [Vuex strict mode](https://vuex.vuejs.org/guide/strict.html)
(Keep in mind, **NOT** to use strict mode in production)
In strict mode, we cannot use `store.replaceState` so instead we use a mutation
You'll need to keep in mind to add the **`RESTORE_MUTATION`** to your mutations
See example below
To configure with strict mode support -
```typescript
import { createApp } from "vue";
import { createStore, Payload } from 'vuex'
import VuexPersistence from 'vuex-persist'
const App = createApp({});
const vuexPersist = new VuexPersistence({
strictMode: true, // This **MUST** be set to true
storage: localStorage,
reducer: (state) => ({ dog: state.dog }),
filter: (mutation) => mutation.type === 'dogBark'
})
const store = createStore({
strict: true, // This makes the Vuex store strict
state: {
user: {
name: 'Arnav'
},
foo: {
bar: 'baz'
}
},
mutations: {
RESTORE_MUTATION: vuexPersist.RESTORE_MUTATION // this mutation **MUST** be named "RESTORE_MUTATION"
},
plugins: [vuexPersist.plugin]
})
App.use(store)
```
Some of the most popular ways to persist your store would be -
- **[js-cookie](https://npmjs.com/js-cookie)** to use browser Cookies
- **window.localStorage** (remains, across PC reboots, untill you clear browser data)
- **window.sessionStorage** (vanishes when you close browser tab)
- **[localForage](http://npmjs.com/localforage)** Uses IndexedDB from the browser
### Note on LocalForage and async stores
There is Window.Storage API as defined by HTML5 DOM specs, which implements the following -
```typescript
interface Storage {
readonly length: number
clear(): void
getItem(key: string): string | null
key(index: number): string | null
removeItem(key: string): void
setItem(key: string, data: string): void
[key: string]: any
[index: number]: string
}
```
As you can see it is an entirely synchronous storage. Also note that it
saves only string values. Thus objects are stringified and stored.
Now note the representative interface of Local Forage -
```typescript
export interface LocalForage {
getItem(key: string): Promise
setItem(key: string, data: T): Promise
removeItem(key: string): Promise
clear(): Promise
length(): Promise
key(keyIndex: number): Promise
_config?: {
name: string
}
}
```
You can note 2 differences here -
1. All functions are asynchronous with Promises (because WebSQL and IndexedDB are async)
2. It works on objects too (not just strings)
I have made `vuex-persist` compatible with both types of storages, but this comes at a slight cost.
When using asynchronous (promise-based) storages, your state will **not** be
immediately restored into vuex from localForage. It will go into the event loop
and will finish when the JS thread is empty. This can invoke a delay of few seconds.