Pinna的使用以及pinna的持续化存储(两种方法)

Pinna的使用以及pinna的持续化存储(两种方法)Pinna_vuepinna

一、简介

pinia是 vue3 新的状态管理工具,简单来说相当于之前 vuex,它去掉了 Mutations 但是也是支持 vue2 的,需要的朋友可以参考下

二、使用方法

1.安装

npm install pinia -S

2..引入

import { createPinia,PiniaPluginContext } from ‘pinia’

import { createApp,toRaw } from ‘vue’

import App from ‘./App.vue’

const store = createPinia()

const app  = createApp(App)

app.use(store)

app.mount(‘#app’)

3.创建store文件夹

在src目录下面,创建store文件

注意: pinia 不需要创建 modules 文件来区分模块化,这是它和 vuex 的区别。

Pinna的使用以及pinna的持续化存储(两种方法)

 store/index.ts

import {defineStore } from 'pinia'
import {Names} from './store-name'
type User = {
    name:string,
    age:number
}

const result:User = {
    name:'xiaochen',
    age:888,
}

const asyncResult:User ={
    name:'异步名字',
    age:999,
}

const Login = ():Promise<User> =>{
    return new Promise((resolve) =>{
        setTimeout(()=>{
            resolve(asyncResult)
        },2000)
    })
}
//第一个参数 命名空间唯一值
export const useTestStore = defineStore(Names.TEST,{
    state:()=>{
        return{
            current:122,
            name:'xiaochen2',
            user:<User>{},
            asyncUser:<User>{},
        }
    },
    //相当于computed 修饰一些值 有缓存的
    getters:{
        newName ():string{
            return `$-${this.name}-${this.getUserAge}`
        },
        getUserAge():number{
            return this.user.age || 1
        }
    },
    //methods 可以做同步 异步也支持 提交state
    actions:{
        // setCurrent(num:number){
        //     this.current = num
        // },
        //同步
        setUser(){
            this.user = result
        },
        //异步
        async getUser(){
            const resultList = await Login()
            this.asyncUser = resultList
            this.setName('超级帅的飞机')//相互调用方法
            this.setAge(6666)//相互调用方法
        },
        setName (name:string){
            this.name = name
        },
        setAge (age:number){
            this.user.age = age
        }
    }

}) 

命名空间的唯一值

export const enum Names {
    TEST = 'TEST',
    BASE = 'BASE'
}

 

4.使用Pinia

import { useTestStore} from “../store”;

const sinaTest = useTestStore();

5.修改数据(五种方法)

方法1:直接改变

<div class=”container”>

    Pinia:{
{ sinaTest.current }} — {
{ sinaTest.name }}

    <button @click=”change”>改变</button>

</div>

const change = () => {

  sinaTest.current++;

};

方法2:利用patch直接改变

const change = () => {

  sinaTest.$patch({

    current: 888,

    name: “黑丝”,

  });

};

方法3:利用$patch传递参数

const change = () => {

  //可以写工厂函数

  sinaTest.$patch((state) => {

    state.current = 999;

    state.name = “迪丽热巴”;

  });

};

方法4: 利用$state修改(有弊端不推荐)

const change = () => {

  //可以写工厂函数

  sinaTest.$state = {

    current: 2000,

    name: “134”,

  };

};

方法5: 通过actions去改变

const change = () => {

  sinaTest.setCurrent(852);

};

这里只是简单了一些修改的方法 ,具体使用还是得结合业务场景去使用,具体了解可以看看Pinia官方文档

三、持久化存储

pinia 和 vuex 一样,数据是短时的,只要一刷新页面,数据就会恢复成初始状态,为了避免这个问题,可以对其采用持久化保存方法。

持久化保存的原理是在 pinia 中数据更新时,同步保存到 localStorage 或 sessionStorage 中,刷新后从本地存储中读取数据,

下面介绍两种实现的方法

一:手写

1.自己手写一个实现持久化(在main.ts写)

首先我们先了解一下pinpa能获取到的参数

Pinna的使用以及pinna的持续化存储(两种方法)

Pinna的使用以及pinna的持续化存储(两种方法)

通过上面的打印我们了解到对应的数据存在哪里,我们即可以手写

//先手写我们存储数据的localStorage
const getStorage = (key:string) =>{
    return localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key) as string):{}
 }

 //存储数据
 const setStorage = (key:string,value:any) => {
    localStorage.setItem(key,JSON.stringify(value)) //value可能是对象或者数组 所以JSON.stringify需要这个转换成字符串 ['1','2','3'] => '['1','2','3']'
  }

 2.手写我们插件函数(柯里化优化):柯里化就是将一个多参数的函数  转换成单参数的函数

解析:options?.key ??__piniaKey__          当key不传的时候默认是__piniaKey__ ,传的时候就是传的数据。下面使用的时候有介绍

空值合并运算符( ?? )是一个逻辑操作符,如果左侧的表达式为 null或者 undefined 时,返回其右侧表达式,否则返回左侧表达式。

//函数柯里化  柯里化就是将一个多参数的函数  转换成单参数的函数
const piniaPlugin = (options:Options) =>{
   return (context:PiniaPluginContext)=>{ //拿取到pinpa的参数
    console.log('context',context);
    const {store} = context //解构我们需要的store
    const data = getStorage(`${options?.key ??__piniaKey__}-${store.$id}`) //获取到key
    console.log('data',data);
    //可以通过$subscribe监测到store数据变化
    store.$subscribe(()=>{
        // 每当它发生变化时,将整个状态持久化到本地存储
        //${options?.key ??__piniaKey__}-${store.$id} 唯一值key
        setStorage(`${options?.key ??__piniaKey__}-${store.$id}`,toRaw(store.$state)) //store.$state proxy对象  toRaw把它转为原始对象
    })
    return{
        ...data
    }
   }
}

3.使用我们的插件

store.use(piniaPlugin({
    key:'pinia' //传值key过去 存储用这个名字
}))

4.效果如下

Pinna的使用以及pinna的持续化存储(两种方法)

 二、使用插件

1.安装插件

npm install pinia-plugin-persist

2.引入插件

import piniaPersist from ‘pinia-plugin-persist’

pinia.use(piniaPersist)

3.使用插件

设置key,指定保存内容

export const useBaseStore = defineStore(Names.BASE, {
  state: () => {
    return {
      baseUrl: "http://localhost:9090",
      BaseCurrent: 0,
    };
  },
  persist: {
    enabled: true, // true 表示开启持久化保存
    strategies: [
      {
        key: 'base',
        storage: localStorage,
        paths: ['BaseCurrent','baseUrl']
      },
    ],
  },
  //相当于computed 修饰一些值 有缓存的
  getters: {},
  //methods 可以做同步 异步也支持 提交state
  actions: {},
}); //第一个参数 命名空间唯一值

②你甚至可以对不同数据设置不同的本地存储方式。

export const useBaseStore = defineStore(Names.BASE, {
  state: () => {
    return {
      baseUrl: "http://localhost:9090",
      BaseCurrent: 0,
      testType:'test',
    };
  },
  persist: {
    enabled: true, // true 表示开启持久化保存
    strategies: [
      {
        key: 'base',
        storage: localStorage,
        paths: ['BaseCurrent','baseUrl']
      },
      {
        key: 'base2',
        storage: sessionStorage,
        paths: ['testType']
      },
    ],
  },
  //相当于computed 修饰一些值 有缓存的
  getters: {},
  //methods 可以做同步 异步也支持 提交state
  actions: {},
}); //第一个参数 命名空间唯一值

         

Pinna的使用以及pinna的持续化存储(两种方法)

③保存到 cookie

保存到 cookie 中当然也是可以的,不过需要手动添加 cookie 的保存方式,同样,此处也是推荐使用插件 js-cookie 来完成。一般用于存储token

npm install js-cookie

 

import Cookies from 'js-cookie'
//存储在cookie
const cookiesStorage: Storage = {
  setItem(key, state:any) {
    console.log('state',state);
    return Cookies.set(key, state, { expires: 3 }); // 设置有效期 3 天,不设置默认同 sessionStorage 有效期一致
  },
  getItem(key) {
    return JSON.stringify({
      accessToken: Cookies.get(key),
    });
  },
  length: 0,
  clear: function (): void {
    throw new Error("Function not implemented.");
  },
  key: function (index: number): string | null {
    throw new Error("Function not implemented.");
  },
  removeItem: function (key: string): void {
    throw new Error("Function not implemented.");
  }
}

export const useBaseStore = defineStore(Names.BASE, {
  state: () => {
    return {
      baseUrl: "http://localhost:9090",
      BaseCurrent: 0,
      testType:'test',
      token:'12314',
    };
  },
  persist: {
    enabled: true, // true 表示开启持久化保存
    strategies: [
      {
        key: 'base',
        storage: localStorage,
        paths: ['BaseCurrent','baseUrl']
      },
      {
        key: 'base2',
        storage: sessionStorage,
        paths: ['testType']
      },
      {
        key: 'tokenSave',
        storage: cookiesStorage,
        paths: ['token']
      },
    ],
  },
  //相当于computed 修饰一些值 有缓存的
  getters: {},
  //methods 可以做同步 异步也支持 提交state
  actions: {},
}); //第一个参数 命名空间唯一值

Pinna的使用以及pinna的持续化存储(两种方法)

 

今天的文章Pinna的使用以及pinna的持续化存储(两种方法)分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/83334.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注