为什么现在更推荐使用Pinia?深入了解Pinia,解锁响应式数据的新姿势

1. pinia的安装和使用

csharp 复制代码
yarn add pinia
# 或者使用 npm
npm install pinia
javascript 复制代码
import App from './App.vue'
import { createApp } from 'vue'
import { createPinia } from 'pinia'

const pinia = createPinia()
const app = createApp(App)

app.use(pinia)
app.mount('#app')

具体详细步骤可以参照Pinai官方文档

2. pinin与vuex的异同

同:

  1. 状态管理:Pinia 和 Vuex 都是状态管理的工具,允许你在应用中统一管理和共享数据。
  2. 响应式:它们都利用 Vue 的响应式系统来跟踪状态的变化,并更新相关的组件。
  3. 插件化:都可以通过插件的形式扩展功能。

异:

  1. API 设计:Pinia 更面向未来,使用了更现代的 API 设计,提供了更简单和直观的方法来定义和使用状态。
  2. 模块化:Pinia 支持模块化的状态管理,每个模块都有自己的状态、操作和订阅者,使代码更易维护和组织。
  3. 性能:Pinia 在某些情况下可能比 Vuex 更高效,因为它使用了 Vue 3 的 reactivity system,可以更好地利用原生的响应式特性。
  4. TypeScript 支持:Pinia 对 TypeScript 的支持更好,提供了更好的类型推断和类型安全。

总的来说,Pinia 更加现代化并且在 Vue 3 中得到了更好的集成,如果你正在开发 Vue 3 项目并且喜欢模块化的状态管理,那么 Pinia 可能是一个更好的选择。而对于传统的 Vue 2 项目,或者需要与大量现有 Vuex 代码交互的项目,则可以继续使用 Vuex。

3. 功能实现

3.1 定义 state 和 getter

js 复制代码
// stores/counter.js
// 导入一个 defineStore 方法
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'

// 抛出方法
export const useCounterStore = defineStore('counter',() => {
    // 定义数据 (state)
    const count = ref(0)
    
    // state定义修改数据方法(action 同步操作)
    const increment = () => {
        count.value++
    }
    
    // getter定义
    const doubleCounter = computed(() => {
        return count.value * 2
    })
    
    // 以对象的方式return提供数组使用
    return { 
        count,
        increment,
        doubleCounter
        }
})
html 复制代码
<template>
    <button @click="counterStore.increment">{{ counterStore.count }}</button>
    <p>{{ counterStore.doubleCounter }}</p>
</template>

<script setup>
// 1. 导入 useCounterStore 方法
import { useCounterStore } from '@/stores/counter.js'

// 2. 执行方法得到 store 实例对象
const counterStore = useCounterStore()

console.log(counterStore)
// 打印Proxy

</script>

我们可以看到响应式对象count成功在vue文件中显示,并实现了getter中的doubleCounter方法,点击后count*2,我们再来看看执行方法得到 store 实例对象counterStore的打印结果是一个Proxy对象,而我们在stores/counter.js文件中定义的count、increment、doubleCounter也全部传入到vue文件中供实例对象counterStore使用。

3.2 定义action异步方法

先导入axios

复制代码
npm install axios
js 复制代码
// stores/counter.js
// 导入一个方法 defineStore
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import axios from 'axios'

// 抛出方法
export const useCounterStore = defineStore('counter',() => {
    // 定义数据 (state)
    const count = ref(0)
    // 接口调用
    const API_URL = 'http://geek.itheima.net/v1_0/channels'
    
    // state定义修改数据方法 (action 同步操作)
    const increment = () => {
        count.value++
    }

    // getter定义
    const doubleCounter = computed(() => {
        return count.value * 2
    })

    // action定义异步方法
    const list = ref([])
    // getlist 方法从API 获取数据并存储到 list 中,它是一个异步的操作,利用 axios 发起了一个 HTTP GET 请求。
    const getlist = async () => {
        const res = await axios.get(API_URL)
        list.value = res.data.data.channels
    }

    // 以对象的方式return提供数组使用
    return { 
        count,
        increment,
        doubleCounter,
        list,
        getlist}
})
html 复制代码
<template>
  <div>
    <button @click="counterStore.increment">{{ counterStore.count }}</button>
    <p>{{ counterStore.doubleCounter }}</p>
    
    <ul>
      <li v-for="item in counterStore.list" :key="item.id">{{ item.name }}</li>
    </ul>
    
  </div>
</template>

<script setup>
// 导入 useCounterStore 方法
import { useCounterStore } from '@/stores/counter.js'
// 导入生命周期函数
import { onMounted } from 'vue';

// 执行方法得到 store 实例对象
const counterStore = useCounterStore()

console.log(counterStore)
// 打印Proxy

// 使用异步操作 getlist 并渲染到列表中
onMounted(()=>{
  counterStore.getlist()
})

</script>

<style lang="scss" scoped>
</style>

我们在stores/counter.js文件中定义异步方法getlist 成功从远程 API 获取数据并存储到 list 中,所有功能全部传入到vue文件中供实例对象counterStore使用。

在 Pinia 中,mutation 不是必须的,但可以作为一种可选的方式来修改状态。相比于 Vuex,Pinia 更加灵活,你可以直接在 action 中修改状态,而无需显式地定义 mutation。这样可以简化代码结构并减少一些模板代码。如果你希望更明确地追踪状态的变更,并且想要确保状态的修改是同步的,那么也可以使用 mutation。

4. 提问与归纳

  1. Pinia是用来做什么的? 答:集中状态管理工具,新一代的vuex。

  2. Pinia中还需要mutation吗? 答:不需要,action既支持同步也支持异步

  3. Pinia如何实现getter? 答:computed计算属性函数

  4. Pinia产生的Store如何解构赋值数据保持响应式? 答:storeToRefs

关于第四点问题,可以来看看笔者的Pinia 状态管理利器:探秘 storeToRefs 的神奇魔力

相关推荐
用户479492835691514 分钟前
从一句话或代码仓到可交互 HTML:开源 Agent 画图技能 Archify v3.2 实测与选型边界
前端·后端·面试
风骏时光牛马3 小时前
生成一个AI多模态标题,仅输出一条标题,无额外文字、问句、备选、配图、文案等任何附加内容,不需要其他的任务服务 只要标题。
前端
wangruofeng3 小时前
从 GIF 到 AVIF:网页图片格式演进与 2026 年选型指南
前端·架构
清晨Coding4 小时前
为什么用 React Developer Tools 查看组件树这么乱?
前端·react.js
johnjincaaaa4 小时前
猿人学第 18 题「jsvmp 洞察先机」逆向通关实录
javascript·后端
鶴哥只手遮天4 小时前
《Electron 45.2.3 内核解剖》第 4 章 补丁体系:380 个补丁改了什么
前端·electron
FungLeo7 小时前
成为全栈·Vue 管理后台篇·分类树与标签管理:层级数据如何落到管理界面
前端·javascript·vue.js·分类树·naive ui·标签管理·前端数据结构
总要学点什么7 小时前
第108篇:三维特效-图片轨迹线效果——把贴图滚成一串箭头,想用它的本色反而整条消失
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
Lank_M10 小时前
白底都占八成,PNG 为何只在图表页赢过 JPG
前端
张一凡9310 小时前
给 Coding Agent 加一道"架构闸门":Jin 是如何做到"先审架构、再写代码、不漂移"的
前端·后端·agent