Pinia轻量级状态管理

1.1核心概念

vuex中有四个核心概念:

  • State
  • Getters
  • Mutaions
  • Actions

在Pinia中:

  • State
  • Getters
  • Actions 同步异步都支持

1.2基本示例

// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  // could also be defined as
  // state: () => ({ count: 0 })
  actions: {
    increment() {
      //在vuex中我们需要搞两步
      //1.定义mutations
      //2.提交mutations
      this.count++
    },
  },
})

然后在组件中使用它:

import { useCounterStore } from '@/stores/counter'

export default {
  setup() {
    const counter = useCounterStore()

    counter.count++
    // with autocompletion ✨
    counter.$patch({ count: counter.count + 1 })
    // or using an action instead
    counter.increment()
  },
} 

1.3Pinia vs Vuex

2.快速入门

2.1安装

yarn add pinia
# or with npm
npm install pinia

2.2初始化配置

Vue3:

import { createPinia } from 'pinia'

app.use(createPinia())

Vue2:
如果您使用的是 Vue 2,您还需要安装一个插件并pinia在应用程序的根目录插入创建的插件:

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,
})

2.3用vite来创建一个项目

1.下载vite

npm init vite@latest

2.创建项目名
pinia-examples

3.选择vue

4.用ts还是不用
选择vue-ts

5.npm install pinia

6.打开main.ts

import { createApp } from 'vue'
import App from './App.vue'
import { createPinia} from 'pinia'

//创建Pinia实例
const pinia=createPinia()

const app=createApp(App)

//挂载到Vue根实例
app.use(pinia)

app.mount('#app')

7.创建src\store\index.ts文件

import { defineStore}from 'pinia'

// 1.定义并导出容器
//参数1:容器的ID,必须唯一,将来Pinia会把所有的容器挂载到根容器
//参数2:选项对象
//返回值:
export const useMainStore=defineStore('main',{
    /*
    类似于组件的data,用来存储全局状态的
    1.必须是函数:这样是为了在服务端渲染的时候避免交叉请求导致的数据状态污染
    2.必须是箭头函数,这是为了更好的TS类型推导
    */
    state:()=>{
        return {
            count:100,
            foo:'bar',
            arr:[1,2,3]
        }
    },
    // 类似于组件的computed,用来封装计算属性,有缓存的功能
    //函数接受一个可选参数,state状态对象
    getters:{
        count10(state){
            console.log('count10 调用了')
            return state.count+10
        }
        //如果再getters中使用了this,则必须手动指定返回值的类型,否则类型推导不出来
        // count10(): number{
        //     console.log('count10 调用了')
        //     return this.count+10
        // }
    },
    // 类似于组件的methods,封装业务逻辑,修改state
    actions:{
        //注意:不能使用箭头函数定义,因为箭头函数绑定外部this
        changeState(){
            //优化前
            // this.count++
            // this.foo='hello'
            // this.arr.push(4)
            //优化后,批量更新
            //如果涉及数据比较多,则推荐使用仓库实例的$patch方法,
            //批量修改,虽然看起来和前面的几乎没有区别,但是会加快修改速度,
            //对程序的性能有很大的好处。$patch传入一个对象,对象的属性就是各种状态
            this.$patch(state=>{
                state.count++
                state.foo='hello'
                state.arr.push(4)
            })
        } 
    }
})

8.修改HelloWorld.vue

<template>
    <p>{{mainStore.count}}</p>
    <p>{{mainStore.foo}}</p>
    <p>{{mainStore.arr}}</p>
    <p>{{mainStore.count10}}</p>
    <p>{{mainStore.count10}}</p>
    <p>{{mainStore.count10}}</p>
    <hr>
    <p>{{count}}</p>
    <p>{{foo}}</p>
    <hr>

    <p>
      <button @click="handleChangeState">修改数据</button>
    </p>
</template>

<script lang="ts" setup>
import {storeToRefs} from 'pinia'
import {useMainStore} from '../store'

const mainStore=useMainStore()
console.log(mainStore.count)

//这是有问题的,因为这样拿到的数据不是响应式的,是一次性的
//Pinia 其实就是把state数据都做了reactive处理了
//const {count,foo}=mainStore

//解决办法就是使用
//把结构出来的数据做ref响应式代理
const {count,foo}=storeToRefs(mainStore)

const handleChangeState=()=>{
  //方式一:
  //mainStore.count++
  //mainStore.foo='hello'

  //方式二:如果需要修改多个数据,建议使用$patch批量更新
  // mainStore.$patch({
  //     count:mainStore.count+1,
  //     foo:'hello',
  //     arr:[...mainStore.arr,4]
  // })

  //方式三:更好的批量更新的方式: $patch 一个函数
  // mainStore.$patch(state=>{
  //     state.count++
  //     state.foo='hello'
  //     state.arr.push(4)
  // })

  //方式四:逻辑比较多的时候可以封装到actions做处理
  mainStore.changeState()
}

</script>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bruce-li__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值