vue3通信大全(一)------ 组件通信与provide - 掘金 (juejin.cn)
vue3通信大全(二)------ 路由传参与 teleport - 掘金 (juejin.cn)
前言
前两篇已经讲述了vue3内常见组件通信方式,也是我们必须要掌握的组件通信。这里我们再来介绍两个组件通信方式,当然这个并不是传统的通信方式,而是全局状态管理,但是他们也可以兼职组件通信的功能。这里我们不深入他们的研究,只谈他们在组件通信中的使用。
pinia
Pinia针对Vue 3设计,充分利用Composition API,提倡更简洁和直观的状态管理方式。每个store在Pinia中都是独立的,同时为了兼容Vuex的写法Pinia仍然支持使用选项式API,也是现在主流的状态管理库。
在main.js
文件中:
javascript
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia=createPinia() //创建pinia实例对象
createApp(App)
.use(pinia) // use这个实例对象
.mount('#app')
在store
文件中
ini
import { defineStore } from "pinia";
import { ref, computed } from 'vue';
export const useCounterStore = defineStore('counter',
() => {
// state
const count = ref(0);
// actions
const increment = () => {
count.value++;
};
const decrement = () => {
count.value--;
};
const reset = () => {
count.value = 0;
};
const doubleCount = computed(() => {
return count.value * 2;
});
return { count, increment, decrement, reset, doubleCount };
},
);
export const useStore = defineStore('store',
() => {
const someState=ref('hello Pinia');
const incrementSomeState = () => {
someState.value += '!'
}
return { someState , incrementSomeState }
},
);
App.vue
文件与child.vue
文件内容相近我们就放一份代码了:
xml
<template>
<div>
<h1>App</h1>
<h1>Counter: {{ store.count }}</h1>
<h1>Double:{{ store.doubleCount }}</h1>
<button @click="store.increment">Increment</button>
<button @click="store.decrement">decrement</button>
<button @click="store.reset">reset</button>
</div>
<h1>String: {{ hel.someState }}</h1>
<button @click="hel.incrementSomeState">+ ! </button>
<Child />
</template>
<script setup>
import {useCounterStore,useStore} from '@/Pinia/counter.js' //引入定义好的状态库
import Child from '@/components/child.vue'
const store=useCounterStore()
const hel=useStore()
</script>
这里在pinia里我们使用的是Composition API 的方式书写,在store
文件中我们将 state,action,getter统统return出交给引入的组件使用,当组件调用这些API时,store将会记录内部的状态并修改,从而响应式的将所有引入的该状态的组件值修改。
vuex
Vuex设计为一个全局状态管理的单例模式,有一个中心化的存储来管理应用的所有状态。它基于Vue 2的Options API,强调状态的集中管理和严格的规则,包括State、Getters、Mutations(用于同步更改状态)和Actions(可以处理异步逻辑)。其使用与pinia的CompositionAPI 的写法还是略有不同的。 main.js
文件:
javascript
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import store from './store' // vuex是导入状态仓库,pinia是创建实例对象createPinia
const app=createApp(App)
app.use(store)
app.mount('#app')
store
文件内:
javascript
import { createStore } from 'vuex'
const state = {
counter: 0,//计数状态
user: null
}
const actions = {
//修改状态的方法
increment: ({ commit }) => {
// commit 提交一项修改 提交给mutations
commit('increment')
},
}
//所有的状态修改都要经过mutations,只有mutations 可以修改状态
const mutations = {
increment(state) {
state.counter++
}
}
//getter
const getters = {
doubleCount: (state) => {
return state.counter * 2
}
}
//除了读操作,对写操作十分严格
const store = createStore({state,actions,mutations,getters}) //创建实例对象
export default store
App.vue
文件: child.vue
组件类似
xml
<template>
<h2>App.vue:</h2>
<div>
count: {{ store.state.counter }}
</div>
<button @click="increment">+</button>
<div>
doubleCount: {{store.getters.doubleCount}}
</div>
<AppHeader />
</template>
<script setup>
import {useStore} from 'vuex'
import AppHeader from './components/app-header.vue'
const store=useStore()
const increment = () => {
//使用dispatch派出increment action的方法
store.dispatch('increment')
}
</script>
在vuex我们强调3个点:
- 在
main.js
文件中vuex使用的是导出的store仓库,而pinia是使用实例化对象 store
仓库中的actions
是提交修改方法名,而真正修改是通过mutations
,actions
就像是秘书,而mutation
像是boss,你不能直接找到boss修改属性,而必须通过dispatch
派出increment action
的方法,让mutation
去修改这个值。- vuex中的
getter
是不需要引入computed这个方法的,他会自动一直监听内部的状态是否发生改变。
虽然但是
虽然pinia很好但是vuex还是被许多项目使用中。