Pinia
状态管理工具,它和vuex有很多相似的地方
本质上他是vuex团队核心成员开发的,在vuex上面提出了一些改进
Pinia的引入(Vue2)
定义store(option)
import { defineStore } from 'pinia'
export const useStore = defineStore('main', {
// state为全局的共享状态 跟vuex不同 写法为函数返回对象
state: () => ({
counter: 4
}),
// getters为计算属性 接收第一个参数为state
getters: {
nct: state => state.counter * 5
},
// pinia去掉了mutations
// 统一在actions对于状态进行修改
// 不在限制同步或者异步的操作
actions: {
setCounter (payload) {
// 在actions的函数当中直接访问
// state直接通过this就可以访问
setTimeout(() => {
this.counter = this.counter + payload
}, 1500)
}
}
})
全局使用pinia
// main.js中进行挂载
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import VueCompositionApi from '@vue/composition-api'
import { createPinia, PiniaVuePlugin } from 'pinia'
Vue.config.productionTip = false
// 在vue2中使用需要安装@vue/composition-api 可以不使用
Vue.use(VueCompositionApi)
Vue.use(PiniaVuePlugin)
// 全局使用pinia
const pinia = createPinia()
new Vue({
router,
pinia,
render: h => h(App)
}).$mount('#app')
组件中使用(option api语法)
<template>
<div class="home">
{{ct}}
{{nct}}
</div>
</template>
<script>
import { mapActions, mapState, mapStores } from 'pinia'
import { useStore } from '@/store/index.js'
import { useMa } from '@/store/ma.js'
export default {
name: 'HomeView',
computed: {
...mapState(useStore, {
ct: 'counter', // mapState第一种写法
nct: store => store.counter * 2 // mapState第二种写法
}),
// 使用mapStores可以直接映射所有模块内的属性和方法 让组件实例直接访问对应的模块
...mapStores(useStore, useMa)
// 直接访问时需要加上模块名称+Store进行访问
// 如useStore调用时传入的名称为main
// 因此调用setCounter时为this.mainStore.setCounter()
// 获取属性同理this.mainStore.counter
},
methods: {
...mapActions(useMa, {
// 取出useMa模块下的actions指定的setCounter2函数
fn1: 'setCounter2'
})
}
}
</script>
Pinia的引入(Vue3)
定义store(setup)
import { defineStore } from 'pinia'
import {computed, reactive, ref} from "vue";
export const useStore = defineStore('main', () => {
// 当defineStore第二个参数改为函数时,写法与vue setup的写法相同
const counter = ref(4)
const nct = computed(() => counter.value * 5)
const setCounter = (payload) => {
setTimeout(() => {
counter.value = counter.value + payload
}, 1500)
}
// 由于没有setup语法糖的作用因此需要将所有需要用到的变量和方法return出来 否则无法访问
return {
counter,
nct,
setCounter
}
})
全局使用pinia
// main.js中进行挂载
import {createApp} from 'vue'
import App from './App.vue'
import router from './router/index.js'
import { createPinia } from 'pinia'
const store = createPinia()
const app = createApp(App)
app.use(router).use(store).mount('#app')
组件中使用(setup语法)
<template>
<div class="about">
{{ct}}
{{nct}}
<button @click="fn1">增加</button>
</div>
</template>
<script setup>
import { useStore } from '@/store/index.js'
import {storeToRefs} from "pinia";
import { computed } from 'vue'
const store = useStore()
const {counter, nct} = storeToRefs(store)
// 此处的counter和nct由于storeToRefs API的作用下,为响应式解构,对应拿到的也为ref数据,因此需要.value获取值
store.setCounter(2)
// 调用函数直接store.xx即可
</script>