ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
>[success] # composition API -- VUEX 1. 可以通过 获取`this.$store` 来进行调用里面提供数据对象 * **state**-- 保存数据状态 * **mutations** -- 对`state `中的数据更改都是通过`mutations`中的方法操控,`Vuex `不提倡直接更改`state`中的数据 * **getters** -- 当我们要获取`state`中的方法的时候从`getter`中取值 * **Action** -- 异步获取请求参数赋值,他会操控`mutations`,再让`mutations`给`state`赋值 * **module**-- store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块 >[info] ## 综合案例 ~~~ // 创建vuex import { createStore } from "vuex"; const store = createStore({ state: () => { return { name: "wwww", age: 12, friends: [ { id: 111, name: "a", age: 20 }, { id: 112, name: "b", age: 30 }, { id: 113, name: "c", age: 25 }, ], }; }, getters: { // 第一个参数当前state getName(state) { return state.name; }, // 第一个参数当前state 第二个参数是getters getInfo(state, getters) { return state.age + getters.getName; }, // 通过返回一个函数达到 让 getter 可以接收参数 getFriendById(state) { return function (id) { const friend = state.friends.find((item) => item.id === id); return friend; }; }, }, mutations: { // 第一个参数 state ,第二个参数调用传入的值 changeName(state, payload) { state.name = payload; }, }, actions: { /** 处理函数总是接受 context 作为第一个参数,context 对象包含以下属性 * state, // 等同于 `store.state`,若在模块中则为局部状态 * rootState, // 等同于 `store.state`,只存在于模块中 * commit, // 等同于 `store.commit` * dispatch, // 等同于 `store.dispatch` * getters, // 等同于 `store.getters` * rootGetters // 等同于 `store.getters`,只存在于模块中 */ incrementAction(context, payload) { // console.log(context.commit) // 用于提交mutation // console.log(context.getters) // getters // console.log(context.state) // state context.commit("changeName", payload); }, }, }); export default store; ~~~ >[danger] ##### 特殊说明 -- state 1. `composition Api` 使用方式比较多,但推荐直接使用 `toRefs` 即可 2. 想使用`mapState` 这类 由于其映射出来的对象,所有要获取指定`key`对应的`function`,但要注意 `setup` 此时`this ` 指向问题,你需要手动指定`this`,否则执行失败 * 执行效果图 ![](https://img.kancloud.cn/e2/60/e2604d827159bcc61f4229a35d9dee3f_385x171.png) ~~~html <template> <div> {{ store.state.name }} {{ name }} {{ cname }} {{ tAname }} {{ tBname }} {{ rName }} </div> <button @click="changeState">changeState</button> </template> <script setup> import { computed, toRefs } from "vue"; import { useStore, mapState } from "vuex"; const store = useStore(); // 方法一 获取 state 依次赋值 const name = store.state.name; // 非响应 // 方法二 使用计算属性 const cname = computed(() => store.state.name); // 方法三使用 mapState 但需要自定义this 指向 const tAname = mapState(["name"]).name.apply({ $store: store }); // 非响应 const tBname = computed(mapState(["name"]).name.bind({ $store: store })); console.log(mapState(["name"])); // -----------最简单的方法 toRefs 解构-------------- const { name: rName } = toRefs(store.state); // 强制改变state function changeState() { store.state.name = "新"; } </script> ~~~ * 如果非要使用 `mapState `执行可以封装一个`hooks` ~~~ import { computed } from 'vue' import { useStore, mapState } from 'vuex' export default function useState(mapper) { const store = useStore() const stateFnsObj = mapState(mapper) const newState = {} Object.keys(stateFnsObj).forEach(key => { newState[key] = computed(stateFnsObj[key].bind({ $store: store })) }) return newState } ~~~ ~~~ // 使用 封装的 useState,其实和toRefs 一样 const { name, level } = useState(["name", "level"]) ~~~ >[danger] ##### 其他综合使用 ~~~html <template> <div> {{ getName }} </div> <button @click="changeName('111')">changeState</button> <button @click="increment('111')">incrementAction</button> <button @click="mapActions('111')">mapActions</button> </template> <script setup> import { toRefs } from "vue"; import { useStore, mapMutations, mapActions } from "vuex"; const store = useStore(); const { getName } = toRefs(store.getters); // 方式 一 const changeName = (name) => store.commit("changeName", name); // 方式二 手动的映射和绑定 // const mutations = mapMutations(["changeName"]); // const newMutations = {}; // Object.keys(mutations).forEach((key) => { // newMutations[key] = mutations[key].bind({ $store: store }); // }); // const { changeName } = newMutations; // ------------ action ---------- // 1.使用默认的做法 function increment(name) { store.dispatch("incrementAction", name); } // 2.在setup中使用mapActions辅助函数 // const actions = mapActions(["incrementAction", "changeNameAction"]) // const newActions = {} // Object.keys(actions).forEach(key => { // newActions[key] = actions[key].bind({ $store: store }) // }) // const { incrementAction, changeNameAction } = newActions </script> ~~~