在上一篇当中讲到关于接口请求函数获取数据,拿到 response.data ,简化调用,那么在拿到请求的响应数据之后呢?在前面讲到组件间的通信当中,如父子通信(父传子props,子传父$emit)以及组件与组件之前不能通过直接通信,但可以通过间接的方式,即中间人模式,这种方式仍存在问题,到后续通过事件中心的方式来进行处理,这当中也反应了一些问题:1.传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。2.经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。那么Vue也提供了相应的方案 —— Vuex 状态管理模式 !
那么在本篇当中就来开讲关于在项目当中来如何使用Vuex状态管理,这里可能有人在想是不是vue项目开发都需要使用Vuex来进行状态的管理呢,显然不是,具体什么时候用?官话如下:
简单来讲若项目简单就不需要,建议使用store模式; 若项目较大,建议使用Vuex来管理;这个需要对项目有一定的了解以及对Vuex的了解了!才疏学浅,仅是笔者的愚见,望海涵!
安装Vuex
npm i -S vuex
创建Vuex整体结构
/store/index.js 这个文件是初始化项目生成的,也是Vuex最核心的管理对象store,分别将里面的核心对象作为模块来导入;可以对应的来创建这些模块文件 :
/store/state.js —— 状态对象
/store/getters.js —— 基于state的getter计算属性
/store/mutaions.js —— 直接更新state
/store/actions.js —— 通过mutaions间接更新state/store/mutaions-types.js —— mutaions的type名称常量
在 /stroe/index.js 文件当中分别引入这些模块;
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import getters from './getters'
import mutations from './mutations'
import actions from './actions'Vue.use(Vuex)export default new Vuex.Store({state,getters,mutations,actions
})
state
现在需要获取一些轮播数据列表,通过数据请求的方式获取,然后直接保存到swiperList当中,通过v-for指令渲染,那么如果需要在其他组件当中去使用的话就需要数据传递,或是重新对数据进行请求,那么这时就可以将他作为一个共享的数据,在state中来定义swiperList,而不在当前组件的data中定义;
/* state 共享数据状态 */export default {swiperList: [] // swiperList-轮播列表
}
mutation-types
创建 /store/mutation-types.js 文件来定义mutation中的type常量,当然也可以不用,但在项目中尽可能保证项目的一个结构:
/* mutation的type常量 */export const RECEIVE_SWIPERLIST = 'receive_swiperList' // 接收轮播数据
actions
异步请求swiperList的轮播列表数据,如果是从前面的文章内容学习到这里可能有的对于同步以及异步数据请求还不大了解,那么在后续会来将同步和异步请求;
/* 通过mutation间接更新state */import { reqSwiperList } from '../api'
import { RECEIVE_SWIPERLIST } from './mutation-types'export default {// 异步请求 —— 获取swiperList数据async getSwiperList ({ commit }) {const result = await reqSwiperList()if (result.meta.status === 200) {const swiperList = result.data.swiperListcommit(RECEIVE_SWIPERLIST, { swiperList })}}
}
[ 小白注解 ] :这个部分其实看过上一篇内容的就可能不陌生,reqSwiperList() 就是通过调用封装各接口函数中的reqSwiperList方法,现在来看一下该接口函数:/api/index.js (之前的接口省略)
/* 封装各接口函数 */
// 引入ajax接口请求函数模块
import ajax from './ajax'
export const reqSwiperList = () => ajax('/api/swiperList')
这里同时用了反向代理处理了跨域 —— 配置vue.config.js ,在前面这块内容也有详细的讲解;
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,lintOnSave: false,devServer: {proxy: {'/api': {target: 'http://127.0.0.1:3000',changeOrigin: true}}}
})
到这里你可能就理解了reqSwiperList()这块 ,那么判断 result.meta.status 则需要看一下API文档,那么这里就直接来看一下请求回来的数据看一下吧!
通过状态码status===200判断是否请求成功,成功会返回数据,可以看到data当中的数据,这里用的是本地搭建Node服务器,可以看一下微信小程序搭载node.js服务器(简)这篇文章搭建一下最简单的测试一下;result.data.swiperList 为什么不直接去交给state中swiper就可以了,而是要 commit ( RECEIVE_SWIPERLIST,{ swiperList } ) ,commit是提交,提交给到mutation去,并将swiperList的数据一并带过去,如果在actions直接交给state赋值,就会导致数据不在被监控了,后续出现问题会无迹可寻;进行提交到mutation;
mutation
commit ( RECEIVE_SWIPERLIST,{ swiperList } ) 提交到 mutation 中 ;mutation可以直接来修改 state 的数据状态,所以将提交过来的数据赋值给到state.swiperList即可;
/* 直接更新state的多个方法 */
import { RECEIVE_SWIPERLIST } from './mutation-types'export default {[RECEIVE_SWIPERLIST] (state, { swiperList }) {state.swiperList = swiperList}
}
这样一来这整个过程就到结束了,state中的swiperList就有了,下面来测试一下,通过 vue的拓展工具 devtools 来进行查看:
下面如何来组件当中如何进行使用该共享数据呢?这里现来main.js中注册store,一般创建项目的话 store 就已经注册好了!
渲染 state 数据
1 ) 在mounted生命周期中,通过 dispatch 来触发 actions 调用 ;this.$store.dispatch()
<!-- App.vue -->
<template><div id="app"><li v-for="item in $store.state.swiperList" :key="item.goods_id"><img :src="item.imgUrl" alt=""></li></div>
</template>
<script>
export default {mounted () {this.$store.dispatch('getSwiperList')}
}
</script>
2 ) 测试运行一下:
3)现在如果不在App.vue中渲染,改在MusicView.vue组件(前面内容讲解的留下的)中去调用,需要去父传子,子传父等进行通信传递吗?不需要的,state中的数据就是共享的;下面来这个组件(MusicView.vue)中渲染,同样在 mounted 生命周期中通过 this.$store.dispatch() 来触发 actions 调用 ;
<!--MusicView.vue-->
<template><div><h3>分享音乐社区</h3><router-link to="/music/kugou" active-class="chosen_cl"><li>分享酷狗Music</li></router-link><router-link to="/music/kuwo" active-class="chosen_cl"><li>分享酷我Music</li></router-link><router-view></router-view><li v-for="item in $store.state.swiperList" :key="item.goods_id"><img :src="item.imgUrl" alt=""></li></div>
</template>
<script>
export default {mounted () {this.$store.dispatch('getSwiperList')}
}
</script>
<style lang="scss">.chosen_cl{color:skyblue;font-weight: bold;}img{width: 200px;}
</style>
那么本篇的内容就到此结束了,讲了如何引入使用 vuex 状态管理模式,以及通过一个简单的例子,如何进行异步请求数据保存到 state 和 通过 this.$store.dispatch() 来触发 actions 的调用 ;那么可能有些读者是一些初学者或者跟着前面的篇目学习的,对于这篇的内容有点小难度,那么会在后续出这么一篇关于同步和异步请求数据的篇目加强和巩固相关知识点,最后感谢大家的支持!