回顾组件的通信
全局状态控制
但是当组件越来越多,组件相关性不大时,我们子级管理组件之间的通信就比较复杂而且乱。我们需要vuex这种专业的组件间的通信共享仓库来管理全局状态控制,它能够方便、高效的实现组件之间的数据共享。
- 好处
- 数据的存取一步到位,不需层层传递
- 数据的流动非常清晰
- 存储在Vuex中的数据都是响应式的(数据更新后,使用数据的组件都会自动更新)
使用范围
- 频繁、大范围需要共享的数据(用户的登录状态、用户名称)
安装 Vuex
安装最新版本的 Vuex
复制npm install vuex@next
vuex的使用
vuex的工作原理
vuex的工作流程
创建Vuex实例
在根目录下创建一个名为 store.js 的文件
复制import { createStore } from 'vuex'; // 引入方法
const store = createStore({
state: { // 相当于依赖注入中祖先节点中的data
money: 0,
},
getters: { // 相当于依赖注入中祖先节点中的computed
gold: (state) => {
return state.money * 100;
}
},
// mutations可以修改state, 但不支持异步操作
mutations: {
recharge(state, n) { // 相当于依赖注入中祖先节点中的methods
state.money += n;
}
},
// actions 不能直接修改state的内容,需要调用mutations的方法更新,但是支持异步操作
actions: {
buy(context, n) {
context.commit("recharge", -n);
},
},
moudles: { // 如果 state 的个数太多,可以拆分为各个模块,相当于 mixins
},
});
export default store;
挂载Vuex实例
在 main.js 中安装上面的store
复制import { createApp } from 'vue';
import App from './App.vue';
import store from './store.js'; // 引入Vuex实例store
const app = createApp(App);
app.use(store); // 通过 app.use 方法将store挂载到应用实例上
app.mount('#app');
使用Vuex实例
选项式API中的使用
复制<template>
<div>
<p>我的余额: {{ money }}</p>
<p>我的金豆: {{ gold }}</p>
<button @click="recharge">充值</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
export default {
computed: {
money() {
return this.$store.state.money;
},
gold() {
return this.$store.getters.gold;
},
},
// computed: mapState(['money']), // 简写
// computed: { // 如果本身有其他的计算属性,可以使用...符号合并
// ...mapState(['money'])
// ...mapGetters(['gold'])
// },
methods: {
recharge() { // 定义一个方法,调用 this.$store.commit 提交 mutations 的方法
this.$store.commit('recharge', 5);
},
// ...mapMutations(['recharge']), // 简写
buy() { // 定义一个方法,调用 this.$store.commit 提交 mutations 的方法
this.$store.dispatch('buy', 5);
},
// ...mapActions(['buy']), // 简写
}
}
</script>
注意:
调用mutation里的方法用commit,dispatch
组合式API中的使用
复制<template>
<div>
<p>我的余额: {{ money }}</p>
<p>我的金豆: {{ gold }}</p>
<button @click="recharge">增加</button>
</div>
</template>
<script>
import { computed } from 'vue';
export default {
setup() {
const store = useStore(); // 使用useStore获取到Vuex实例store
return { // 暴露变量
// 在 computed 函数中访问 state
money: computed(() => store.state.money), // 需要使用computed达到响应式
// 在 computed 函数中访问 getter
gold: computed(() => store.getters.gold)
// 使用 mutation
recharge: () => store.commit('recharge'),
// 使用 action
buy: () => store.dispatch('buy')
}
}
}
</script>