Pinia
Pinia是Vue的专属的最新状态管理库 ,是Vuex状态管理工具的替代品,用于组件之间共享数据
Pinia中文文档
安装
下载依赖
导入
1 2 3 4 5 6 7 8 import { createPinia } from 'pinia' const pinia = createPinia ()createApp (App ).use (pinia).mount ('#app' )
Hello World 使用Pinia实现简易计数器
创建Store,定义变量和方法
1 2 3 4 5 6 7 8 9 10 11 12 // stores.counter.js import { ref } from "vue"; import { defineStore } from "pinia"; export const useCounterStore = defineStore('counter', () => { const count = ref(0) function increment() { count.value++ } return { count, increment } })
其他组件使用Store
1 2 3 4 5 6 7 8 9 10 11 12 // components.PiniaTest.vue <script setup> import { useCounterStore } from '@/stores/counter' const counter = useCounterStore() </script> <template> <div> <button @click="counter.increment()">{{ counter.count }}</button> </div> </template>
Getter
相当于计算属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import { computed, ref } from "vue"; import { defineStore } from "pinia"; export const useCounterStore = defineStore('counter', () => { const count = ref(0) function increment() { count.value++ } // Getter const doubleCount = computed(() => count.value * 2) return { count, increment, doubleCount } })
Action
相当于方法
创建异步获取数据的action
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // store import { ref } from "vue"; import { defineStore } from "pinia"; import axios from "axios"; const API_URL = 'http://geek.itheima.net/v1_0/channels' export const useCounterStore = defineStore('counter', () => { // Action const list = ref([]) const getList = async () => { const res = await axios.get(API_URL) list.value = res.data.data.channels } return { list, getList } })
组件调用store的action
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <script setup> import { useCounterStore } from '@/stores/counter' import { onMounted } from 'vue'; const counter = useCounterStore() onMounted(() => { counter.getList() }) </script> <template> <ul> <li v-for="item in counter.list" :key="item.id"> {{ item.name }} </li> </ul> </template>
解构 可以通过storeToRefs把store解构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <script setup> import { useCounterStore } from '@/stores/counter' import { onMounted } from 'vue'; import { storeToRefs } from 'pinia' const counter = useCounterStore() // 只能解构出数据(state, getter),方法(action)解构不出来 const { list } = storeToRefs(counter) onMounted(() => { counter.getList() }) </script> <template> <ul> <li v-for="item in list" :key="item.id"> {{ item.name }} </li> </ul> </template>
实例 通过pinia优化请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import { ref } from "vue" import { defineStore } from "pinia" import { getCategoryAPI } from '@/apis/layout' export const useCategoryStore = defineStore ('categoryStore' , () => { const categoryList = ref ([]) async function getCategoryList ( ) { const res = await getCategoryAPI () categoryList.value = res.result } return { categoryList, getCategoryList } })
在父组件里发送请求,把数据保存在store中,之后子组件通过store获取数据,不需要再去重新请求数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // src/views/Layout/index.vue <script setup> import LayoutNav from './components/LayoutNav.vue'; import LayoutHeader from './components/LayoutHeader.vue'; import LayoutFooter from './components/LayoutFooter.vue'; import LayoutFixed from './components/LayoutFixed.vue'; import { useCategoryStore } from '@/stores/category'; import { onMounted } from 'vue'; // 加载导航列表,让吸顶导航条和导航条只需要一次请求 const categoryStore = useCategoryStore() onMounted(() => { categoryStore.getCategoryList() }) </script> <template> <LayoutFixed/> <LayoutNav/> <LayoutHeader/> <RouterView/> <LayoutFooter/> </template>
pinia负责触发action
Pinia负责用户数据相关的state和action,组件中只负责触发action函数并传递参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import { defineStore } from 'pinia' import { ref } from 'vue' import { loginAPI } from '@/apis/user' export const useUserStore = defineStore ('user' , () => { const userInfo = ref ({}) async function getUserInfo ({account, password} ) { const res = await loginAPI ({ account, password }) userInfo.value = res.result } return { userInfo, getUserInfo } })
组件通过调用useUserStore
来发起请求,并把数据保存在Pinia。Pinia中的数据是保存在内存中的,一刷新就没了,需要进行持久化
Pinia持久化插件
持久化后,store return的数据会被保存到Local Storage
中