Day6、Vue3 Pinia状态管理库

「本专栏是我在学习 Vue3 过程中的总结与分享,旨在帮助初学者快速上手 Vue3。由于我也在持续学习中,如果有任何疏漏或错误,欢迎大家在评论区指正,我们一起进步!」
提示:使用该文档学习vue3需要有一些vue和vue2的基础才可以更好的学习噢~~
版权:未经允许,禁止转载!
鼓励:每一次努力,都是在为未来的自己铺路;哪怕今天只进步一点点,也是在靠近更好的明天!
————————————————


前言

提示:在Vue3的世界中,路由与管理库的学习都是重中之重,希望大家认真学习本章内容!

在当今的前端开发中,状态管理是一个至关重要的环节。随着 Vue 3 的推出,Pinia 作为新一代的状态管理库,凭借其简洁、灵活和高效的特点,逐渐成为开发者们的首选。Pinia 不仅完美契合 Vue 3 的 Composition API,还提供了更直观的状态管理方式,极大地提升了开发体验。本文将深入探讨 Vue 3 与 Pinia 的结合使用,帮助开发者更好地理解其核心概念与实践方法。


一、pinia初识

1.1 认识pinia

Pinia 是 Vue.js 生态中一个现代化的状态管理库,专为 Vue 3 设计。它的主要用途是帮助开发者更高效地管理应用中的全局状态,同时提供了一种简洁、灵活且易于维护的状态管理方案。以下是 Pinia 的主要用途与作用:

1. 集中管理应用状态
用途:在复杂的 Vue 应用中,组件之间的状态共享和通信可能变得非常复杂。Pinia 提供了一个集中式的状态存储(Store),使得所有组件都可以访问和修改同一份状态数据。

作用:避免了组件之间通过 Props 或事件传递数据的繁琐操作,简化了状态管理的逻辑。

2. 支持模块化状态管理
用途:Pinia 允许将应用的状态拆分为多个独立的 Store,每个 Store 可以专注于管理某一特定功能或模块的状态。

作用:这种模块化的设计使得代码结构更加清晰,便于维护和扩展,特别适合大型项目。

3. 与 Vue 3 的 Composition API 深度集成
用途:Pinia 充分利用了 Vue 3 的 Composition API,使得状态管理更加灵活和直观。开发者可以在 Store 中使用 ref、computed 等 Composition API 特性。

作用:让状态管理的代码更具可读性和可维护性,同时与 Vue 3 的开发风格保持一致。

4. 提供响应式状态
用途:Pinia 的状态是响应式的,当状态发生变化时,依赖该状态的组件会自动更新。

作用:开发者无需手动监听状态变化,减少了冗余代码,提升了开发效率。

5. 支持 TypeScript
用途:Pinia 对 TypeScript 提供了开箱即用的支持,能够为状态、Getters 和 Actions 提供完整的类型推断。

作用:增强了代码的可靠性和可维护性,特别适合大型团队协作开发。

6. 轻量且高效
用途:Pinia 的代码库非常轻量,核心逻辑简洁,没有过多的抽象层。

作用:减少了应用的体积,同时提升了运行性能。

7. 插件化扩展
用途:Pinia 支持通过插件扩展功能,例如持久化存储、日志记录等。

作用:开发者可以根据需求灵活地扩展 Pinia 的功能,满足不同场景的需求。

8. 替代 Vuex 的现代化方案
用途:Pinia 被设计为 Vuex 的替代方案,提供了更简单的 API 和更直观的使用方式。

作用:对于新项目,Pinia 是一个更现代、更轻量的选择;对于老项目,也可以逐步迁移到 Pinia,以提升状态管理的效率。

总结
Pinia 的主要用途是帮助开发者更高效地管理 Vue 应用中的全局状态,其作用体现在简化状态管理逻辑、提升代码可维护性、支持模块化开发、与 Vue 3 深度集成等方面。无论是小型项目还是大型应用,Pinia 都能提供一种简洁、灵活且高效的状态管理方案,是 Vue 3 生态中不可或缺的工具之一。

1.2 搭建pinia环境

第一步:安装pinia

npm i pinia

第二步:配置main.ts

import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
// 引入pinia
const app = createApp(App)
// 创建pinia
const pinia = createPinia()
// 安装pinia
app.use(pinia)
app.mount('#app')

二、数据的使用与修改

Pinia 提供了一种简洁而强大的方式来管理和操作应用中的状态数据。以下是关于 Pinia 数据使用与修改的核心概念和方法:

1. 定义状态(State)
使用:状态是 Pinia Store 中存储数据的地方。你可以在 Store 中定义一个初始状态,这些状态通常是响应式的。

修改:状态可以直接在 Store 中定义,并通过 Actions 或直接赋值的方式进行修改。

2. 访问状态
使用:在组件或其他 Store 中,可以通过 Store 实例直接访问状态。Pinia 的状态是响应式的,因此当状态发生变化时,依赖该状态的组件会自动更新。

修改:虽然可以直接修改状态,但建议通过 Actions 来修改状态,以确保状态变化的可预测性和可维护性。

3. 使用 Getters 计算状态
使用:Getters 是用于从状态中派生出新数据的函数。它们类似于 Vue 中的计算属性,可以根据状态的变化自动更新。

修改:Getters 本身是只读的,不能直接修改状态。如果需要修改状态,应该通过 Actions 来实现。

4. 通过 Actions 修改状态
使用:Actions 是用于修改状态的函数。它们可以包含异步逻辑(如 API 请求),并在操作完成后更新状态。

修改:Actions 是修改状态的主要方式。通过 Actions 修改状态可以确保状态变化的逻辑集中且易于追踪。

5. 直接修改状态(不推荐)
使用:在某些简单场景下,可以直接通过 Store 实例修改状态。

修改:虽然直接修改状态是可行的,但这种方式缺乏约束,可能导致状态管理混乱,因此不建议在复杂项目中使用。

6. 响应式更新
使用:Pinia 的状态是响应式的,当状态发生变化时,依赖该状态的组件会自动更新。

修改:无论是通过 Actions 还是直接修改状态,只要状态发生变化,所有依赖该状态的地方都会同步更新。

示例代码:

注意: 在reactive里面的ref不用value属性

count.ts

import { defineStore } from "pinia";
export const useCountStore = defineStore('count', {
  // state 存储数据的地方
  state() {
    return {
      sum: 6
    }
  },
  // 里面放置的是动作函数
  actions: {
    increment(value: any) {
      this.sum += value
    }
  },
  // 
  getters: {
    // 第一种方式
    // bigSum(state) {
    //   return state.sum * 10
    // }

    // 第二种方式
    // bigSum(): number {
    //   return this.sum * 10
    // }

    // 第三种方式
    bigSum: state => state.sum * 10·
  }
})

loveTalk.ts

import axios from "axios";
import { nanoid } from "nanoid";
import { defineStore } from "pinia";
import { reactive } from "vue";
// 选项式API 
/* export const useTalkStore = defineStore('talk', {
  // state 存储数据的地方
  state() {
    return {
      talkList: JSON.parse(localStorage.getItem('talkList') as string) || []
    }
  },
  actions: {
    async getTalk() {
      //双层解构 加 改名字
      let { data: { content: title } } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
      // 使用nanoid 可以唯一生成一个字符串
      // 安装 npm i nanoid
      let obj = { id: nanoid(), title: title }
      this.talkList.unshift(obj)
    }
  }
}) */

// 组合式API
export const useTalkStore = defineStore('talk', () => {
  const talkList = reactive(
    JSON.parse(localStorage.getItem('talkList') as string) || []
  )
  async function getTalk() {
    //双层解构 加 改名字
    let { data: { content: title } } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
    // 使用nanoid 可以唯一生成一个字符串
    // 安装 npm i nanoid
    let obj = { id: nanoid(), title: title }
    talkList.unshift(obj)
  }
  return { talkList, getTalk }
})

Count.vue

<template>
  <div class="count">
    <h2>当前求和为:{{sum}}</h2>
    <h2>扩大十倍为:{{bigSum}}</h2>
    <!-- 常用 后面加上.number -->
    <select v-model.number="n">
      <!-- 加冒号就变成了数字 -->
      <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 setup lang='ts' name="Count">
import { useCountStore } from '@/store/count';
import { storeToRefs } from 'pinia';
import { ref } from 'vue';

const countStore = useCountStore()
// 解构用storeTorefs!
// 使用getters
let {sum,bigSum} = storeToRefs(countStore)


// 获取数据的两种方式
// console.log(countStore.sum);
// console.log(countStore.$state.sum);

 let n = ref(1) // 选择的数字

function add(){
  // 修改pinia数据
  // pinia 可以直接修改数据
     countStore.sum += n.value

  // 也可以通过$patch({sum:888})的方式修改

  // 通过actions修改(麻烦)
  // countStore.increment(n.value)
}
function minus(){
  countStore.sum -= n.value
}
</script>
 
<style scoped>
 .count{
  background-color: skyblue;
  padding: 10px;
 }
 select,button{
  margin: 0 5px;
  height: 25px;
 }
</style>

LoveTalk.vue

<template>
  <div class="talk">
    <button @click="getTalk">获取一句土味情话</button>
    <ul>
      <li v-for="item in talkStore.talkList" :key="item.id">
        {{item.title}}
      </li>
    </ul>
  </div>
</template>
 
<script setup lang='ts' name="LoveTalk">
import { useTalkStore } from '@/store/loveTalk';

const talkStore = useTalkStore()
function getTalk(){
  talkStore.getTalk()
}
//  $subscribe 来监听库数据的改变
talkStore.$subscribe((rule,state) =>{
  localStorage.setItem('talkList', JSON.stringify(state.talkList))
})

</script>
 
<style scoped>
  .talk{
  background-color: orange;
  padding: 10px;
 }
 select,button{
  margin: 0 5px;
  height: 25px;
 }
</style>

总结

Vue 3 与 Pinia 的结合为前端开发者提供了一种更加现代化、高效的状态管理方案。通过本文的学习,相信读者已经对 Pinia 的核心概念和使用方法有了更深入的理解。在实际开发中,合理运用 Pinia 不仅能提升代码的可维护性,还能显著提高开发效率。希望本文能为您的 Vue 3 项目开发带来启发,助力您构建更加高效、优雅的前端应用。未来,随着前端技术的不断发展,Pinia 也将在更多场景中展现其强大的潜力。让我们共同期待,并在实践中不断探索与创新!

本章的学习到此结束,不会的地方大家评论区探讨,明天正常更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值