引言
在了解状态管理库Pinia之前,我们先回顾一下组件通信,我们有父传子,子传父,那么我们想要子--子之间进行通信,那怎么办呢?传统的,我们如果只知道父组件和子组件进行通信,就只能子组件1传给父组件,然后父组件再传给子组件2,想一想,这样会不会太麻烦了?我们可不可以定义一些公共数据,让任意组件都可以获取呢?
简单介绍一下Pinia
Pinia是一个用于Vue应用程序的状态管理库,它旨在提供一种更简洁、更现代的方式来处理跨组件状态共享,,主要用于在Vue应用中管理全局状态,即那些需要在多个组件之间共享和访问的数据。
关键词:跨组件之间进行通信
下面,让我们来了解一下Pinia的基本用法
-
安装Pinia: 使用npm或yarn安装Pinia包,指令:npm i pinia
-
创建store: 定义你的状态、actions和getters,并创建一个store模块。
-
激活Pinia: 在主应用文件中,通过
createPinia()
创建Pinia实例,并使用app.use()
将其注入到Vue应用中。 -
使用store: 在组件中通过组合API的
useStore
函数来访问store,或者在选项API中使用provide/inject
来访问store。
文件引入
main.js里面
-
引入
createPinia
函数(来自pinia
包)。 -
创建 Pinia 实例:
-
创建 Vue 应用实例: 使用
createApp
创建 Vue 应用实例,并传入根组件。 -
使用 Pinia: 在创建的 Vue 应用实例上使用 Pinia。这会将 Pinia 的状态管理功能注入到整个应用中。
-
挂载应用: 将 Vue 应用挂载到 DOM 中的某个元素上,通常是
#app
。
import { createApp } from 'vue'; 引入 `createPinia` 函数(来自 `pinia` 包)。
import { createPinia } from 'pinia';
import App from './App.vue';
const pinia = createPinia(); // 创建 Pinia 实例
const app = createApp(App); //创建 Vue 应用实例,并传入根组件
app.use(pinia); // 使用 Pinia
app.mount('#app'); //挂载应用
这里,main.js里面的内容我们就完成了
接下来,一般情况下,我们在src文件夹下面创建一个名叫stores的文件夹,stores的文件夹下面创建一个counter.js文件
counter.js里面
- 引入 Pinia: 首先,你需要从
pinia
包中引入defineStore
函数,用于定义 store。
import { defineStore } from 'pinia'
- 定义 Store: 使用
defineStore
函数来创建一个 store。你可以定义多个 store,每个 store 通常负责管理应用中特定部分的状态。
const useCounterStore = defineStore()
Pinia存储数据
import { ref,computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () =>
{
const count = ref(0) const name =ref('宇哥')
const doubleCount = computed(() => count.value * 2)
function increment() { count.value++
}
return { count, doubleCount,name, increment } })
解释
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
ref
和computed
是 Vue 3 Composition API 中的两个核心函数,用于创建响应式数据和计算属性。defineStore
是 Pinia 提供的函数,用于定义一个状态管理器。
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const name = ref('宇哥')
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, doubleCount, name, increment }
})
defineStore('counter', () => { ... })
定义了一个名为counter
的状态管理器。count
是一个通过ref
创建的响应式变量,初始值为0
。name
也是通过ref
创建的响应式变量,初始值为'宇哥'
。doubleCount
是一个通过computed
创建的计算属性,它的值是count.value
的两倍。increment
是一个函数,用于增加count
的值。return { count, doubleCount, name, increment }
将count
、doubleCount
、name
和increment
这些变量和函数暴露给外部使用。
接下来,我们来访问一下我们仓库里定义的数据
<template>
<div>
数量: {{ count }}
<br>
姓名:{{ name }}
</div>
</template>
<script setup>
import { useCounterStore } from "@/stores/counter.js"
import { storeToRefs } from "pinia";
const useStore = useCounterStore()
const { count, name } = storeToRefs(useStore)
</script>
<style lang="scss" scoped>
</style>
解释一下代码
<template>
<div>
数量: {{ count }}
<br>
姓名:{{ name }}
</div>
</template>
- 这部分定义了组件的模板。在模板中,通过
{{ count }}
和{{ name }}
来显示从状态管理器中获取的count
和name
的值。
<script setup>
import { useCounterStore } from "@/stores/counter.js"
import { storeToRefs } from "pinia";
const useStore = useCounterStore()
const { count, name } = storeToRefs(useStore)
</script>
import { useCounterStore } from "@/stores/counter.js"
导入了之前定义的useCounterStore
,该函数返回了一个 Pinia 的 store 实例。import { storeToRefs } from "pinia";
导入了storeToRefs
函数,用于将 store 实例中的响应式数据转换为普通的 ref 对象。const useStore = useCounterStore()
调用useCounterStore
函数得到一个实例useStore
。const { count, name } = storeToRefs(useStore)
使用storeToRefs
将useStore
中的count
和name
转换为普通的响应式对象。
常出现的错误!!!!!
如果是export xxxxxxxx
引入的话,就需要 import {xxxxxx} from ''
如果是 expotr default xxxxxxxx
引入的话,就 import xxxxxx from ''
这是我学Vue的时候经常出现的我问题,给大家分享一下
- 命名导出 (
export { ... }
): 允许一个模块导出多个变量、函数或对象,并且每个导出都有一个明确的名字。这种方式使得在导入时可以选择性地导入需要的部分,不需要导入整个模块的内容。 - 默认导出 (
export default ...
): 通常用于导出一个模块中的主要功能或对象,使得在导入时可以更简洁地引用,默认导出的内容可以使用任何合法的标识符来命名,而不需要花括号{}
包裹。
怎么通过Pinia修改数据呢
如果我们想把 宇哥改为鹿哥,并且每点一次加一,count就加一,该怎么办呢?
在这里,我们在Pinia里面定义一个改名名字的函数,抛出,然后,让组件去调用
App.vue
<template>
<div>
数量: {{ count }}
<br>
姓名:{{ name }}
<br>
<button @click="change()">点击修改姓名,变为鹿哥</button>
<br>
<button @click="add()">点击加一</button>
</div>
</template>
<script setup>
import { useCounterStore } from "@/stores/counter.js"
import { storeToRefs } from "pinia";
const useStore = useCounterStore()
const { count, name } = storeToRefs(useStore)
function change(){
useStore.changeName('鹿哥')
}
function add(){
useStore.Add()
}
</script>
<style lang="scss" scoped>
</style>
counter.js
import { ref,computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const name =ref('宇哥')
const doubleCount = computed(() => count.value * 2)
function Add() {
count.value++
}
function changeName(name)
{
this.name=name
}
return { count, doubleCount, name, Add, changeName }
})
在counter.js里面,我们定义了一个changeName(改变姓名)和一个Add,(点击数量加一)的两个函数,这两个函数在App.vue里面进行调用
最终的结果是:点击姓名变为鹿哥, 点击加以 数量加一
总结
在本文中,我们首先探讨了传统的Vue组件通信方式以及其局限性,随后介绍了Pinia作为现代化的Vue状态管理库的基本概念和使用方法。Pinia的安装和配置过程包括创建和定义store,以及在主应用中激活和使用Pinia实例。我们详细讨论了如何在组件中访问和修改Pinia store中的数据,例如通过计算属性和响应式数据管理计数器和姓名,并通过实例方法实现对数据的修改。