上节课我们布置了阅读统计的作业,但是并没有讲状态管理。所以这节课,我们先来讲状态管理。
由于状态零散地分布在许多组件和组件之间的交互中,大型应用复杂度也经常逐渐增长。为了解决这个问题,Vue 提供 vuex1.
Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择2。
首先,我们大致了解一下什么是前端状态。
所有程序都有“状态”,状态表现在代码中其实就是各种类型的变量,其实程序运行的过程就可以理解为是程序内部的“状态“发生改变的过程,而我们编写的程序就是在控制这些“状态”如何发生改变。比如说,这次作业里的阅读统计数就是一种状态。
在了解完前端状态以后,接下来就让我们从零开始打造一个简单的状态管理。
新建一个store文件夹,并在该文件夹下新建一个index.js文件。
/*
* @Author: CaesarDing
* @Mail: [email protected]
* @Date: 2022-04-24 13:23:31
* @LastEditors: CaesarDing
* @LastEditTime: 2022-04-24 13:51:16
* @FilePath: /my_first_vue/my-vue-app/src/store/index.js
* @Description:
*/
import {reactive} from 'vue'
const store = {
debug: true,
state: reactive({ // reactive 方法可以让对象成为响应式对象
count: 0
}),
addCountAction(){
if (this.debug) {
console.log('增加阅读计数,当累积计数', this.state.count)
}
this.state.count += 1
},
getCountAction(){
return this.state.count
}
}
export default store
看完刚才新建的store,大家是不是有一种似曾相识的感觉?没错就是SpringBoot里面的对象。需要注意,所有 store 中 state 状态的变更,都放置在 store 自身的 action 方法 中去管理。这种集中式状态管理能够被更容易地理解哪种类型的变更将会发生,以及它们是如何被触发。当错误出现时,现在也会有一个 log 记录 bug 之前发生了什么。
在创建完store对象以后,我们需要把它导入我们需要的地方。
因为时间有限,这里不过多讲解created的使用,强烈建议大家在课后自行阅读:Vue.js生命周期钩子
<script>
import store from '../store/index.js' // 导入store对象
export default {
created() { //当视图被创建时会执行这个函数
store.addCountAction();
},
}
script>
<template lang="">
<div>
<h1>阅读统计h1>
<p>在过去的一段时间里,您累计产生{{count}}次阅读p>
div>
template>
<script>
import store from '../store/index.js' // 导入状态管理
export default {
data() {
return {
count: 0
}
},
created() { //当视图被创建时会执行这个函数
this.count = store.getCountAction();
},
}
script>
<style lang="">
style>
最终效果
相信大家或多或少已经了解过ajax,而这节课我将会介绍一种和ajax类似的技术——axios.Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
npm install axios
现在已经是第四节课了,假设大家已经对服务端接口的使用熟稔于心。那么接下来,我将会带着大家去调用服务端接口,进行前后端交互,最终实现信息页面的全部内容。
同样,我们先在src目录下封装一个utils/axios.js
文件。
/*
* @Author: CaesarDing
* @Mail: [email protected]
* @Date: 2022-04-24 14:40:02
* @LastEditors: CaesarDing
* @LastEditTime: 2022-04-24 15:46:39
* @FilePath: /my_first_vue/my-vue-app/src/utils/axios.js
* @Description:
*/
import axios from 'axios'
//请将baseURL替换成你自己的服务器地址和端口号
axios.defaults.baseURL = process.env.NODE_ENV == 'development' ? '//rest.apizza.net/mock/849d0956c4ceb50ba864859f0f50cf88/' : '//'
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
axios.defaults.headers.post['Content-Type'] = 'application/json'
//设置拦截器
axios.interceptors.response.use(res => {
if (res.status === 200) {// 正常情况
return Promise.resolve(res.data)
} else {
alert('Error!')
return Promise.reject(res)
}
})
export default axios
封装完成以后,我们再在src新建一个service/info.js
文件重写axios实例。
/*
* @Author: CaesarDing
* @Mail: [email protected]
* @Date: 2022-04-24 14:55:37
* @LastEditors: CaesarDing
* @LastEditTime: 2022-04-24 15:54:42
* @FilePath: /my_first_vue/my-vue-app/src/service/info.js
* @Description:
*/
import axios from '../utils/axios'
//获取信息列表
export function getInfoList() {
return axios.get('/info/getInfoList');
}
//获取信息详细
export function getInfoDetail(id) {
return axios.post(`/info/detail`,id);
}
重写完成后,我们回到Info.vue和InfoDetail.vue页面进行调用.
<script>
//导入axios实例
import { getInfoList } from '../service/info.js'
export default {
data() {
return {
infoList: [],
}
},
created() {
getInfoList().then(result => {
this.infoList = result
}).catch(err=>{
console.log("error message:",err)
})
},
}
script>
<template lang="">
<div>
<h1>{{ title }}h1>
<div class="content" v-html="detail">div>
div>
template>
<script>
import { getInfoDetail } from '../service/info.js';
import store from '../store/index.js' // 导入状态管理
export default {
data() {
return {
title:'',
detail: '',
}
},
created() {
store.addCountAction();
const id = this.$route.params.infoId; //获取当前文章的id
getInfoDetail(id).then(res =>{
this.title = res.title
this.detail = res.detail
})
},
}
script>
最后再让我们添加一些样式,我们的咖啡屋就做好啦。
至此,我们为期四周的前端培训内容就告一段落了。希望通过这段时间的学习,大家都能有所收获!
你可以在Gitee上找到本项目的全部代码(有彩蛋哦 ):
https://gitee.com/caesarding/vue-js-project-basic-learning
Store ↩︎
什么是“状态管理模式” ↩︎