一、安装pinia
npm install pinia
二、使用pinia
1. 引入pinia
// mian.js
import { createApp } from 'vue'
import App from './App.vue'
// 引入pinia
import { createPinia } from 'pinia'
// 创建pinia
const pinia = createPinia()
const app = createApp(App)
// 安装pinia
app.use(pinia)
app.mount('#app')
2. 创建一个store
这里有两种写法:一种是配置项写法,另一种则是组合式api写法
配置项写法
// defineStore定义仓库函数
import { defineStore } from 'pinia'
// 定义仓库 & 导出仓库
// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useNumStore = defineStore('numStore', {
// state 状态/数据
state: () => {
return {
num: 10
}
},
// 计算属性
getters: {
dobuleNum() {
// 通过this获取state中的数据
return this.num * 2
}
},
// 函数(不分同步/异步)
actions: {
increaseNum() {
this.num++
},
decreaseNum(val) {
this.num += val
},
// 异步
asyncChangeNum() {
return new Promise((resolve, reject) => {
setTimeout(() => {
this.num += 2
// 切换状态为成功
resolve()
}, 1000)
})
}
}
})
组合式api写法
// 创建组合式api仓库
import { defineStore } from "pinia"
import { computed, ref } from "vue"
// 创建 & 导出仓库
export const useCounterStore = defineStore('counterStore', () => {
// 数据
const num = ref(10)
// 计算属性
const doubleNum = computed(() => num.value * 2)
// 方法
function increaseNum() {
num.value++
}
return { num, doubleNum, increaseNum }
})
3. 在组件中使用该store
1. 渲染方式1
<template>
<div>
<h3>渲染方式1</h3>
<p>num:{{ numStore.num }}</p>
<p>dobuleNum:{{ numStore.dobuleNum }}</p>
</div>
</template>
<script setup lang="ts">
// 导入仓库hooks函数
import { useNumStore } from '../store/num'
// 实例化仓库
const numStore = useNumStore()
</script>
2. 渲染方式2
<template>
<div>
<h3>渲染方式2: toRefs解构响应式数据</h3>
<p>num:{{ num }}</p>
<p>dobuleNum:{{ dobuleNum }}</p>
</div>
</template>
<script setup lang="ts">
import { useNumStore } from '../store/num'
const numStore = useNumStore()
// 渲染方式2 storeToRefs解构响应式数据
import { storeToRefs } from 'pinia'
const { num, dobuleNum } = storeToRefs(numStore)
</script>
3. 渲染方式3
<template>
<div>
<h3>渲染方式3: computed解构</h3>
<p>num:{{ numC }}</p>
<p>dobuleNum:{{ doubleNumC }}</p>
</div>
</template>
<script setup lang="ts">
import { useNumStore } from '../store/num'
const numStore = useNumStore()
// 渲染方式3 computed 进行响应式解构
import { computed } from 'vue';
const numC = computed(() => numStore.num)
const doubleNumC = computed(() => numStore.dobuleNum)
</script>
4. 方法使用1
<template>
<div>
<h3>方法使用1</h3>
<button @click="numStore.increaseNum">num++</button>
</div>
</template>
<script setup lang="ts">
// 导入仓库hooks函数
import { useNumStore } from '../store/num'
// 实例化仓库
const numStore = useNumStore()
</script>
5. 方法使用2
<template>
<div>
<h3>方法使用2</h3>
<button @click="increaseNum">num++</button>
</div>
</template>
<script setup lang="ts">
// 导入仓库hooks函数
import { useNumStore } from '../store/num'
// 实例化仓库
const numStore = useNumStore()
// 方法使用2: 解构方法(数据需要storeToRefs解构,而方法可以直接解构)
const { increaseNum, decreaseNum, asyncChangeNum } = numStore
</script>