Pinia
Pinia简介
Pinia是Vue的专属状态管理库,它允许跨组件或页面共享状态。所谓状态管理,简单来说就是一个存储数据的地方。
Vue2的状态管理使用Vuex,Vue3在继续支持Vuex的同时,还支持新开发了Pinia,当然Pinia也支持Vue2。
Pinia起始于2019年11月,Pinia其实就是Vuex的升级版本。根据官网的描述,Pinia将取代Vuex,即Pinia=Vuex5。
Pinia与Vuex(<=4)的区别:
- mutation 已被弃用。它们经常被认为是极其冗余的。它们初衷是带来 devtools 的集成方案,但这已不再是一个问题了。
- 无需要创建自定义的复杂包装器来支持 TypeScript,一切都可标注类型,API 的设计方式是尽可能地利用 TS 类型推理。
- 无过多的魔法字符串注入,只需要导入函数并调用它们,然后享受自动补全的乐趣就好。
- 无需要动态添加 Store,它们默认都是动态的,甚至你可能都不会注意到这点。注意,你仍然可以在任何时候手动使用一个 Store 来注册它,但因为它是自动的,所以你不需要担心它。
- 不再有嵌套结构的模块。你仍然可以通过导入和使用另一个 Store 来隐含地嵌套 stores 空间。虽然 Pinia 从设计上提供的是一个扁平的结构,但仍然能够在 Store 之间进行交叉组合。你甚至可以让 Stores 有循环依赖关系。
- 不再有可命名的模块。考虑到 Store 的扁平架构,Store 的命名取决于它们的定义方式,你甚至可以说所有 Store 都应该命名。
安装Pinia
npm install pinia
在main.js中进行导入并注册使用
import { createApp } from 'vue'
import './style.css'
import App from './VueRouter/App.vue'
import router from './VueRouter/router' // 导入路由
import ElementPlus from 'element-plus' // 引入element plus组件库
import 'element-plus/dist/index.css' // 引入element plus样式表
import { createPinia } from 'pinia' // 导入pinia
const pinia = createPinia()
const app = createApp(App)
app.use(ElementPlus) // 加载Elementpuls
app.use(router) // 注册路由插件
app.use(pinia) // 注册pinia状态插件
app.mount("#app")
定义optionStore
新建src/VueRouter/store/tabbar.js
import { defineStore } from "pinia";
// 第一个参数是唯一的storeId
const useTabbarStore = defineStore("tabbar",{
// option Store
state:()=>({
isTabbarShow:true
}),
// getters
// actions
})
export default useTabbarStore
修改App.vue
<template>
<div>
<!-- 通过插槽插入子组件路由 -->
<router-view></router-view>
<!-- 增加导航 -->
<Tabbar v-show="store.isTabbarShow"></Tabbar>
</div>
</template>
<script setup>
import Tabbar from './components/Tabbar.vue';
import useTabbarStore from './store/tabbar';
const store = useTabbarStore()
</script>
<style>
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
}
</style>
修改Detail.vue
<template>
<div>
<button @click="plBackClick">返回</button>
detail
</div>
</template>
<script setup>
import {onMounted,onBeforeMount,onBeforeUnmount} from 'vue'
import { useRoute,useRouter } from 'vue-router'
import useTabbarStore from '../store/tabbar';
const route = useRoute()
const router = useRouter()
const store = useTabbarStore()
onBeforeMount(()=>{
store.isTabbarShow = false
})
onBeforeUnmount(()=>{
store.isTabbarShow = true
})
onMounted(()=>{
console.log('接收上一个页面传来的参数',route.params.plid)
})
const plBackClick = ()=>{
router.back() // 返回 router.forward()
}
</script>
Action
新建src/VueRouter/store/recommend.js
import { defineStore } from "pinia"
import axios from "axios"
const useRecommendStore = defineStore("recommend",{
// options store
state:()=>({
recommendList:[]
}),
actions:{
async getRecommendList(){
let res = await axios({
url:"https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=112132",
headers:{
'X-Client-Info':'{"a":"3000","ch":"1002","v":"5.2.1","e":"16931924276063063597842433"}',
'X-Host':'mall.film-ticket.cinema.list'
}
})
this.recommendList=res.data.data.cinemas
}
}
})
export default useRecommendStore
修改Recommend.vue
<template>
<div>
<ul>
<li v-for="data in store.recommendList" :key="data.cinemaId">
{{data.name}}
</li>
</ul>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
// import { useStore } from 'vuex'
import useRecommendStore from '../../store/recommend';
const type =ref(1)
// const store = useStore()
const store = useRecommendStore()
onMounted(()=>{
if(store.recommendList.length===0){
store.getRecommendList()
// store.dispatch("RecommendModule/getRecommendList")
}else{
console.log("缓存")
}
})
</script>
<style scoped lang="scss">
ul{
li{
padding:10px;
}
}
</style>
Getter
修改recommend.js,增加getters进行筛选
import { defineStore } from "pinia"
import axios from "axios"
const useRecommendStore = defineStore("recommend",{
// options store
state:()=>({
recommendList:[]
}),
actions:{
async getRecommendList(){
let res = await axios({
url:"https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=112132",
headers:{
'X-Client-Info':'{"a":"3000","ch":"1002","v":"5.2.1","e":"16931924276063063597842433"}',
'X-Host':'mall.film-ticket.cinema.list'
}
})
this.recommendList=res.data.data.cinemas
}
},
getters:{
filterRecommendList(state){
return (type)=>{
return state.recommendList.filter(item=>item.eTicketFlag===type)
}
}
}
})
export default useRecommendStore
修改Recommend.vue
<template>
<div>
<select v-model="type">
<option :value="1">App订票</option>
<option :value="0">前台兑换</option>
</select>
<ul>
<li v-for="data in store.filterRecommendList(type)" :key="data.cinemaId">
{{data.name}}
</li>
</ul>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
// import { useStore } from 'vuex'
import useRecommendStore from '../../store/recommend';
const type =ref(1)
// const store = useStore()
const store = useRecommendStore()
onMounted(()=>{
if(store.recommendList.length===0){
store.getRecommendList()
// store.dispatch("RecommendModule/getRecommendList")
}else{
console.log("缓存")
}
})
</script>
<style scoped lang="scss">
ul{
li{
padding:10px;
}
}
</style>
定义Setup Store
在Setup Store中:
ref()
就是state
属性computed()
就是getters
function()
就是actions
Setup Store比Option Store有更多的灵活性。
将tabbar.js和recommend.js由Option Store模式改为Setup Store模式
tabbar.js
import { defineStore } from "pinia";
import { ref } from "vue"
// 第一个参数是唯一的storeId
const useTabbarStore = defineStore("tabbar",()=>{
// setup Store
// ref包装定义的就是state
const isTabbarShow = ref(true)
const change = (value)=> {
isTabbarShow.value = value
}
return {
isTabbarShow,
change
}
})
export default useTabbarStore
recommend.js
import { defineStore } from "pinia"
import { ref,computed } from "vue"
import axios from "axios"
const useRecommendStore = defineStore("recommend",()=>{
// setup store
const recommendList = ref([])
const getRecommendList = async()=>{
let res = await axios({
url:"https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=112132",
headers:{
'X-Client-Info':'{"a":"3000","ch":"1002","v":"5.2.1","e":"16931924276063063597842433"}',
'X-Host':'mall.film-ticket.cinema.list'
}
})
recommendList.value=res.data.data.cinemas
}
const filterRecommendList = computed(()=>
(type)=>{
return recommendList.value.filter(item=>item.eTicketFlag===type)
}
)
return {
recommendList,
getRecommendList,
filterRecommendList
}
})
export default useRecommendStore