随笔 - 118  文章 - 0 评论 - 341 阅读 - 299万
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

1. 准备工作

1) 创建一个store,state只包含一个count成员:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        increment(state) {
            state.count++;
        }
    },
    actions: {
        incrementOfActive: ({ commit }) => {
            commit('increment');
        }
    },
    getters: {
        countOfGetter: (state) => {
            return state.count;
        }
    }
});

  

2) 创建一个Vue对象,并设置store

1
2
3
4
window.DEMO_VM = new Vue({
    el: '#app',
    store
});

 

2. Vuex对getter做了哪些处理

通过阅读Vuex的源码,发现对getter做了下面处理

2.1 进行局部化

说明:当创建Vuex.Store时,如果内部嵌套了多个stroe(Module),将进行局部化,目的是为了Module各自的getters都保持对各自state的访问。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function registerGetter(store, type, rawGetter, local) {
    if (store._wrappedGetters[type]) {
        if (__DEV__) {
            console.error(`[vuex] duplicate getter key: ${type}`);
        }
        return;
    }
    store._wrappedGetters[type] = function wrappedGetter(store) {
        return rawGetter(
            local.state, // local state
            local.getters, // local getters
            store.state, // root state
            store.getters // root getters
        );
    };
}

 

2.2 注册为计算属性

说明:初始化内部变量_vm,将getter注册为_vm的计算属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 获取getters内的每个getter封装到_vm
const wrappedGetters = store._wrappedGetters;
const computed = {};
forEachValue(wrappedGetters, (fn, key) => {
    computed[key] = partial(fn, store);
    Object.defineProperty(store.getters, key, {
        get: () => {
            return store._vm[key];
        },
        enumerable: true // for local getters
    });
});
 
store._vm = new Vue({
    data: {
        $$state: state
    },
    computed
});

 

3. 解析逻辑

3.1 $store.getters.countOfGetter值从哪里来

说明:虽然我们创建的countOfGetter的内部为"return state.count;",难道我们每次调用countOfGetter都是执行了对应的函数吗?

从2.2节的源码上看,Vuex对countOfGetter设置了get特性,每次调用都是从_vm.countOfGetter获取。

所以当调用 window.DEMO_VM.$store.getters.countOfGetter 时 → 实际上从返回为 window.DEMO_VM.$store._vm.countOfGetter

这里要注意一点store.getters都被注册为了_vm的计算属性。

官方对计算属性好处介绍:“计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。

总结:这样子也进一步说明store.getters保留了缓存特性。

 

3.2 修改了state,getters为什么会变更

说明:跟上面的说的getters注册为计算属性一样,_vm绑定了state与getters对应的关系,当变更state时,对应的getter也会发生改变。

 

4. 问题

4.1 为何不直接在组件外修改state?

既然可以通过"window.DEMO_VM.$store.state.count = 4" 这样操作来修改state,为什么还需要mutations、actions?

有下面几个原因:

1) 统一规范。如果都像这样在外部直接修改state,那么整个Vuex体系就会乱掉,直接当成了全局变量(缓存)来使用了。

2) hooks:mutations、actions内部的调用了都附加了Subscribe的处理。

 

posted on   FangMu  阅读(1859)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示