于Nuxt中使用Vuex
1、何为 Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
但是在 Nuxt.js 内置引用了 vuex 模块,所以不需要额外安装。
Nuxt.js 会尝试找到应用根目录下的 store 目录,无需配置 nuxt.config.js,如果该目录存在,它将做以下的事情:
引用 vuex 模块 将 vuex 模块 加到 vendors 构建配置中去 设置 Vue 根实例的 store 配置项
2、引用 Vuex
Nuxt.js 支持两种使用 store 的方式,你可以择一使用:
普通方式: store/index.js 返回一个 Vuex.Store 实例 模块方式: store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块 (当然,index 是根模块)
2.1 普通方式
使用普通方式的状态树,需要添加 store/index.js 文件,并对外暴露一个 Vuex.Store 实例:
1 | import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store = () |
在组件中就可以直接调用:<font style="color:#DD1144;background-color:#F6F6F6;"><span>{{$store.state.count}}</span><button </font>``[@click](https://github.com/click)``<font style="color:#DD1144;background-color:#F6F6F6;">="$store.commit('add')">+1</button></font>
2.2 模块方式
状态树还可以拆分成为模块,store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块
使用状态树模块化的方式,store/index.js 不需要返回 Vuex.Store 实例,而应该直接将 state、mutations 和 actions 暴露出来:
1 | export const state = () => ({ scount: 0 }) export const mutations = { |
在页面组件调用:
<font style="color:#DD1144;background-color:#F6F6F6;"><span>{{$store.state.index2.scount}}</span> <button @click="$store.commit('index2/addScount')">+2</button></font>
3、规范案例
在 Nuxt 项目的 store 目录下新建一个 index.js 文件作为主入口,这样项目就启用了 vuex
1 | import Vue from 'vue'; import Vuex from 'vuex'; import counter_add from |
其他的业务代码分模块来写,在 store 文件夹里再新建一个 filter.js 文件,在 index.js 中引入一下。
1 | const state = ({ value: 'Hello World', list: [1, 2, 3, 4, 5] }); const getters = |
这个文件中输出时候的 namespaced 属性,如果为 true 时,使用这个文件的方法时,需要标注 namespace,不写或为 false 时,则可以直接使用,这里建议使用 namespaced,因为大型项目可能有很多复杂的业务,可能命名冲突,使用 namespaced 可以把方法区分开,避免很多问题
__
现在,我们在 vue 文件中使用 vuex
1 | <template> |
在 vue 文件中,首先通过 import { mapState, mapMutations, mapActions, mapGetters } from ‘vuex’ 来引入我们需要的模块,按需引用,只需要引入本页面用到的模块即可
mapGetters 和 mapState 需要在页面的计算属性 computed 中引入, mapMutations 和 mapActions 需要在 methods 中引入,此时要注意模块的命名空间,如果 vuex 文件导出时标注了 namespaced,我们使用时也需要写出才可以找到,反之则不需要
首先是 mapState,使用 mapState 时,我有两种方法来取,两种方式都可以,这个方法是从 store 中取出这个变量,然后显示在此页面上,store 变动的话,此页面也会跟着动态改变
1.1 实例
1 | ...mapState({ value: state => state.filter.value }) |
1.2 实例
1 | ...mapState('filter', { value: state => state.value }) |
MapMutation 是更改 store 中状态的唯一方法,Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
mapAction 类似于 mutation, 但是 Action 提交的是 mutation,而不是直接变更状态,Action 可以包含任意异步操作,我们一般把异步获取数据的方法都放在这里,然后在回调函数里使用 mutation 里的方法把异步获取的数据保存在 store 里,然后把 store 里的数据传到页面
4、使用 QS 库
axios 默认的 content-type 是 application/json 也就是 java 后端经常让你把参数放在 body 中的那种格式 传输的样式是 requestbody
1 | { name:xxx, age:xxx } |
如果使用的 qs 进行序列化
那么 content-type 就是 application/x-www-form-urlencoded
也就是常说的表单提交
传输的样式是 formdata
1 | name:xxx, age:xxx |
总结,实际上 urlencoding 后是 <font style="color:#DD1144;background-color:#F6F6F6;">name=xxx&age=xxx</font>
ajax 请求的 get 请求是通过 URL 传参的(以?和&符连接),而 post 大多是通过 json 传参的。 qs 是一个库。里面的 stringify 方法可以将一个 json 对象直接转为(以?和&符连接的形式)。
5、FAQ
Q:Cannot assign to read only property ‘exports’ of object
请检查您的项目是否存在 module.exports = xyz 表达,因为 webpack 2 中不允许混用 import 和 module.exports