引言
在现代Web开发中,前端应用变得越来越复杂。随着应用规模的扩大和数据流的复杂性增加,有效地管理应用的状态成为了一项重要任务。Vue.js作为一种流行的JavaScript框架,提供了Vuex这个强大的状态管理库,旨在解决这个问题。本文将深入探讨Vuex的核心概念和特点,并通过实际案例展示如何使用Vuex进行数据获取、值变更和异步请求。
1. Vuex的简介
1.1 什么是Vuex?
Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态的一致性和可预测性。Vuex的设计灵感来自于Flux和Redux,但针对Vue.js的特点进行了优化和扩展。
1.2 Vuex的核心概念
在使用Vuex之前,我们需要了解其核心概念:
- State:即应用的状态,保存在一个单一的JavaScript对象中。通过this.$store.state可以访问状态。
- Mutation:用于变更状态的方法,每个mutation都有一个字符串的事件类型和一个回调函数。通过commit方法触发mutation。
- Getter:类似于组件中的计算属性,用于从state中派生出一些状态。通过this.$store.getters可以访问getter。
- Action:用于处理异步操作或批量提交mutation的方法。通过dispatch方法触发action。
2. Vuex的值获取与改变(综合案例)
首先,需要两个页面
page1
<template> <div> <h1>page1</h1> <p>改变state的值</p> 请输入:<input v-model="msg"/> <button @click="fun1">获取state</button> <button @click="fun2">改变state</button> </div> </template> <script> export default{ data(){ return { msg:'mrz' } },methods:{ fun1(){ alert(this.$store.state.eduName) },fun2(){ this.$store.commit('setEduName',{ eduName:this.msg }) } } } </script> <style> </style> • 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
page2
<template> <div><h1>page2</h1> {{eduName}} </div> </template> <script> export default{ data(){ return { msg:'mrz' } },computed:{ eduName(){ return this.$store.getters.getEduName; } } } </script> <style> </style> • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22 • 23 • 24
配置路由
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import Login from '@/views/Login' import Register from '@/views/Register' import AppMain from '@/components/AppMain' import LeftNav from '@/components/LeftNav' import TopNav from '@/components/TopNav' import AddBook from '@/views/book/AddBook' import BookList from '@/views/book/BookList' import page1 from '@/views/vuex/page1' import page2 from '@/views/vuex/page2' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Login', component: Login }, { path: '/Register', component: Register }, { path: '/AppMain', name: 'AppMain', component: AppMain, children:[ { path: 'LeftNav', name: 'LeftNav', component: LeftNav }, { path: 'TopNav', name: 'TopNav', component: TopNav }, { path: '/book/AddBook', name: 'AddBook', component: AddBook }, { path: '/book/BookList', name: 'BookList', component: BookList }, { path: '/vuex/page1', name: 'page1', component: page1 }, { path: '/vuex/page2', name: 'page2', component: page2 } ] } ] }) • 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 • 66 • 67 • 68 • 69
建包store以及五个js文件
state.js
export default{ eduName:'唱歌会跑调Y' } • 1 • 2 • 3 • 4
mutations.js
export default{ setEduName:(state,payload)=>{ state.eduName = payload.eduName } } • 1 • 2 • 3 • 4 • 5 • 6 • 7
getters.js
export default{ getEduName:(state)=>{ return state.eduName; } } • 1 • 2 • 3 • 4 • 5 • 6
index.js
import Vue from 'vue' import Vuex from 'vuex' import state from './state' import getters from './getters' import actions from './actions' import mutations from './mutations' Vue.use(Vuex) const store = new Vuex.Store({ state, getters, actions, mutations }) export default store • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16
配置main.js(import store from ‘./store’)
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' //开发环境下才会引入mockjs // process.env.MOCK && require('@/mock') // 新添加1 import ElementUI from 'element-ui' // 新添加2,避免后期打包样式不同,要放在import App from './App';之前 import 'element-ui/lib/theme-chalk/index.css' import App from './App' import router from './router' import store from './store' // 新添加3 Vue.use(ElementUI) Vue.config.productionTip = false /* eslint-disable no-new */ import axios from '@/api/http' import VueAxios from 'vue-axios' Vue.use(VueAxios,axios) new Vue({ el: '#app', router, store, data(){ return{ Bus:new Vue() } }, components: { App }, template: '<App/>' }) • 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
- 这样获取和改变就OK了,看看效果
点击改变
page2的值发生改变
3. Vuex的异步请求
3.1 异步请求的必要性
在现代Web应用中,我们经常需要进行异步操作,如获取后端数据、发送网络请求等。Vuex提供了一种机制来处理这种场景,并保证状态的一致性。
3.2 使用Actions进行异步操作
在Vuex中,我们可以定义actions来进行异步操作。以下是一些使用actions的示例:
page1
<template> <div> <h1>page1</h1> <p>改变state的值</p> 请输入:<input v-model="msg" /> <button @click="fun1">获取state</button> <button @click="fun2">改变state</button> <button @click="fun3">改变state</button> <button @click="fun4">请求后台</button> </div> </template> <script> export default { data() { return { msg: 'mrz' } }, methods: { fun1() { alert(this.$store.state.eduName) }, fun2() { this.$store.commit('setEduName', { eduName: this.msg }) }, fun3() { this.$store.dispatch('setEduNameAsync', { eduName: this.msg }) }, fun4() { this.$store.dispatch('setEduNameAjax', { eduName: this.msg, _this:this }) } } } </script> <style> </style> • 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
actions.js
export default{ setEduNameAsync:(context,payload)=>{ setTimeout(function(){ context.commit('setEduName',payload) },15000) }, setEduNameAjax:(context,payload)=>{ let _this = payload._this let url = _this.axios.urls.Vuex_Ajax; let params = { resturantName: payload.eduName } _this.axios.post(url, params).then(r => { console.log(r) }).catch(e => { }) } } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20
- 同步用commit,异步用dispatch,期间主页this的局限,在actions.js调用不到全局this的实例,需要用传参代替,将参数带过去,才能发送Ajax请求.
- 另外,注意http发送请求超时时间,一般设置为10秒,超过10秒及超时,则不会相应数据,在用deBug的情况下经常会出现数据相应不到的情况,需注意!!!
// axios默认配置
axios.defaults.timeout = 10000; // 超时时间
总结
本文深入介绍了Vuex的核心概念和特点,并通过三个大目录展示了在实际应用中如何使用Vuex进行状态管理。我们学习了如何获取和改变Vuex中的值,以及如何处理异步请求。Vuex作为Vue.js生态系统中的重要组成部分,在复杂应用开发中扮演着关键的角色。希望本文对于理解和应用Vuex有所帮助。