Pinia 是 Vue 的专属的最新状态管理库 ,是 Vuex 状态管理工具的替代品
后面在实际开发Vue医疗项目的时候,Pinia可以在项目创建时自动添加,现在我们初次学习,从零开始:
npm create vite@latest vue-pinia-ts -- --template vue-ts
包管理器安装
pinia
npm install pinia
- 1
创建一个 pinia(根存储)并将其传递给应用程序:
import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const app = createApp(App) const pinia = createPinia() //pinia添加到应用中(插件安装) app.use(pinia) app.mount('#app')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
定义:
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useCounterStore = defineStore('counter', () => {
// 数据(state)
const count = ref(0)
// 修改数据的方法(action)
const increment = () => {
count.value++
}
// 以对象的形式返回
return { count, increment }
})
使用:
<script setup lang="ts">
// 1.导入useCounterStore方法
import { useCounterStore } from './stores/counter'
// 2.执行方法得到counterStore对象
const counterStore = useCounterStore()
script>
<template>
<button @click="counterStore.increment">
{{ counterStore.count }}
button>
template>
<style scoped>style>
Pinia中的 getters 直接使用 computed函数 进行模拟, 组件中需要使用需要把 getters return出去
定义:
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const increment = () => {
count.value++
}
const doubbleCount = computed(() => count.value * 2)
return { count, increment, doubbleCount }
})
使用:
<script setup lang="ts">
import { useCounterStore } from './stores/counter'
const counterStore = useCounterStore()
script>
<template>
<button @click="counterStore.increment">
{{ counterStore.count }}:{{ counterStore.doubbleCount }}
button>
template>
<style scoped>style>
方式:异步action函数的写法和组件中获取异步数据的写法完全一致
需求:在Pinia中获取频道列表数据并把数据渲染App组件的模板中
定义:channel.ts
import axios from 'axios'
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useChannelStore = defineStore('channel', () => {
// 1. 定义类型
type ChannelItem = {
id: number
name: string
}
type ResData = {
data: {
channels: ChannelItem[]
}
message: string
}
// 2. 定义响应式数据 (state)
const list = ref<ChannelItem[]>([])
// 3. axios获取数据 (异步action)
const getList = async () => {
const res = await axios.request<ResData>({
url: 'http://geek.itheima.net/v1_0/channels',
method: 'GET'
})
list.value = res.data.data.channels
}
return { list, getList }
})
使用:
<script setup lang="ts">
import { onMounted } from 'vue'
import { useChannelStore } from './stores/channel'
const channelStore = useChannelStore()
// 触发异步action
onMounted(() => {
channelStore.getList()
})
script>
<template>
<ul>
<li v-for="item in channelStore.list" :key="item.id">{{ item.name }}li>
ul>
template>
<style scoped>style>
./stores/channel
使用storeToRefs函数可以辅助保持数据(state + getter)的响应式解构
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { onMounted } from 'vue'
import { useChannelStore } from './stores/channel'
const channelStore = useChannelStore()
// storeToRefs只支持数据state/getters
const { list } = storeToRefs(channelStore)
// 方法直接用channelStore.getList()调用,或者采用如下的原始解构方法
const { getList } = channelStore
onMounted(() => {
getList()
})
script>
<template>
<ul>
<li v-for="item in list" :key="item.id">{{ item.name }}li>
ul>
template>
<style scoped>style>
Vue官方的 dev-tools 调试工具 对 Pinia直接支持,可以直接进行调试