12、Pinia 快速入门

1、什么是Pinia

Pinia 是 Vue 的最新 状态管理工具 ,是 Vuex 的 替代品

2、手动添加Pinia到Vue项目

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

1.使用 Vite 创建一个空的 Vue3 项目
npm create vue@latest

2.按照官方文档 安装 pinia 到项目中

(1)用你喜欢的包管理器安装 pinia:

yarn add pinia
npm install pinia

(2)创建一个 pinia 实例 (根 store) 并将其传递给应用:
main.js

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

    src - store - counter.js
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'

// 定义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 pinia')

    return {
        count,
        msg,
        addCount,
        subCount,
        double
    }
})

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.count }} - {{ counterStore.double }}</h3>
    <Son1Com></Son1Com>
    <Son2Com></Son2Com>
  </div>
</template>

<style scoped>

</style>

components - Son1com.vue

<script setup>
import { useCounterStore } from '@/store/counter'
const counterStore = useCounterStore()
</script>

<template>
  <div>
    我是Son1.vue - {{ counterStore.count }} -<button @click="counterStore.addCount">+</button>
  </div>
</template>

<style scoped>

</style>

components - Son2Com

<script setup>
import { useCounterStore } from '@/store/counter'
const counterStore = useCounterStore()
</script>

<template>
  <div>
    我是Son1.vue - {{ counterStore.count }} - <button @click="counterStore.subCount">-</button>
  </div>
</template>

<style scoped>

</style>

4、getters实现

Pinia中的 getters 直接使用 computed函数 进行模拟, 组件中需要使用需要把 getters return出去

5、action异步实现

编写方式:异步action函数的写法和组件中获取异步数据的写法完全一致
接口地址:http://geek.itheima.net/v1_0/channels
需求:在Pinia中获取频道列表数据并把数据渲染App组件的模板中

store - channel.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
    }
})

App.vue

<script setup>
import Son1Com from './components/Son1Com.vue'
import Son2Com from './components/Son2Com.vue'
import { useCounterStore } from '@/store/counter'
import { useChannelStore } from './store/channel'
const counterStore = useCounterStore()
const channelStore = useChannelStore()
</script>

<template>
  <div>
    <h3>App.vue根组件 - {{ counterStore.count }} - {{ counterStore.double }}</h3>
    <Son1Com></Son1Com>
    <Son2Com></Son2Com>
    <hr>
    <button @click="channelStore.getList">获取频道数据</button>
    <ul>
      <li v-for="item in channelStore.channelList" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<style scoped>

</style>

6、storeToRefs工具函数

使用storeToRefs函数可以辅助保持数据(state + getter)的响应式解构

App.vue

import { storeToRefs } from 'pinia'
// 此时,直接解构,不处理,数据会丢失响应式
const { count, msg } = storeToRefs(counterStore) 

store 是一个用reactive 包裹的对象,这意味着不需要在getter 之后写.value,但是,就像setup 中的props 一样,我们不能对其进行解构

为了从 Store 中提取属性同时保持其响应式,您需要使用storeToRefs()。 它将为任何响应式属性创建 refs。 当您仅使用 store 中的状态但不调用任何操作时,这很有用

//作为action的increment 可以直接解构
const { increment } = store

App.vue

<script setup>
import Son1Com from './components/Son1Com.vue'
import Son2Com from './components/Son2Com.vue'
import { useCounterStore } from '@/store/counter'
import { useChannelStore } from './store/channel'
import { storeToRefs } from 'pinia'
const counterStore = useCounterStore()
const channelStore = useChannelStore()

// 此时,直接解构,不处理,数据会丢失响应式
const { count, msg } = storeToRefs(counterStore) 
const { channelList } = storeToRefs(channelStore)
const { getList } = channelStore
</script>

<template>
  <div>
    <h3>App.vue根组件 - {{ count }} - {{ msg }}</h3>
    <Son1Com></Son1Com>
    <Son2Com></Son2Com>
    <hr>
    <button @click="getList">获取频道数据</button>
    <ul>
      <li v-for="item in channelList" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<style scoped>

</style>

7、 Pinia的调试

Vue官方的 dev-tools 调试工具 对 Pinia直接支持,可以直接进行调试

8、Pinia持久化插件

持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘、数据库等)。

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

  1. 安装插件 pinia-plugin-persistedstate
    npm i pinia-plugin-persistedstate

  2. main.js 使用
    import persist from ‘pinia-plugin-persistedstate’

    app.use(createPinia().use(persist))

import { createApp } from 'vue'
import { createPinia } from 'pinia'
// 导入持久化插件
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

import App from './App.vue'
const pinia = createPinia()  //创建Pinia实例
const app = createApp(App)  //创建根实例
app.use(pinia.use(piniaPluginPersistedstate))  //pinia插件的安装配置
app.mount('#app') //视图的挂载
  1. store仓库中,persist: true 开启
    store - counter.js
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'

// 定义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 pinia')

    return {
        count,
        msg,
        addCount,
        subCount,
        double
    }
},{
    // persist: true //开启当前模块的持久化
    persist: {
        key: 'wjr-counter',
        paths: ['count']  //只持久化count
    }
})

9、小结

  1. Pinia是用来做什么的?
    新一代的状态管理工具,替代vuex
  2. Pinia中还需要mutation吗?
    不需要,action 既支持同步也支持异步
  3. Pinia如何实现getter?
    computed计算属性函数
  4. Pinia产生的Store如何解构赋值数据保持响应式?
    storeToRefs
  5. Pinia 如何快速实现持久化?
    pinia-plugin-persistedstate
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值