https://github.com/hzzly/xyy-vue
http://hjingren.cn/2017/03/08/%E8%BF%9B%E9%98%B6vue%E5%85%A8%E5%AE%B6%E6%A1%B6/
https://liuxingzhijian1320.github.io/vuex-shopcart/index.html
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
每一个 Vuex 应用的核心就是 store(仓库)。”store” 基本上就是一个容器,它包含着应用中大部分的状态(state)。
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交(commit) mutations。这样使得我们可以方便地跟踪每一个状态的变化。
整个的流程是在组件的created中提交dispatch,
然后通过action调用一个封装好的axios,
然后再触发mutation来提交状态改变state中的数据,
然后在组件的计算属性中获取state的数据并渲染在页面上
运行命令:npm install vuex --save-dev
在项目的入口js文件main.js中:import store from './store/index'
并将store挂载到vue上:
new Vue({
el: '#app',
router,
store,
template: '<App/>',
render: (createElement) => createElement(App)
})
然后看下整个store的目录结构:
modules文件夹用来将不同功能也面的状态分成模块,
index.js文件夹是store的入口文件,
types文件夹是定义常量mutation的。
文件夹整个vuex的目录结构如下
在store的入口文件index.js中:
// 组装模块并导出 store 的文件
import Vue from 'vue'
import Vuex from 'vuex'
import mine from './modules/mine';
import club from './modules/club';
Vue.use(Vuex);
// 导出需要的模块
export default new Vuex.Store({
modules: {
club,
mine
}
});
点击触发事件----------actions-----------mutations-----------state---------getters
第一步:在组件页面中,点击事件----触发分发actions事件
E:\收藏\xyy-vue\src\pages\Login.vue:
import { mapActions } from 'vuex'------------------------配套写法
...mapActions({ setUserInfo: 'setUserInfo' }),----------配套写法
this.setUserInfo(res.data)-------------------------------配套写法
this.$store.dispatch('setLoadingState', true)------------直接单独写,不需要引用mapActions写法
this.$store.dispatch('setLoadingState', false)
第二步:actions事件触发-----触发mutations
E:\收藏\xyy-vue\src\vuex\modules\com.js:
const actions = {
setLoadingState({ commit }, status) {
commit(types.COM_LOADING_STATUS, status)
},
第三步:查找mutations type类型
E:\收藏\xyy-vue\src\vuex\types.js:
export const COM_LOADING_STATUS = 'COM_LOADING_STATUS'
第四步:mutations (类似于setter操作)
E:\收藏\xyy-vue\src\vuex\modules\com.js:
const mutations = {
[types.COM_LOADING_STATUS](state, status) {
state.loading = status
},
对应到的state信息------变量声明
E:\收藏\xyy-vue\src\vuex\modules\com.js:
const state = {
loading: false,
对应到页面中用到的变量:
E:\收藏\xyy-vue\src\vuex\modules\com.js:
const getters = {
loading: state => state.loading,
E:\收藏\xyy-vue\src\pages\Home.vue:
import { mapGetters } from 'vuex'
computed: {
...mapGetters([
'travelListIndex'
])
},
E:\收藏\xyy-vue\src\fetch\api.js:
import axios from 'axios'
import qs from 'qs'
import * as _ from '../util/tool'
// axios 配置
axios.defaults.timeout = 5000;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
axios.defaults.baseURL = 'http://localhost:4000/';
//POST传参序列化
axios.interceptors.request.use((config) => {
if(config.method === 'post'){
config.data = qs.stringify(config.data);
}
return config;
},(error) =>{
_.toast("错误的传参", 'fail');
return Promise.reject(error);
});
//返回状态判断
axios.interceptors.response.use((res) =>{
if(!res.data.success){
// _.toast(res.data.msg);
return Promise.reject(res);
}
return res;
}, (error) => {
_.toast("网络异常", 'fail');
return Promise.reject(error);
});
export function fetch(url, params) {
return new Promise((resolve, reject) => {
axios.post(url, params)
.then(response => {
resolve(response.data);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
}
export default {
/**
* 用户登录
*/
Login(params) {
return fetch('/users/api/userLogin', params)
},
/**
* 用户注册
*/
Regist(params) {
return fetch('/users/api/userRegist', params)
},
/**
* 发送注册验证码
*/
RegistVerifiCode(tellphone) {
return fetch('/users/api/registVerifiCode', {tellphone: tellphone})
},
/**
* 获取约跑步列表
*/
SportsList() {
return fetch('/api/sportList')
},
/**
* 获取约出行列表
*/
TravelsList() {
return fetch('/api/travelList')
},
/**
* 获取约跑步详情
*/
SportsDetail(id) {
return fetch('/api/sportDetail', {sportId: id})
},
/**
* 获取约出行详情
*/
TravelsDetail(id) {
return fetch('/api/travelDetail', {travelId: id})
},
/**
* 获取出行活动点击次数
*/
travelClicks(id) {
return fetch('/api/travelClickNum', {travelId: id})
},
/**
* 获取用户信息
*/
UserInfo(id) {
return fetch('/users/api/userInfo', {userId: id})
},
/**
* 获取用户发布约行个数
*/
getPubTotravelNum(id) {
return fetch('/users/api/getPubTotravelNum', {userId: id})
},
/**
* 获取用户自己发布的约行
*/
getMyTravel(id) {
return fetch('/users/api/myTravel', {userId: id})
},
/**
* 发布约行活动
*/
PostTravel(params) {
return fetch()
},
/**
* 获取全国JSON数据
*/
getAddressJson() {
return fetch('/api/address')
}
}
E:\收藏\xyy-vue\src\main.js:
// 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'
import App from './App'
import router from './router'
import store from './vuex/store'
import * as filters from './util/filter'
Object.keys(filters).forEach(k => Vue.filter(k, filters[k])) //注册过滤器
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
...App
})
E:\收藏\xyy-vue\src\vuex\store.js:
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import sport from './modules/sport'
import travel from './modules/travel'
import detail from './modules/detail'
import com from './modules/com'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
user,
sport,
travel,
detail,
com
}
})
E:\收藏\xyy-vue\src\vuex\modules\detail.js:
import api from '../../fetch/api'
import * as types from '../types'
const state = {
detail: ''
}
const actions = {
/**
* 获取活动详情
*/
getDetail({ commit }, palyload) {
commit(types.COM_LOADING_STATUS, true)
if(palyload.router == 'sport') {
api.SportsDetail(palyload.id)
.then(res => {
commit(types.COM_LOADING_STATUS, false)
commit(types.GET_SPORTS_DETAIL, res)
})
} else if(palyload.router == 'travel') {
api.TravelsDetail(palyload.id)
.then(res => {
commit(types.COM_LOADING_STATUS, false)
commit(types.GET_TRAVELS_DETAIL, res)
})
}
},
/**
* 活动点击次数
*/
travelClicks({ commit }, id) {
api.travelClicks(id)
.then(res => {
console.log(res)
})
}
}
const getters = {
getDetail: state => state.detail
}
const mutations = {
[types.GET_SPORTS_DETAIL](state, res) {
state.detail = res.data
},
[types.GET_TRAVELS_DETAIL](state, res) {
state.detail = res.data
}
}
export default {
state,
actions,
getters,
mutations
}