vue3--pinia详解

pinia介绍

  1. 更简洁的 APIPinia 的 API 设计得更加简洁和直观,使得状态管理更加容易理解和使用。与 Vuex 相比,Pinia 减少了样板代码,使得状态的定义和使用更加直接。
  2. 模块化Pinia 支持模块化的状态管理,允许你将状态逻辑组织到不同的模块中。每个模块可以包含自己的状态、getter、动作(actions)和插件,这有助于保持代码的组织性和可维护性。
  3. 响应式Pinia 使用 Vue 3 的 Composition API 和其响应式系统,这意味着状态的变化会自动触发视图的更新。Pinia 的响应式系统比 Vuex 更轻量,更高效。
  4. 插件系统Pinia 允许你通过插件扩展其功能。你可以编写自己的插件来添加额外的功能,如持久化、日志记录等。
  5. 更好的 TypeScript 支持Pinia 提供了更好的 TypeScript 支持,使得在 TypeScript 项目中使用状态管理更加方便和安全。

安装和基本使用

安装pinia

npm i pinia

搭建pinia环境

// 导入 Vue 的 createApp 方法,用于创建 Vue 应用
import { createApp } from "vue";

// 导入本地的 App 组件,这是应用的根组件
import App from "./App.vue";

import { createPinia } from "pinia";

//创建一个应用
const app=createApp(App);

const pinia=createPinia()

app.use(pinia)

app.mount('#app')

创建一个 Pinia Store

// 引入defineStore用于创建store
import {defineStore} from 'pinia'

// 定义并暴露一个store
export const useCountStore = defineStore('count',{
  // 动作
  actions:{},
  // 状态
  state(){
    return {
      sum:6
    }
  },
  // 计算
  getters:{}
})
// 引入defineStore用于创建store
import {defineStore} from 'pinia'

// 定义并暴露一个store
export const useTalkStore = defineStore('talk',{
  // 动作
  actions:{},
  // 状态
  state(){
    return {
      talkList:[
        {id:'yuysada01',content:'你今天有点怪,哪里怪?怪好看的!'},
     		{id:'yuysada02',content:'草莓、蓝莓、蔓越莓,你想我了没?'},
        {id:'yuysada03',content:'心里给你留了一块地,我的死心塌地'}
      ]
    }
  },
    // 计算
    getters:{}
})

在组件中使用 Store

<template>
    <div class="count">
         <h2>当前求和为:{{ sum }}</h2>
         <select v-model.number="num">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
         </select>
         <button @click="add"></button>
         <button @click="minus"></button>
    </div>
</template>

<script lang="ts" setup name="Count">
    import {ref} from 'vue'
    import {useCountStore} from '@/store/count'
    import { storeToRefs } from 'pinia'

    const countStore=useCountStore()

    //storeToRefs  只关心数据  不关心方法  只将数据变成ref包裹的对象
    const {sum}=storeToRefs(countStore)

    
    let num=ref(1)

    function add(){

        //第一种方式  直接改
        countStore.sum +=num.value

        //第二种方式  批量改
        // countStore.$patch(
        //     {
        //         sum:888
        //     }
        // )


    }

    function minus(){
        countStore.sum -=num.value
    }

</script>

<style scoped>
    .count{
        background-color: aqua;
        padding: 10px;
        border-radius: 10px;
        box-shadow: 0 0 10px;
    }

    select,button{
        margin: 0 5px;
        height: 25px;
    }
</style>

<template>
    <div class="count">
        <button @click="addTalk">点击来一句土味情话</button>
        <ul v-for="talk in talkStore.talkList" :key="talk.id">
            <li>{{ talk.content }}</li>
        </ul>
    </div>
</template>

<script lang="ts" setup name="LoveTalk">
    import { reactive } from 'vue';
    import axios from 'axios';
    import {useTalkStore} from '@/store/loveTalk'

    const talkStore=useTalkStore()

    async function addTalk() {
            let result = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json');
            talkStore.talkList.push({ id: `${talkStore.talkList.length + 1}`, content: result.data.content });

    }
</script>

<style scoped>
    .count {
        background-color: chartreuse;
        padding: 10px;
        border-radius: 10px;
        box-shadow: 0 0 10px;
    }
</style>

实现的简单效果

在这里插入图片描述
点击加或者减后 数字发生变化 点击再来一句土味情话 土味情话加1

在这里插入图片描述

storeToRefs

借助storeToRefsstore中的数据转为ref对象,方便在模板中使用

storeToRefs 只关心数据 不关心方法 只将数据变成ref包裹的对象

<template>
    <div class="count">
         <h2>当前求和为:{{ sum }}</h2>
         <select v-model.number="num">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
         </select>
         <button @click="add"></button>
         <button @click="minus"></button>
    </div>
</template>

<script lang="ts" setup name="Count">
    import {ref} from 'vue'
    import {useCountStore} from '@/store/count'
    import { storeToRefs } from 'pinia'

    const countStore=useCountStore()

    //storeToRefs  只关心数据  不关心方法  只将数据变成ref包裹的对象
    const {sum}=storeToRefs(countStore)

    
    let num=ref(1)

    function add(){

        //第一种方式  直接改
        countStore.sum +=num.value

        //第二种方式  批量改
        // countStore.$patch(
        //     {
        //         sum:888
        //     }
        // )


    }

    function minus(){
        countStore.sum -=num.value
    }

</script>

<style scoped>
    .count{
        background-color: aqua;
        padding: 10px;
        border-radius: 10px;
        box-shadow: 0 0 10px;
    }

    select,button{
        margin: 0 5px;
        height: 25px;
    }
</style>

$subscribe

通过 store$subscribe() 方法侦听 state 及其变化

    countStore.$subscribe((mutate,state)=>{
        console.log('LoveTalk',mutate,state)
        localStorage.setItem('talk',JSON.stringify(sum.value))
    })

当数字发生了改变的时候
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值