首页 > 其他分享 >学习Pinia(安装,引入注册Vue3,初始化仓库Store,State值获取修改,解构store,actions,getters,API方法,数据持久化)

学习Pinia(安装,引入注册Vue3,初始化仓库Store,State值获取修改,解构store,actions,getters,API方法,数据持久化)

时间:2022-11-03 16:23:11浏览次数:83  
标签:const getters 解构 current state Pinia Test import store

全局状态管理工具

Pinia.js 有如下特点:

完整的 ts 的支持;
足够轻量,压缩后的体积只有1kb左右;
去除 mutations,只有 state,getters,actions;
actions 支持同步和异步;
代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的
无需手动添加 store,store 一旦创建便会自动添加;
支持Vue3 和 Vue2
官方文档Pinia

git 地址 https://github.com/vuejs/pinia

1.起步 安装

yarn add pinia
 
npm install pinia

  

2.引入注册Vue3

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')

  

Vue2 使用

import { createPinia, PiniaVuePlugin } from 'pinia'
 
Vue.use(PiniaVuePlugin)
const pinia = createPinia()
 
new Vue({
  el: '#app',
  // other options...
  // ...
  // note the same `pinia` instance can be used across multiple Vue apps on
  // the same page
  pinia,
})

 

初始化仓库Store

1.新建一个文件夹Store

2.新建文件[name].ts

3.定义仓库Store

import { defineStore } from 'pinia'

  

4.我们需要知道存储是使用定义的defineStore(),并且它需要一个唯一的名称,作为第一个参数传递

我这儿名称抽离出去了

新建文件store-namespace/index.ts

export const enum Names {
    Test = 'TEST'
}

  

store 引入

import { defineStore } from 'pinia'
import { Names } from './store-namespace'
 
export const useTestStore = defineStore(Names.Test, {
 
})

  

这个名称,也称为id,是必要的,Pania 使用它来将商店连接到 devtools。将返回的函数命名为use...是可组合项之间的约定,以使其使用习惯。

 

5.定义值

State 箭头函数 返回一个对象 在对象里面定义值

import { defineStore } from 'pinia'
import { Names } from './store-namespace'
 
export const useTestStore = defineStore(Names.Test, {
     state:()=>{
         return {
             current:1,
             age:18
         }
     },
     //类似于computed 可以帮我们去修饰我们的值
     getters:{
 
     },
     //可以操作异步 和 同步提交state
     actions:{
 
     }
})

  

State值获取修改

1.修改一个值,可以直接 点 修改值

<template>
     <div>
         <button @click="Add">+</button>
          <div>
             {{Test.current}}
          </div>
     </div>
</template>
 
<script setup lang='ts'>
import {useTestStore} from '../store'
const Test = useTestStore()
const Add = () => {
    Test.current++
}
 
</script>
 
<style>
 
</style>

  

2.批量修改,在他的实例上有$patch方法可以批量修改多个值

<template>
     <div>
         <button @click="Add">+</button>
          <div>
             {{Test.current}}
          </div>
          <div>
            {{Test.age}}
          </div>
     </div>
</template>
 
<script setup lang='ts'>
import {useTestStore} from '../store'
const Test = useTestStore()
const Add = () => {
    Test.$patch({
       current:200,
       age:300
    })
}
 
</script>
 
<style>
 
</style>

  

3.批量修改函数写法

推荐使用函数形式 可以自定义修改逻辑

<template>
     <div>
         <button @click="Add">+</button>
          <div>
             {{Test.current}}
          </div>
          <div>
            {{Test.age}}
          </div>
     </div>
</template>
 
<script setup lang='ts'>
import {useTestStore} from '../store'
const Test = useTestStore()
const Add = () => {
    Test.$patch((state)=>{
       state.current++;
       state.age = 40
    })
}
 
</script>
 
<style>
 
</style>

  

4.通过原始对象改变整个实例

$state您可以通过将store的属性设置为新对象来替换store的整个状态

缺点就是必须修改整个对象的所有属性

<template>
     <div>
         <button @click="Add">+</button>
          <div>
             {{Test.current}}
          </div>
          <div>
            {{Test.age}}
          </div>
     </div>
</template>
 
<script setup lang='ts'>
import {useTestStore} from '../store'
const Test = useTestStore()
const Add = () => {
    Test.$state = {
       current:10,
       age:30
    }    
}
 
</script>
 
<style>
 
</style>

  

5.通过action修改

定义Actions

在actions 中直接使用this就可以指到state里面的值

import { defineStore } from 'pinia'
import { Names } from './store-namespace'

export const useTestStore = defineStore(Names.Test, {
  state: () => {
    return {
      current: 1,
      age: 30
    }
  },

  actions: {
    setCurrent() {
      this.current++
    }
  }

})

  

<template>
     <div>
         <button @click="Add">+</button>
          <div>
             {{Test.current}}
          </div>
          <div>
            {{Test.age}}
          </div>
     </div>
</template>
 
<script setup lang='ts'>
import {useTestStore} from '../store'
const Test = useTestStore()
const Add = () => {
     Test.setCurrent()
}
 
</script>
 
<style>
 
</style>

  

解构store

在Pinia是不允许直接解构要不会失去响应性的

const Test = useTestStore()
 
const { current, name } = Test
 
console.log(current, name);

 

差异对比

修改Test current 解构完之后的数据不会变

而源数据是会变的

<template>
  <div>origin value {{Test.current}}</div>
  <div>
    pinia:{{ current }}--{{ name }}
    change :
    <button @click="change">change</button>
  </div>
</template>
  
<script setup lang='ts'>
import { useTestStore } from './store'
 
const Test = useTestStore()
 
const change = () => {
   Test.current++
}
 
const { current, name } = Test
 
console.log(current, name);
 
 
</script>
  
<style>
</style>

  

解决方案可以使用 storeToRefs

import { storeToRefs } from 'pinia'
 
const Test = useTestStore()
 
const { current, name } = storeToRefs(Test)  

其原理跟toRefs 一样的给里面的数据包裹一层toref

 

Actions,getters

Actions(支持同步异步)

1.同步 直接调用即可

import { defineStore } from 'pinia'
import { Names } from './store-namespace'

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>
 
<style>
 
</style>

  

2.异步 可以结合async await 修饰

import { defineStore } from 'pinia'
import { Names } from './store-namespace'

type Result = {
  name: string
  isChu: boolean
}

const Login = (): Promise<Result> => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        name: '小满',
        isChu: true
      })
    }, 2000)
  })
}


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>
 
<style>
 
</style>

  

3.多个action互相调用getLoginInfo  setName

    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

1.使用箭头函数不能使用this this指向已经改变指向undefined 修改值请用state

主要作用类似于computed 数据修饰并且有缓存

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

  

2.普通函数形式可以使用this

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

  

3.getters 互相调用

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

  

Pinia API

1.$rest

重置store到他的初始状态

state: () => ({
     user: <Result>{},
     name: "default",
     current:1
}),

  

Vue 例如我把值改变到了10

const change = () => {
     Test.current++
}

  

调用$reset();

将会把state所有值 重置回 原始状态

 

2.订阅state的改变

类似于Vuex 的abscribe  只要有state 的变化就会走这个函数

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

  

 

 

 

第二个参数

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

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

  

3.订阅Actions的调用

 只要有actions被调用就会走这个函数

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

  

 

 

pinia持久化

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

可以利用localStorage和sessionStorage存储

 

 


————————————————
版权声明:本文为CSDN博主「小满zs」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq1195566313/article/details/123338137

标签:const,getters,解构,current,state,Pinia,Test,import,store
From: https://www.cnblogs.com/xiaobaibubai/p/16854706.html

相关文章

  • Pinia在请求中无法获取函数的报错
    //在*.ts/js文件中使用pinia报错解决方法(未删减完全)//文件路径srcstore-index.ts-user.store.ts-user.store.tsrouter-index.ts//使用......
  • 【JEECG】Vue3-03Pinia详细使用教程
    1、安装npminstallpinia或yarnaddpinia2、引用import{createApp}from'vue'importAppfrom'./App.vue'import{createPinia}from'pinia'constpinia=create......
  • js 变量作用域与解构赋值| 22
    在JavaScript中,用​​var​​申明的变量实际上是有作用域的。如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量:'usestrict';functionf......
  • 解构赋值
    //数组解构constf4=[小白,小黄,小黑,小花];let[bai,huang,hei,hua]=f4;console.log(bai);console.log(huang);......
  • Pinia
    介绍PiniaPinia.js有如下特点:完整的ts的支持;足够轻量,压缩后的体积只有1kb左右;去除mutations,只有state,getters,actions;actions支持同步和异步;代码扁平化没有模......
  • 【ES6】let、const关键字和解构赋值
    ......
  • pinia - 为 antdv 表格添加加载状态
    前言我们之前制作的Vue3+AntDesignVue+SpringBoot的增删改查小Demo的功能已经全部实现了,但是还是有一点不完美,在发送请求到后端返回数据这一段时间内前台未做任......
  • vue3 + pinia实现简单购物车功能
    这个小例子是学习vue3与pinia状态管理工具时写的一个简单的购物车功能,它实现了从模拟接口(node.js的json-server提供)读取商品数据,到添加商品到购物车和购物车中删除商品......
  • Vite + Vue3 + Pinia + es6 + TypeScript 搭建项目
    vite中文参考文档:​​https://vitejs.cn/guide/#scaffolding-your-first-vite-project​​执行 npminitvite@latest步骤如下图:下载依赖npmi 启动项目:npmrundev......
  • ES6中新增的解构语法
    对象的解构将对象中对应名字的值赋值给同名的变量   !!注意点:对象的解构必须是变量名和对象中的属性名同名才可以解构对象的解构的优点:"可以快速的将对象中赋......