nuxt 踩坑之 -- Vuex状态树的模块方式使用

原创 2017年12月20日 11:24:14
  • 874

初次看到这个模块方式,感觉很是新奇,之前的vuex状态树使用方法用的也有些腻了,就想来实践一发新的东西 
废话不多说,直接进入正题

Vuex状态树-模块方式官方文档解读

  1. 状态树还可以拆分成为模块,store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块

    • 这句话啊,看了半天,我都没绕出来。之前一直用的是store目录下文件为:index.js、state.js、mutations.js、actions.js。后三个是index.js的子模块,你说这每个js文件都是一个模块?懵逼一分钟
    • 继续往下:使用状态树模块化的方式,store/index.js 不需要返回 Vuex.Store 实例,而应该直接将 state、mutations 和 actions 暴露出来。 到这里我虽然还懵逼着,但是转念一想,nuxt还有这操作,都不用我们自己辛辛苦苦写export default store = () => new Vuex.Store({}) 了,倒也真的省事儿呢
    • 还是继续看例子吧,官方给的这个,看了一遍没看懂(笨小孩的世界真滴难),你这index.js不是Vuex默认的store文件么,再来一todos.js,同样暴露出去的对象,不应该是index.js同级的么
    • 重点来了,看不会不要紧,照猫画虎我还是会滴~

照猫画虎

// store/index.js
export const state = () => ({
  num: 0
})

export const mutations = {
  increment (state) {
    state.num ++
  },
  decrement (state) {
    state.num --
  }
}

// store/plus.js
export const state = () => ({
  plusNum: 1
})

export const mutations = {
  plus (state) {
    state.plusNum ++
  }
}

// store/minus.js
export const state = () => ({
  minusNum: 10
})

export const mutations = {
  minus (state) {
    state.minusNum --
  }
}

// pages/store.vue
<template>
  <section class="container">
    <table>
        <tr>
            <td colspan=4>vuex状态树使用</td>
        </tr>
        <tr>
            <td>页内数据</td>
            <td>index.js</td>
            <td>plus.js</td>
            <td>minus.js</td>
        </tr>
        <tr>
            <td>{{ count }}</td>
            <td>{{ $store.state.num }}</td>
            <td>{{ $store.state.plus.plusNum }}</td>
            <td>{{ $store.state.minus.minusNum }}</td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </table>
  </section>
</template>
  • 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
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 跑一下,唷!报错了,我说同学们啊,我写的真的没有错!!!
  • 好吧,报错内容:[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
  • 意思是我客户端和vue SSR生成的DOM不一样,客户端不也是SSR生成的,这是个问题,有知道的大佬,希望可以告诉我。
  • 不过这个问题我倒是解决了,虽然不知道问什么-_-!,把那一大堆的tr标签都放到tbody里面就OK了
  • 跑起来,没问题,按示例的写法,这样成功拿到了state的数据
  • 接着试试mutation的方法
<tr class="mutation-fun">
    <td @click="count ++">count ++</td>
    <td @click="$store.commit('increment')">increment</td>
    <td @click="$store.commit('plus')">plus</td>
    <td @click="$store.commit('minus')">minus</td>
</tr>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 报错:[vuex] unknown mutation type: plus
  • 修改下:
<tr class="mutation-fun">
    <td @click="count ++">count ++</td>
    <td @click="$store.commit('increment')">increment</td>
    <td @click="$store.commit('plus/plus')">plus/plus</td>
    <td @click="$store.commit('minus/minus')">minus/minus</td>
</tr>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 搞定~

自己先小结下这个模块怎么用的吧

  1. nuxt很贴心的帮我们省去了返回Vuex实例的代码,我们可以不用去写了
  2. 只有store文件夹下的index.js是一级的vuex状态,其他的js文件都是二级的状态树。(能不能有三级的我不知道,不过感觉没必要,哈哈哈!!)
  3. 每个状态树文件都可以包含state,mutation,action
  4. 使用二级状态树的state用: $store.state.文件名.变量名
  5. 使用二级状态树的mutation用: $store.commit(‘文件名/变量名’)
  6. 使用二级状态树的action用: $store.dispatch(‘文件名/变量名’)

官方示例没有提到的

  1. 二级状态树能调用一级状态树的state和mutation以及action吗?

    • 我们来给plus.js增加一个修改index.js中的state的方法plusIndex
export const state = () => ({
  plusNum: 1
})

export const mutations = {
  plus (state) {
    state.plusNum ++
  },
  plusIndex (state) {
    state.num ++
    console.log('点击递增index的num')
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 去试着调用了一下,文本打印出来了,也没有报错,但是完全获取不到index中的num哇~~
  • 这次聪明点儿,我直接把state打印出来:
export const state = () => ({
  plusNum: 1
})

export const mutations = {
  plus (state) {
    state.plusNum ++
  },
  plusIndex (state) {
    console.log('state: ', state)
    state.num ++
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 跑一下试试: 结果有点儿让人想哭:state: {num: NaN, plusNum: 1}。再看看页面上index.js对应的num依然是0,这就说明我们这里的num不是index.js里的num,而是下面state ‘.’(点)出来的num,并且没有给初始值就执行了一次 ++ ,所以值为NaN
  • 到这里,我已经大概猜测到了这里的弯弯绕是怎么回事儿了 –> 模块儿的作用域是本文件内。但编程不是靠猜的,要用实践证明的才是对的,下面在深究这个问题

    1. 反过来,一级状态树能调用二级状态树的state和mutation以及action吗?
  • 这里的情况跟上面一样,既然我们的这个store是模块方式生成的,那就要遵循模块化的规范,变量作用域只能在文件内

通过模块化编程规范来获取一级状态树的state

  • 先把index.js引过来,因为不放心引用过来的还是不是原来那个index.js,所以把它打印出来看看
const indexVuex = require('./index.js')
console.log('indexVuex: ', indexVuex)
  • 1
  • 2
  • 这下不就炸了嘛,我引过来的居然是一个空的vuex状态树!!!内容长这样子
{
    mutation: {},
    modules: {
        plus: {
            mutation: {},
            namespaced: true
        },
        minus: {
            mutation: {},
            namespaced: true
        }
    },
    namespaced: true
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 好吧,我这个用模块化的方式来使用其他文件内的变量的想法也是泡汤了

最后的让步,我在组件中调用状态树时再去用二级状态树的方法修改一级状态树的state,先试试:

// plus.js
export const state = () => ({
  plusNum: 1
})

export const mutations = {
  plus (state) {
    state.plusNum ++
  },
  plusIndex (state, meio) {
    meio ++
    console.log('meio: ', meio)
  }
}

// 调用:
<td @click="$store.commit('plus/plusIndex', $store.state.num)">递增index的num</td>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 点击后,依然没能修改index.js中的num,查看打印结果中一直都是1,也就是说我们传进去的是基本数据类型的0~~
  • 那修改一下,我们传进去一个引用数据类型的看看可以不
// plus.js
export const state = () => ({
  plusNum: 1
})

export const mutations = {
  plus (state) {
    state.plusNum ++
  },
  plusIndex (state, meio) {
    meio.num ++
    console.log('meio: ', meio.num)
  }
}

// 调用:
<td @click="$store.commit('plus/plusIndex', $store.state)">递增index的num</td>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 功夫不负有心人,终于是成功了,虽然这样很麻烦,但也起到了效果
  • 这里经验证:反过来一级状态树调用二级状态树也是一样的,代码就不贴了

小结一下

  1. vuex状态树的模块写法,不同的文件之间不能直接引用
  2. vuex状态树使用模块加载引用,得到的是一组命名空间,而不是最终生成的Vuex模块文件
  3. 要通过b文件修改其他文件的state需要在store外部去修改

最后,小小的STAR下

  1. 情境(situation):粗略的看完一遍NUXT的官方文档,回头把不太清楚的东西再整理一下,这儿就卡在Vuex状态树的的模块写法上
  2. 任务(task):通过各种方法弄明白NUXT的Vuex状态树的模块写法是怎么实现的
  3. 行动(action):第一步,参照官方示例先让自己的状态树能运行起来;第二步,与普通写法的状态树写法比较并举一反三,看看模块写法和普通写法的状态树在使用上有什么区别和需要注意的
  4. 结果(result):第一,学会了vuex状态树的模块写法和用法;第二,通过探索store目录下的不同文件之间是否可以互相引用以及模块引用来熟悉模块方式的写法和普通方式的区别,也找到了模块写法中修改其他模块的state的方法;第三,模块写法的优点:写法简单,结构清晰明了,符合现在模块化开发;同文件(模块)内部类似普通写法,可按业务模块划分Vuex模块,提高开发效率;还有一点儿,我觉得这样写省事儿,也好看-,-| 妈妈再也不用担心我所有的Vuex都放同一个文件中,要用时还得找半天了~~

=============================================================================== 
以上!下期再见! 
初学者,问题还很多,欢迎各位大神拍砖指导

vuex分模块3的更多相关文章

  1. vuex分模块后,如何获取state的值

    问题:vuex分模块后,一个模块如何拿到其他模块的state值,调其他模块的方法? 思路:1.通过命名空间取值--this.$store.state.car.list // OK 2.通过定义该属性的 ...

  2. 对vuex分模块管理

    为什么要分模块: 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象.当应用变得非常复杂时,store 对象就有可能变得相当臃肿.为了解决以上问题,Vuex 允许我们将 store 分割成模块 ...

  3. vuex分模块4

    Vuex下Store的模块化拆分实践 https://segmentfault.com/a/1190000007667542 vue.js vuex 猫切 2016年12月02日发布 赞  |   1 ...

  4. vuex分模块2

    深入理解Vuex 模块化(module) 转载  2017-09-26   作者:ClassName    我要评论 本篇文章主要介绍了Vuex 模块化(module),小编觉得挺不错的,现在分享给大 ...

  5. vuex分模块

    Vuex速学篇:(4)把我们的业务按模块分类 原创 2016年11月29日 10:45:38 8504 文档:http://vuex.vuejs.org/zh-cn/modules.html 这个mo ...

  6. vuex分模块管理

    1.定义命名空间 dog.js export default { namespaced: true, // 局部状态 state: { name: "拉布拉多", age: 1 } ...

  7. 分模块创建maven项目(一)

    maven是一个项目构建和管理的工具. 我们可以通过maven仓库可以实现管理构建(主要是JAR还包括:WAR,ZIP,POM等等). 我们可以通过maven插件可以实现编译源代.产生Javadoc文 ...

  8. Maven02——回顾、整合ssh框架、分模块开发、私服

    1 回顾 1.1 Maven的好处 节省空间 对jar包做了统一管理 依赖管理 一键构建 可跨平台 应用在大型项目可提高开发效率 1.2 Maven安装部署配置 1.3 Maven的仓库 本地仓库 远 ...

  9. 若依项目分模块集成uflo2

    关于若依分模块创建项目可参考:https://www.cnblogs.com/conswin/p/9766186.html 了解uflo2,uflo2是一套由BSTEK自主研发的基于Java的工作流引 ...

随机推荐

  1. QT开发环境的建立以及QTE4.6.3、tslib1.4的移植过程

    1.首先是建立Linux开发环境1.1.在windowsXP下安装博创公司提供的虚拟机软件VMware Workstation,版本为VMware-workstation-full-7.0.1-227 ...

  2. HDU 4414 Finding crosses(dfs)

    Problem Description The Nazca Lines are a series of ancient geoglyphs located in the Nazca Desert in ...

  3. MySQL更改表的存储引擎

    MySQL它提供了多种数据库存储引擎,存储引擎负责MySQL存储和检索数据的数据库.不同的存储引擎具有不同的特性,能须要将一个已经存在的表的存储引擎转换成另外的一个存储引擎.有非常多方法能够完毕这样的 ...

  4. HierarchicalDataTemplate

    针对具有分层数据结构的控件设计的,比如说TreeView,相当于可以每一个层级上做DataTemplate XmlDataProvider:数据源,写在Resources下 <XmlDataPr ...

  5. 使用StringBuilder与SqlParameter

    好处: 防止sql注入:占用内存更少 例子: 传参有业务查询条件startDate,endDate,A,每页数据个数pageSize,当前查询页码pageIndex string sql = @&qu ...

  6. WMWaire使用FreeNAS硬盘挂载、Raid0

    FreeNAS硬盘挂载.Raid0 发表于2012 年 03 月 28 日由admin 创建成功,FreeBSD的Hardware显示状态 今天,我们将在VMware工具的帮助下,学习“FreeNAS ...

  7. n阶贝塞尔曲线绘制(C/C#)

    原文:n阶贝塞尔曲线绘制(C/C#) 贝塞尔是很经典的东西,轮子应该有很多的.求n阶贝塞尔曲线用到了 德卡斯特里奥算法(De Casteljau's Algorithm) 需要拷贝代码请直接使用本文最 ...

  8. php 获取今日、昨日、本周,上周、本月,上月,季度的起始时间戳和结束时间戳的方法

    php 获取今日.昨日.上周.本月的起始时间戳和结束时间戳的方法,主要使用到了 php 的时间函数 mktime.下面首先还是直奔主题以示例说明如何使用 mktime 获取今日.昨日.上周.本月的起始 ...

  9. 【Ubuntu】查看系统资源占用(内存,cpu和进程)

    1 top 查看ubuntu的资源占用的命令为 $: top 说明:top命令就可以查看内存,cpu和进程了,很方便 top: 主要参数: d:指定更新的间隔,以秒计算. q:没有任何延迟的更新.如果 ...

  10. 【shell】分享高通平台刷版本简单的一个shell脚本

    #!/bin/shadb wait-for-deviceadb reboot bootloaderecho "start download"wait 5sudo fastboot ...