ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] >[success] # state 与 getter ![](https://img.kancloud.cn/b3/f9/b3f994c71d894b582bae15b4a1df8ebb_701x551.png) 上图就是 **Vuex** 状态管理的 **流程** ,在 **Vue Components(组件)** 里可以触发一个 **Actions(Actions里可以做异步接口请求)** , **请求完成** 后触发一个 **Mutations** ,通过 **Mutations** 修改 **State** 的状态值,**State** 修改之后会触发 **vue组件视图的渲染** 。 >[success] ## state **state** 是 **vuex** 用来存放 **变量** 用的 **对象** ,为了提前做好准备,首先要将它**引入** : 1. 首先在 **store文件夹** 中 创建一个 **state.js** **store/state.js** ~~~ const state = { // 变量写这里 } export default state ~~~ 2. 在 **store/index.js** 中引入 **state.js** ,首先想使用 **Vuex** , **Vuex** 作为 **Vue** 的 **插件** 肯定要先 **引入Vue** ,然后再 **引入Vuex** ,然后引入我们 **初始化项目** 时候写好的 **mutations** 、 **actions** 、 **user** 以及刚刚写的 **state** 这几个 **js文件** ,然后引入 **Vue** 后通过 **Vue.use(Vuex)** 把 **Vuex** 加载进来,然后用 **new Vuex.Store()** 来 **创建实例** 。 **store/index.js** ~~~ import Vue from 'vue' import Vuex from 'vuex' import state from './state' // state.js文件可以不写.js结尾,这样写也会自动找到state.js文件 import mutations from './mutations' import actions from './actions' import user from './module/user' // 引入模块文件 Vue.use(Vuex) export default new Vuex.Store({ state, // ES6对象简写的形式,state: state 等同与 state mutations, actions, modules: { // 模块引用 user } }) ~~~ 3. 在 **main.js** 中把 **stroe文件夹** 中 **index.js** 里写好的 **Vuex实例** 引入并且 **挂载** 在 **根组件** 的 **实例**上 **main.js** ~~~ import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import './plugins/element.js' import Bus from './lib/bus' // 引入Bus Vue.config.productionTip = false Vue.prototype.$bus = Bus // 挂载Bus到Vue原型链(全局挂载Bus) new Vue({ router, store, render: h => h(App) }).$mount('#app') ~~~ >[success] ### 使用方法 1. **访问根状态的state** 可以把 **state** 看做成 **Vue** 中的 **data** ,在里面定义一个 **变量** **store/state.js** ~~~ const state = { appName: 'admin' } export default state ~~~ **state** 中定义的 **变量** 可以在 **各个组件** 中使用,如下: **store.vue** ~~~ <template> <div> <p>{{ appName }}</p> </div> </template> <script> export default { computed:{ appName(){ return this.$store.state.appName } } } </script> ~~~ 在使用的组件中通过 **computed(计算属性)** 来把 **state** 中的内容显示在页面上。 2. **访问模块中的state** 在 **模块** 中定义的 **state** 变量 **userName** **store/module/user.js** ~~~ const state = { userName: '小明' } const mutations = { // } const actions = { // } export default { state, mutations, actions } ~~~ 在组件中这样使用 **store.vue** ~~~ <template> <div> <p>{{ userName }}</p> </div> </template> <script> export default { computed:{ userName(){ return this.$store.state.user.userName // this.$store.state.模块名.模块中的变量名 } } } </script> ~~~ 3. **mapState函数访问state** 除了上面的 **2** 种方法还可以使用 **Vuex** 提供的 **mapState工具函数** 来访问 **state** ***** 3.1 **使用 mapState 访问 根状态state** **store.vue** ~~~ <template> <div> <p>{{ appName }}</p> </div> </template> <script> // 结构赋值写法 import { mapState } from 'vuex' // 相当于这么写 // import vuex from 'vuex' // const mapState = vuex.mapState export default { computed:{ ...mapState([ 'appName' ]) // 上面的跟下面这个效果是一样的 // appName(){ // return this.$store.state.appName // } } } </script> ~~~ **mapState** 方法会 **返回一个对象** ,使用 **扩展运算符扁平化的展开这个对象**,然而 **mapState** 也可以 **传入一个对象的写法** **store.vue** ~~~ <template> <div> <p>{{ appName }}</p> </div> </template> <script> // 结构赋值写法 import { mapState } from 'vuex' // 相当于这么写 // import vuex from 'vuex' // const mapState = vuex.mapState export default { computed:{ ...mapState({ appName: state => state.appName // state是根状态的state }) } } </script> ~~~ 3.2 **使用 mapState 访问 module 中的 state** **store.vue** ~~~ <template> <div> <p>{{ userName }}</p> </div> </template> <script> // 结构赋值写法 import { mapState } from 'vuex' // 相当于这么写 // import vuex from 'vuex' // const mapState = vuex.mapState export default { computed:{ ...mapState({ userName: state => state.user.userName // state.模块名称.模块里的state变量名 }) } } </script> ~~~ 3.3 **命名空间访问 module 中的 state** **命名空间** 的写法需要在 **module(模块)** 中添加一个 **namespaced:true** 表示开启 **命名空间**,如果获取的是 **根状态的state** 就 **不需要在store/index.js** 添加 **namespaced:true** 。 **store/module/user.js** ~~~ const state = { userName: '小明' } const mutations = { // } const actions = { // } export default { namespaced: true, state, mutations, actions } ~~~ 如果你设置了 **namespaced: true** 就可以在 **组件** 中使用 **Vuex** 的另外一个方法 **createNamespacedHelpers** 方法,这个方法可以传入一个 **命名空间的模块名**,这样写的话就不用给 **mapState** 写第一个参数(**模块名称**) **store.vue** ~~~ <template> <div> <p>{{ userName }}</p> </div> </template> <script> import { createNamespacedHelpers } from 'vuex' const { mapState } = createNamespacedHelpers('user') // 命名空间的参数是模块名,这时mapState就包含了user模块 export default { computed:{ ...mapState({ userName: state => state.userName // 这样就可以不用state.user.userName这样指向模块名再指向变量了 }) } } </script> ~~~ 或者也可以不用 **createNamespacedHelpers**, 用 **mapState** 直接写,如下: **store.vue** ~~~ <template> <div> <p>{{ userName }}</p> </div> </template> <script> import { mapState } from 'vuex' export default { computed:{ ...mapState('user', { // 第一个参数是模块名 userName: state => state.userName // 这里依旧不用像state.user.userName这样指向模块名再指向变量 }) } } </script> ~~~ >[success] ## getter 1. **getter** 可以理解为组件里的 **计算属性** ,下面的代码中是 **计算属性** 的使用方法: **store.vue** ~~~ <template> <div> <input type="text" v-model="inputVal"> 计算值:{{ inputValueLastLetter }} </div> </template> <script> export default{ name: 'demo', data(){ return{ inputVal: '' } }, computed: { inputValueLastLetter(){ return this.inputVal.substr(-1, 1) // 截取字符串的最后一位 } } } </script> ~~~ 2. **getter**是**vuex** 中的 **计算属性** ,为了提前做好准备,首先创建一个 **getters.js** 文件 **store/getters.js** ~~~ const getters = { // 这里写Vuex的计算属性 } export default getters ~~~ 3. 然后将 **getters.js** 引入到 **store/index.js** 中 **store/index.js** ~~~ import Vue from 'vue' import Vuex from 'vuex' import state from './state' // state.js文件可以不写.js结尾,这样写也会自动找到state.js文件 import getters from './getters' import mutations from './mutations' import actions from './actions' import user from './module/user' // 引入模块文件 Vue.use(Vuex) export default new Vuex.Store({ state, // ES6对象简写的形式,state: state 等同与 state getters, mutations, actions, modules: { // 模块引用 user } }) ~~~ >[success] ### 使用方法 1. **访问根状态的getter** **store/state.js** ~~~ const state = { appVersion: 1.0 } export default state ~~~ **store/getters.js** ~~~ const getters = { // state代表当前同级别(state.js)里的state appNameWithVersion: (state) => { return state.appVersion + 0.1 } } export default getters ~~~ 上面 **计算属性** 的 **第一个参数state** ,实际上就是 **store/state.js** 中的变量,然后在组件中 **使用getter** **store.vue** ~~~ <template> <div> {{ appNameWithVersion }} </div> </template> <script> export default{ name: 'demo', computed: { appNameWithVersion(){ return this.$store.getters.appNameWithVersion } } } </script> ~~~ 2. **访问模块中的getter** ,这里使用的是 **Vuex** 提供的工具方法 **mapGetters** 来获取 **getter** **** 2.1 **mapGetters配合命名空间使用** **store/module/user.js** ~~~ const state = { userName: '小明' } const mutations = { // } const actions = { // } const getters = { firstLetter: (state) => { // 定义getter return state.userName.substr(0, 1) } } export default { namespaced: true, getters, state, mutations, actions } ~~~ 使用 **mapGetters** 配合 **命名空间** 获取 **module(模块)** 中的 **getter** 一定要设置 **namespaced: true** ,然后组件里这样使用 **store.vue** ~~~ <template> <div> {{ firstLetter }} </div> </template> <script> import { mapGetters } from 'vuex' export default{ name: 'demo', computed: { // 获取根getter写法 // ...mapGetters(['appNameWithVersion']) // 获取模块getter写法 ...mapGetters('user',['firstLetter']) // ...mapGetters('模块名',['getter名']) } } </script> ~~~ 或者可以使用 **mapGetters** 配合 **Vuex** 提供的 **createNamespacedHelpers** 方法一起使用来获取 **模块** 中的 **getter** **store.vue** ~~~ <template> <div> {{ firstLetter }} </div> </template> <script> import { createNamespacedHelpers } from 'vuex' const { mapGetters } = createNamespacedHelpers('user') // createNamespacedHelpers('模块名称') export default{ name: 'demo', computed: { // 获取模块getter写法 ...mapGetters(['firstLetter']), // ...mapGetters(['getter名']) } } </script> ~~~ 2.2 **直接使用mapGetters获取【模块】以及【根状态】 的 【getter】(不配合命名空间使用)** 上面的例子是配合 **命名空间** 使用 **mapGetters** ,以及在 **命名空间** 的情况下用 **mapGetters** 配合**createNamespacedHelpers** 一起使用看起来 **比较繁琐** ,实际上 **mapGetters 不使用命名空间也是可以直接获取到 根状态 和 模块 中的getter** 如下: 1. **根状态下的 state 跟 getter** **store/state.js** ~~~ const state = { appVersion: 1.0 } export default state ~~~ **store/getters.js** ~~~ const getters = { // state代表当前同级别(state.js)里的state appNameWithVersion: (state) => { return state.appVersion + 0.1 } } export default getters ~~~ 2. **模块下的 state 跟 getter** **store/module/user.js** ~~~ const state = { userName: '小明' } const mutations = { // } const actions = { // } const getters = { firstLetter: (state) => { // 定义getter return state.userName.substr(0, 1) } } export default { // namespaced: true, // 注意这里没有开启命名空间 getters, state, mutations, actions } ~~~ 3. **在组件中使用 mapGetters 获取 【根状态】 、 【模块中】的 getter** **store.vue** ~~~ <template> <div> {{ firstLetter }} {{ appNameWithVersion }} </div> </template> <script> import { mapGetters } from 'vuex' export default{ name: 'demo', computed: { // 直接使用mapGetters获取【模块】、【根状态】中的getter即可 ...mapGetters(['firstLetter','appNameWithVersion']), // ...mapGetters(['getter名']) } } </script> ~~~