好用的 Vue 状态管理模式:浅谈 Vuet 在实际应用中解决的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
1340641314
V2EX    分享创造

好用的 Vue 状态管理模式:浅谈 Vuet 在实际应用中解决的问题

  •  
  •   1340641314
    lzxb 2017-08-21 08:54:45 +08:00 4192 次点击
    这是一个创建于 2977 天前的主题,其中的信息可能已经有所发展或是发生改变。

    父子组件通信

    Alt text

    Vuet 提供了模块化的状态管理,通过对一个组件的注入,再向其子组件进行分发,使得我们可以在任何一个子组件,通过模块的方法对当前模块的状态进行更新,再由和 vuet 连接的父组件对子组件进行单向数据流动。这样我们就可以轻易的解决了父子组件的通信问题,也使得状态测试变得异常简单。

    状态测试

     import test from 'ava' // 假设这是我们应用程序的代码 start import Vue from 'vue' import Vuet from 'vuet' Vue.use(Vuet) const vuet = new Vuet({ modules: { test: { data() { return { count: 0 } }, plus() { this.count++ }, delay() { return new Promise((resolve, reject) => { setTimeout(() => { this.count = 1000 resolve() }, 100) }) } } } }) new Vue({ vuet }) // 假设这是我们应用程序的代码 end // 接下来我们可以写 vuet 的状态测试 test('test', async t => { const vtm = vuet.getModule('test') t.is(vtm.count, 0) vtm.plus() t.is(vtm.count, 1) await vtm.delay() t.is(vtm.count, 1000) }) 

    上面是一个简单的状态测试的例子,在实际项目中,还应该包含很多 http 请求,我们可以使用axios模块来和服务器进行交互,好处就是它也支持在 node 环境中运行,这样我们编写 http 请求相关的状态测试变成了可能。在如今版本快递迭代的大环境中,写测试几乎变成了一种很稀罕的事情,前端的测试更是少之又少。往往一个页面中,又拆分成很多子组件,这使得测试的工作量成指数级增长,面临着需求的频繁改动而无能为力。而 Vuet 的状态测试更类似于单元测试,和组件的依赖较低,组件只会存在调用 Vuet 模块的方法或者读取状态,在组件频繁的改动中,而 Vuet 的改动相对会较小,所以状态测试便会存在一定的价值。

    规则

    在生活中,我们每天都会进行着一些重复的工作,比如每天起床之后都会刷牙、洗脸、吃早餐,这些重复而单调的工作,在 Vuet 中则可以教给规则来处理。 比如: 页面 url 发生改变,重新请求一下数据, 模块的状态发生变化时,使用localStorage做持久化处理, 组件初始化时,请求一下数据, 组件销毁时,重置一下状态, 每隔一段时间,帮我请求一下数据, 等等...... 我们可以将这些简单重复的工作,封装成一个规则,然后可以使用这个规则去更新模块的状态

     export default { rule ({ path }) { return { destroyed () { this.$vuet.getModule(path).reset() } } } } 

    上面是一个非常简单的例子,它的工作就是在组件销毁时,重置模块的状态,以节省内存的占用。如果需要,我们还可以优化这个规则,在组件初始化时从localStorage中还原状态,在组件销毁时使用localStorage存储状态,然后在重置状态。

    总结

    Vuet 可以很好的解决了 Vue.js 中组件通信的问题,而且合理的运用规则,可以让我们事半功倍。 Vuet 官网:传送门

    22 条回复    2017-08-22 11:04:52 +08:00
    Hilong
        1
    Hilong  
       2017-08-21 09:19:26 +08:00 via Android
    没看懂。。。
    sirm2z
        2
    sirm2z  
       2017-08-21 09:40:57 +08:00
    戳中了原生 vue 的什么痛点~
    1340641314
        3
    1340641314  
    OP
       2017-08-21 09:43:59 +08:00
    @Hilong 哈哈
    jin5354
        4
    jin5354  
       2017-08-21 09:44:52 +08:00
    解决了啥 vuex 没解决的问题?
    SourceMan
        5
    SourceMan  
       2017-08-21 09:46:19 +08:00
    可以把它跟 vuex 比较吗?
    如果可以,它比 vuex 的优势在哪里?
    1340641314
        6
    1340641314  
    OP
       2017-08-21 09:52:35 +08:00
    @sirm2z
    解决了父子通信,
    能够有效的实现状态测试,
    使用规则更新状态,使得代码更易于维护。
    1340641314
        7
    1340641314  
    OP
       2017-08-21 09:54:22 +08:00
    @jin5354 vuex 相对于 vuet 写起来更加复杂,除了模块系统之外,还支持规则系统。能将大量相似的操作,封装成规则去驱动模块的更新。
    1340641314
        8
    1340641314  
    OP
       2017-08-21 09:58:02 +08:00
    @SourceMan vuet 的定位并不是取代 vuex,它是为了减少重复的工作而生,同时它也使用状态的维护变得更简单。相比 vuex 把属性、方法一个个注入到组件中,vuet 更注重将整个模块注入到组件中,更倾向于使用规则来处理模块的更新。
    1340641314
        9
    1340641314  
    OP
       2017-08-21 10:03:08 +08:00
    假设在一个场景中,我们希望模块的状态更新后,能存储到`localStorage `中,等用户下次访问的时候,还原状态。
    如果使用 vuex 实现的话,我们需要在更新状态的同时,使用`localStorage`进行存储,手动使用`localStorage`进行取出。
    然而在 vuet 中,它更支持你使用一种规则来定义这个模块的行为,监听模块的改变,自动存储,自动取出。

    这是我写的一个[vuet-store]( https://github.com/medatc/vuet/tree/dev/packages/vuet-store),能够更好的理解 vuet 的作用:
    1340641314
        10
    1340641314  
    OP
       2017-08-21 10:03:34 +08:00
    otakustay
        11
    otakustay  
       2017-08-21 10:36:34 +08:00
    vuex 要用 localStorage 不是应该写个中间件通过特定的 Action (或者所有 Action )来做吗,哪会手动去写代码存储和取出的
    1340641314
        12
    1340641314  
    OP
       2017-08-21 11:07:42 +08:00
    @otakustay 没有,它只能在一个方法调用时,手动操作。其实我想表达的是,vuet 可以开发一个规则,简单到一个 vuet 模块的状态发生更改,由这个规则去存储和取出。而不是写在调用的方法里面去做操作
    xuebi1109
        13
    xuebi1109  
       2017-08-21 13:45:13 +08:00
    @1340641314 看了 github 的 demo 深刻认同,如果有更加经典的使用场景 demo 的话大家会更有深刻的体会,希望继续维护下去,我准备下个项目试一试,解决的痛点我也认同,确实体验比 vuex 好,不过我担心的就是烂尾问题,希望继续迭代下去, 赞!
    1340641314
        14
    1340641314  
    OP
       2017-08-21 14:52:11 +08:00
    @xuebi1109 这个现在只是开始,以后会发展成支持 react、vue、小程序。也就是说将业务的状态写在里面,在迁移到各种框架、小程序平台之类的,只需要一个连接器即可。状态的更新后,通知一下 Vue、React 之类的更新页面而已
    1340641314
        15
    1340641314  
    OP
       2017-08-21 15:00:10 +08:00
    @xuebi1109 如果你觉得有好的经典 demo,可以告诉我,哈哈。表达能力欠佳其实,文章还是没有能够表达我内心深处的想法
    codermagefox
        16
    codermagefox  
       2017-08-21 21:32:43 +08:00
    我能理解为自动挡的 Vuex 吗?
    xuebi1109
        17
    xuebi1109  
       2017-08-22 10:06:38 +08:00
    @1340641314 弄个好的案例, 写篇文章对比在使用 vuex 的时候是这样的,在对比用 vuet 这样做的话优雅很多,在我看来目前 vuex 要不停的去写 mutation 很繁琐,目前我看来 vuet 还可以将单个功能内聚到一个单例里面之后在移植到其他平台确实牛逼。
    1340641314
        18
    1340641314  
    OP
       2017-08-22 10:18:01 +08:00
    @xuebi1109 嗯,有道理,这几天有时间的话,就写一篇。接下来有时间,会试着实现 react 版本的 vuet,如果这一步完成了,再接下来就会整合 vue 版本的 vuet 和 react 版本的 vuet,使用连接器对各种框架进行适配
    1340641314
        19
    1340641314  
    OP
       2017-08-22 10:19:12 +08:00
    @codermagefox 不能,其实和 vuex 很不一样,它们唯一的共同点就是是一个全局的状态管理,未来 vuet 要发展的目标不仅仅只是 vue,而是一个横跨各种框架 js 状态管理模式
    1340641314
        20
    1340641314  
    OP
       2017-08-22 10:23:36 +08:00
    最终的发展目标,react、vue、微信小程序、支付宝小程序,等等之类,通过 vuet 的连接器,由它们将状态渲染成页面展示给用户,这样有一个非常大的好处就是状态测试变得简单,迁移到各种平台也会变得非常简单。
    xuebi1109
        21
    xuebi1109  
       2017-08-22 10:51:52 +08:00
    @1340641314 跨平台抹平问题我觉得可以放远一点,先把 vuet 完善一些做到极致之后在去做跨平台的事
    1340641314
        22
    1340641314  
    OP
       2017-08-22 11:04:52 +08:00
    @xuebi1109 嗯,是的。欢迎反馈 bug。功能开发花的时间其实很少,主要是花在了 测试上面
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5364 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 39ms UTC 08:27 PVG 16:27 LAX 01:27 JFK 04:27
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86