• vue3 状态管理pinia


    1. 什么是Pinia

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

    在这里插入图片描述

    特点优势:

    • 提供更加简单的API(去掉了mutation)
    • 提供符合组合式风格的API(和Vue3新语法统一)
    • 去掉modules的概念,每一个store都是一个独立的模块
    • 配合TypeScript更加友好,提供可靠的类型推断

    2. 手动添加Pinia到Vue项目

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

    1. 使用 Vite 创建一个空的 Vue3项目

      npm init vite@latest
      
      • 1
    2. 按照官方文档安装 pinia 到项目中

      yarn add pinia
      # 或者使用 npm
      npm install pinia
      
      • 1
      • 2
      • 3

      创建一个 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') // 视图的挂载
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

    3. Pinia基础使用

    1. 定义store
    2. 组件使用store

    在这里插入图片描述

    4. getters实现

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

    在这里插入图片描述

    5. action异步实现

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

    在这里插入图片描述

    需求:在Pinia中获取频道列表数据并把数据渲染App组件的模板中

    在这里插入图片描述
    store/channel.js

    import { defineStore } from 'pinia'
    import { ref } from 'vue'
    import axios from 'axios'
    
    export const useChannelStore = defineStore('channel', () => {
        // 声明数据 state
        const channelList = ref([])
        // 声明操作数据的方法 action
        const getList = async () => {
            // 支持异步
            const { data: { data } } = await axios.get('http://geek.itheima.net/v1_0/channels')
            channelList.value = data.channels
        }
        // 声明getters相关
    
        return {
            channelList,
            getList
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    App.vue

    <script setup>
    import { useChannelStore } from '@/store/channel'
    const channelStore = useChannelStore()
    script>
    
    <template>
      <div>
        <h3>App.vue根组件h3>
        <button @click="channelStore.getList">获取频道数据button>
        <ul>
          <li v-for="item in channelStore.getList" :key="item.id">{{ item.name }}li>
        ul>
      div>
    template>
    
    <style scoped>style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    6. storeToRefs工具函数

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

    我们知道 Store 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字

    import { defineStore } from 'pinia'
    
    // 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
    // 第一个参数是你的应用中 Store 的唯一 ID。
    export const useCounterStore = defineStore('counter', {
      // 其他配置...
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这个名字 ,也被用作 id ,是必须传入的, Pinia 将用它来连接 store 和 devtools。为了养成习惯性的用法,将返回的函数命名为 use… 是一个符合组合式函数风格的约定。

    defineStore() 的第二个参数可接受两类值:Setup 函数Option 对象

    Setup函数

    export const useCounterStore = defineStore('counter', () => {
      const count = ref(0)
      function increment() {
        count.value++
      }
    
      return { count, increment }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在 Setup Store 中:

    • ref() 就是 state 属性
    • computed() 就是 getters
    • function() 就是 actions

    2.使用store

    虽然我们前面定义了一个 store,但在我们使用