Pinia是什么
Pinia是Vue的最新状态管理工具,是Vuex的替代品
比Vuex更大的优势在于:
1.提供更加简单的API(去掉了mutation)
2.提供符合,组合式风格的API(和Vue3新语法统一)
3.去掉了modules的概念,每一个store都是一个独立的模块
4.配合TypeScript更加友好,提供可靠的类型推断
手动添加Pinia到Vue项目
在实际开发项目的时候,关于Pinia的配置,可以在项目创建时自动添加
现在初次学习,从零开始:
1.使用Vite创建一个空的Vue3项目
npm create vue@latest
2.按照官方文档安装pinia到项目中
官方文档:Pinia | Pinia
先装包
在mian.js文件中添加以下语句:
import { createPinia } from 'pinia'
const pinia = createPinia()
app.use(pinia)
基本语法
在src文件夹下,创建一个名为store的文件夹,创建js文件
定义数据
JS文件中编写语句定义数据,export导出仓库,仓库里的变量要return出去才能去使用
仓库变量名=use+仓库名+Store
import { defineStore } from 'pinia'
import { ref } from 'vue'//定义store
//defineStore(仓库的唯一标识,()=>{...})
export const useCounterStore = defineStore('counter', () => {//声明数据stateconst count = ref(0)//声明操作数据的方法 action(普通函数)//声明基于数据派生的计算属性 getters(computed)return {count}
})
使用数据(在App.vue和子组件中都是如此)
<script setup>
import { useCounterStore } from '@/store/counter.js'
const counterStore = useCounterStore()
console.log(counterStore.count)
</script><template>{{ counterStore.count }}
</template>
定义操作数据的方法
JS文件中编写语句定义方法,仓库里的方法要return出去才能去使用
import { defineStore } from 'pinia'
import { ref } from 'vue'//定义store
//defineStore(仓库的唯一标识,()=>{...})
export const useCounterStore = defineStore('counter', () => {//声明数据stateconst count = ref(0)//声明操作数据的方法 action(普通函数)const addCount = () => count.value++const subCount = () => count.value--//声明基于数据派生的计算属性 gettersreturn {count,addCount,subCount}
})
使用方法
<script setup>
import { useCounterStore } from '@/store/counter.js'
const counterStore = useCounterStore()
</script><template><div>{{ counterStore.count }}<br><button @click="counterStore.addCount">+</button><button @click="counterStore.subCount">-</button></div>
</template>
定义计算属性(用computed实现getter)
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'//定义store
//defineStore(仓库的唯一标识,()=>{...})
export const useCounterStore = defineStore('counter', () => {//声明数据stateconst count = ref(0)//声明操作数据的方法 action(普通函数)const addCount = () => count.value++const subCount = () => count.value--//声明基于数据派生的计算属性 gettersconst double = computed(() => count.value * 2)return {count,addCount,subCount,double}
})
使用计算属性
<script setup>
import { useCounterStore } from '@/store/counter.js'
const counterStore = useCounterStore()
</script><template><div>{{ counterStore.double }}</div>
</template>
action异步实现
Pinia中不需要mutation,action既支持同步也支持异步
编写方式:异步action函数的写法和组件中获取异步数据的写法完全一致
安装axios
yarn add axios
在store文件夹下,创建一个新的JS文件channel.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
import axios from 'axios'export const useChannelStore = defineStore('channel', () => {//声明数据const channelList = ref([])//声明getters相关const getList = async () => {const { data: { data } } = await axios.get('http://geek.itheima.net/v1_0/channels')channelList.value = data.channels}return {channelList,getList}
})
数据获取和渲染
<script setup>
import { useChannelStore } from '@/store/channel.js'
const channelStore = useChannelStore()
</script><template><button @click="channelStore.getList">获取频道数据</button><ul><li v-for="item in channelStore.channelList " :key="item.id">{{ item.name }}</li></ul>
</template>
storeToRefs方法
如果对仓库直接解构使用,不进行处理,数据会丢失响应式
比如:
<script setup>
import { useCounterStore } from '@/store/counter.js'
const counterStore = useCounterStore()
const {count}=counterStore
</script><template>{{ count }}
</template>
如果想保持数据响应式,可以在解构的时候使用storeToRefs方法;不过解构函数不需要使用storeToRefs方法,直接解构就可以
<script setup>
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/store/counter.js'
const counterStore = useCounterStore()
const { count } = storeToRefs(counterStore)
</script>
Pinia调试
持久化
持久化插件官方文档:快速开始 | pinia-plugin-persistedstate
1.安装包
npm i pinia-plugin-persistedstate
2.在main.js中编写
import { createPinia } from 'pinia'
//导入pinia持久化的插件
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'const pinia = createPinia()
const app = createApp(App)
app.use(pinia.use(piniaPluginPersistedstate))
3.使用:根据自己编写的语法选择添加
persist: true
如果这个模块添加了持久化,那么用户修改的数据会被存储到本地,刷新也是修改后的,加载时也是优先从本地读取数据
修改一些默认配置可以参考:配置 | pinia-plugin-persistedstate
persist: {key: 'my-channels',//修改本地存储的唯一标识storage: sessionStorage,//存储到什么中paths: ['channelList']//存储的是哪些数据}