首页 > 其他分享 >【Vue3.x】pinia

【Vue3.x】pinia

时间:2022-10-08 17:24:41浏览次数:46  
标签:const name state pinia Vue3 Test store

Pinia

Vue3中使用Pinia替代vuex

更改如下:

  • 支持ts
  • 体积小,压缩后1KB
  • 去除 mutations,只有 state,getters,actions;
  • 去除mutations后,actions 直接进行同步和异步操作修改数据
  • 去除modules概念,只有store概念,每个store都是独立的
  • 无需手动添加store,一旦创建则会自动添加

安装 npm i pinia

Vue3中注册pinia

import { createApp } from 'vue'
import App from './App.vue'
import {createPinia} from 'pinia'
 
const store = createPinia()
let app = createApp(App)
 
app.use(store)
 
app.mount('#app')

初试化仓库store

1.新建两个文件

src/store/store-name.ts 负责抽离仓库名字,管理仓库名字

export const enum Names {
    Test1 = 'TEST1'
    Test2 = 'TEST2'
    Test3 = 'TEST3'
}

src/store/index.ts store仓库核心代码

// defineStore()为定义仓库,第一个参数为仓库的ID,第二个参数仓库对象
import { defineStore } from 'pinia'
import { Names } from './store-name'
 
// 仓库名字定义为useXXX
export const useTestStore = defineStore(Names.Test1, {
    // 提示可知state必须是箭头函数类型(actions和getters为对象)
     state:()=>{
         return {
             current:1
         }
     },
     //类似于computed 可以帮我们去修饰我们的值
     getters:{
 
     },
     //可以操作异步 和 同步提交state,无需mutations
     actions:{
 
     }
})

在组件中利用使用以下五种方法修改

import { useTestStore } from "./store";
const Test = useTestStore()
  1. 直接修改state

Test.current++

  1. 仓库实例$patch方法批量修改
  Test.$patch({
    current:9,
    name:'a'
  })
  1. 仓库实例$patch方法批量修改,函数形式
  Test.$patch((state)=>{
    state.current = 10
    state.name = 'b'
  })
  1. 仓库实例$state替换整个实例,必须修改所有书序
  Test.$state = {
    current:2000,
    name:'小满娃娃'
  }
  1. 通过actions修改
    // 仓库里acitons定义方法
    actions:{
        setCurrent(num:number){
            this.current = num
        }
    }
    // 组件直接调用
    Test.setCurrent(567)

解构store

直接解构store里的属性,将会失去响应性

const Test = useTestStore()

const { current, name } = Test

console.log(current, name);

可以在解构前给仓库包裹一层storeToRefs()

import { storeToRefs } from 'pinia'

const Test = useTestStore()

const { current, name } = storeToRefs(Test)

Actions,getters

Actions同步调用

import { defineStore } from 'pinia'
import { Names } from './store-naspace'
export const useTestStore = defineStore(Names.TEST, {
    state: () => ({
        counter: 0,
    }),
    actions: {
        increment() {
            this.counter++
        },
        randomizeCounter() {
            this.counter = Math.round(100 * Math.random())
        },
    },
})
<template>
     <div>
         <button @click="Add">+</button>
          <div>
             {{Test.counter}}
          </div>    
     </div>
</template>
 
<script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {
     Test.randomizeCounter()
}
</script>

Actions异步调用,结合async 和 await

import { defineStore } from 'pinia'
import { Names } from './store-naspace'
 
type Result = {
    name: string
    isChu: boolean
}
 
const Login = (): Promise<Result> => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve({
                name: '小满',
                isChu: true
            })
        }, 3000)
    })
}
 
export const useTestStore = defineStore(Names.TEST, {
    state: () => ({
        user: <Result>{},
        name: "123"
    }),
    actions: {
        async getLoginInfo() {
            const result = await Login()
            this.user = result;
        }
    },
})
<template>
     <div>
         <button @click="Add">test</button>
          <div>
             {{Test.user}}
          </div>    
     </div>
</template>
 
<script setup lang='ts'>
import {useTestStore} from './store'
const Test = useTestStore()
const Add = () => {
     Test.getLoginInfo()
}
 
</script>

多个actions调用

  state: () => ({
        user: <Result>{},
        name: "default"
    }),
    actions: {
        async getLoginInfo() {
            const result = await Login()
            this.user = result;
            this.setName(result.name)
        },
        setName (name:string) {
            this.name = name;
        }
    },

getters的作用类似于computed数据修饰并且有缓存

使用箭头函数不能使用this,请使用state

    getters:{
       newPrice:(state)=>  `$${state.user.price}`
    },

普通函数形式使用this

    getters:{
       newCurrent ():number {
           return ++this.current
       }
    },

getters互相调用

    getters:{
       newCurrent ():number | string {
           return ++this.current + this.newName
       },
       newName ():string {
           return `$-${this.name}`
       }
    },

API

$reset,重置store到初始状态

state: () => ({
     user: <Result>{},
     name: "default",
     current:1
})
const change = () => {
     Test.current++
}
const change = () => {
     Test.$reset()
}

订阅state的改变,只要有state 的变化就会走这个函数

Test.$subscribe((args,state)=>{
   console.log(args,state);
   
})

如果你的组件卸载之后还想继续调用请设置第二个参数

Test.$subscribe((args,state)=>{
   console.log(args,state);
   
},{
  detached:true
})

订阅Actions的调用, 只要有actions被调用就会走这个函数

Test.$onAction((args)=>{
   console.log(args);
   
})

pinia持久化插件

pinia 和 vuex 都有一个通病 页面刷新状态会丢失

const __piniaKey = '__PINIAKEY__'
//定义兜底变量
 
 
type Options = {
   key?:string
}
//定义入参类型
 
 
 
//将数据存在本地
const setStorage = (key: string, value: any): void => {
 
localStorage.setItem(key, JSON.stringify(value))
 
}
 
 
//存缓存中读取
const getStorage = (key: string) => {
 
return (localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key) as string) : {})
 
}
 
 
//利用函数柯丽华接受用户入参
const piniaPlugin = (options: Options) => {
 
//将函数返回给pinia  让pinia  调用 注入 context
return (context: PiniaPluginContext) => {
 
const { store } = context;
 
const data = getStorage(`${options?.key ?? __piniaKey}-${store.$id}`)
 
store.$subscribe(() => {
 
setStorage(`${options?.key ?? __piniaKey}-${store.$id}`, toRaw(store.$state));
 
})
 
//返回值覆盖pinia 原始值
return {
 
...data
 
}
 
}
 
}
 
 
//初始化pinia
const pinia = createPinia()
 
 
//注册pinia 插件
pinia.use(piniaPlugin({
 
key: "pinia"
 
}))

标签:const,name,state,pinia,Vue3,Test,store
From: https://www.cnblogs.com/wanglei1900/p/16769572.html

相关文章

  • Vue3 项目在 H5 + ios 环境中,input 输入框在输入中文未选中汉字时会触发 chang 事件,导
    省流版:看解决3环境vue3+vant+H5需求input输入框为验证码(隐含需求:用户接收到验证码时,需要复制验证码后可以点击输入法的联想词直接输入验证码,且需要仅能输入英文......
  • vue3 导出excel文件
    在中后台页面的开发中少不了excel表格导出功能,以此做个记录:1.后端返回下载地址:直接:window.open("文件地址")    或者:window.location.href= "文件地址"......
  • #yyds干货盘点#Vue3的reactive
    最近一阶段在学习Vue3,Vue3中用 ​​reactive​​、​​ref​​ 等方法将数据转化为响应式数据,在获取时使用 ​​track​​ 往 ​​effect​​ 中收集依赖,在值改变时,使......
  • vue3学习笔记
    1.官方介绍Vue(读音/vjuː/,类似于view)是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层......
  • 如何开发一款基于 vite+vue3 的在线表格系统(下)
    在上篇内容中我们为大家分享了详细介绍Vue3和Vite的相关内容。在本篇中我们将从项目实战出发带大家了解Vite+Vue3的在线表格系统的构建。使用Vite初始化Vue3项目在这里需......
  • vite创建vue3+ts项目
    vite创建vue3+ts项目为何选择vite:vite是一个基于Vue3单文件组件的非打包开发服务器,它做到了本地快速开发启动:快速的冷启动,不需要等待打包操作;即时的热模块更新,替换性能......
  • Vue3移动端组件库Varlet源码主题阅读之一:本地启动服务时都做了什么
    本文为Varlet组件库源码主题阅读系列第一篇Vue开源的组件库有很多,基本各个大厂都会做一个,所以作为个人再重复造轮子其实意义也不是很大,但是笔者对于如何设计一个Vue组件......
  • 【Vue3.x】自定义hooks
    Vue3hooksvue2里的mixins相似,但是mixins会组件的配置项覆盖。vue3使用了自定义hooks替代mixnins,hooks本质上是函数,引入调用。封装自定义的hooks将图片转化成base64im......
  • 【Vue3.x】自定义指令directive
    自定义指令directive不同于vue2指令bindinsertedupdatecomponentUpdatedunbind1.vue3指令中的钩子函数created元素初始化的时候beforeMount指令绑定到元素后......
  • Vue3使用可重复使用的Mixins
     这里有两个子页面是重复功能的,一个是点击事件,一个是鼠标移入事件点击事件  鼠标移入事件  效果      现在使用mixins新键一个文件夹minxs,再......