Vue3 状态管理 - Pinia教程【黑马】

1. 什么是Pinia

Pinia 是 Vue 的专属的最新状态管理库 ,是 Vuex 状态管理工具的替代品。(官网:https://pinia.vuejs.org/zh/
在这里插入图片描述

2. 手动添加Pinia到Vue项目

后面在实际开发项目的时候,Pinia可以在项目创建时自动添加,现在我们初次学习,从零开始:

  1. 使用 Vite 创建一个空的 Vue3项目
npm init vite@latest
  1. 按照官方文档安装 pinia 到项目中
yarn add pinia
# 或者使用 npm
npm install pinia
  1. main.js中创建pinia 实例 (根 store) 并将其传递给应用:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia() // 创建Pinia实例
const app = createApp(App) // 创建根实例

app.use(pinia) // pinia插件的安装配置
app.mount('#app') // 视图的挂载

3. Pinia基础使用

  1. 定义store
  2. 组件使用store
    在这里插入图片描述

4. getters实现

Pinia中的 getters 直接使用 computed函数 进行模拟, 组件中需要使用需要把 getters return出去
在这里插入图片描述
实例:要基于vue3做一个如下效果的数字加减案例,需要几个步骤?(加减按钮在子组件中)
在这里插入图片描述

  1. 创建vue3项目,安装pinia,并在main.js中创建pinia 实例(代码上面有,此处省略)
  2. 创建src/store/counter.js目录,并定义count数据和加减的方法
import { defineStore } from 'pinia'
import { ref } from 'vue' // 导入ref来定义想要的数据
import { computed } from 'vue' // 计算属性需要导入computed来实现

// 定义store
// defineStore( 仓库的唯一标识, () => { ... })
export const useCounterStore = defineStore( 'counter', () => {
    // 声明数据 state - count
    const count = ref(100)
    // 声明操作方法 action (普通函数)
    const addCount = () => count.value++
    const subCount = () => count.value--
    // 声明基于数据派生的计算属性 getters (computed)
    const double = computed(() => count.value*2)
    // 声明数据 state - msg
    const msg = ref('Hello!')
    // 将定义的数据和方法都return出去
    return { count, addCount, subCount, double, msg }
})
  1. src/components目录下新建Son1Com.vueSon2Com.vue两个子组件
<!-- Son1Com.vue -->
<script setup>
// 根据仓库名,导入定义的仓库
import { useCounterStore } from '@/store/counter'
// 通过实例访问定义的仓库
const counterStore = useCounterStore()
</script>
<template>
	<!-- 使用仓库中的count数据 -->
    <div>son1 - {{ counterStore.count }}
    <!-- 使用仓库中定义的方法 -->
    <button @click="counterStore.addCount">+</button></div>
</template>


<!-- Son2Com.vue -->
<script setup>
import { useCounterStore } from '@/store/counter'
const counterStore = useCounterStore()
</script>
<template>
    <div>son2 - {{ counterStore.count }}
    <button @click="counterStore.subCount">-</button></div>
</template>
  1. App.vue中使用子组件
<script setup>
// 导入子组件
import Son1Com from '@/components/Son1Com.vue'
import Son2Com from '@/components/Son2Com.vue'
// 根据仓库名,导入定义的仓库
import { useCounterStore } from '@/store/counter'
const counterStore = useCounterStore()
console.log(counterStore)
</script>

<template>
  <div>
    <h3>App.vue根组件 - {{ counterStore.msg }} </h3>
    <h3>count值:{{ counterStore.count }}</h3>
    <h3>count的2倍:{{ counterStore.double }}</h3>
    <Son1Com/>
    <Son2Com/>
  </div>
</template>

到这里实例就完成了。

5. action异步实现

方式:异步action函数的写法和组件中获取异步数据的写法完全一致

  • 黑马接口地址:http://geek.itheima.net/v1_0/channels

  • 请求方式:get

  • 请求参数:无

在这里插入图片描述

需求:在Pinia中获取频道列表数据并把数据渲染App组件的模板中
在这里插入图片描述

实现:

  1. 创建vue3项目,安装pinia,并在main.js中创建pinia 实例(代码上面有,此处省略)
  2. 安装axios: npm i axios
  3. 创建src/store/channels.js仓库
import { defineStore } from 'pinia'
import {ref} from 'vue'
import axios from 'axios'

export const useChannelStore = defineStore('channel', () => {
    // 声明数据
    const channelList = ref([])
    // 声明操作方法
    const getList = async () => {
        // 支持异步
        const { data: { data } } = await axios.get('http://geek.itheima.net/v1_0/channels')
        channelList.value = data.channels
        console.log(data.channels)
    }
    // 声明getters相关
    return {
        channelList,
        getList
    }
})
  1. App.vue中调用仓库中的方法获取数据并渲染到页面上
<script setup>
import { useChannelStore } from './store/channels'
const channelStore = useChannelStore()
</script>

<template>
  <div>
   <button @click="channelStore.getList">获取频道数据</button>
   <hr>
   <ul>
    <li v-for="item in channelStore.channelList" :key="item.id">{{ item.name }}</li>
   </ul>
  </div>
</template>

6. storeToRefs工具函数

注意,store 是一个用 reactive 包装的对象,这意味着不需要在 getters 后面写 .value。就像 setup 中的 props 一样,我们不能对它进行解构,如我们先前定义的counterStore仓库中的count和doubleCount,如果直接结构,那么再通过页面上的按钮进行加减时,页面将 不会实时更新

我们可以使用storeToRefs函数可以辅助保持数据(state + getter)的响应式解构:
在这里插入图片描述

7. Pinia的调试

Vue官方的 dev-tools 调试工具 对 Pinia直接支持,可以直接进行调试
在这里插入图片描述

8. Pinia持久化插件

官方文档:https://prazdevs.github.io/pinia-plugin-persistedstate/zh/

  1. 安装插件 pinia-plugin-persistedstate
npm i pinia-plugin-persistedstate
  1. 使用 main.js
import persist from 'pinia-plugin-persistedstate'
...
app.use(createPinia().use(persist))
  1. 配置 store/counter.js
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'

export const useCounterStore = defineStore('counter', () => {
  ...
  return {
    count,
    doubleCount,
    increment
  }
}, {
  persist: true
})

如果是微信小程序里面使用pinia,配置持久化时如下:

return {
    count,
    doubleCount,
    increment
    }
}, {
    persist: {
        storage:{
            getItem(key) {
                return uni.getStorageSync(key)
            },
            setItem(key, value) {
                uni.setStorageSync(key, value)
            },
        }
    }
})
  1. 其他配置,看官网文档即可
  • 14
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值