vuex(二)Action

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。
快速构建一个express服务模拟后台响应数据:
var express = require("express");
var app = express();

app.get("/api/carList", (req, res)=>{
	res.json({
		code: 0,
		data: [{
			title: "东风标致", id: 8, buy: false
		},{
			title: "广州本田", id: 9, buy: true
		},{
			title: "一汽大众", id: 6, buy: true
		},{
			title: "东风悦达", id: 7, buy: true
		},{
			title: "长安铃木", id: 5, buy: false
		}]
	})
});
app.listen("8090", ()=> console.log("OK"));

同时配置代理解决同源策略问题:打开项目下config文件夹中的index.js找到proxyTable对象,一般默认是个空对象,加入代理配置:

 proxyTable: {//配置代理
        "/api":{//将/api开头的请求都代理到下面地址
            target: 'http://localhost:8090',
            changeOrigin: true
            //redirectUrl:{}
        }
    },

定义actions事件,引入axios:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

import {CHANGECOUNT} from './mutation-types';
import axios from 'axios';

const store = new Vuex.Store({//创建仓库实例
	state:{//仓库中存放数据的地方
		count: 2,
		products: []
	},
	getters: {//配置从state中衍生出来的数据
		tobuy(state){//默认第一个参数就是store的state
			return state.products.filter(v => v.buy);
		},
		nottobuy(state){
			return state.products.filter(v => !v.buy)
		}
	},
	mutations: {
		[CHANGECOUNT](state, payload){//第二个参数就是组件中传递过来的载荷
			state.count += payload;
		}
	},
	actions: {//做异步操作,成功后commit mutation
		fatchList({commit}){//回调函数的参数是一个和store具有相同属性的对象,但是一般不直传store,需要什么属性直接结构出来
			//这里用express在本地快速模拟了后台响应数据,不过要配置代理,在
			axios.get('/api/carList').then(res =>{
				console.log(res.data.data)
			})
		}
	}
})
export default store;

在事件函数中调用action:

methods: {
			handleCount(){
				 this.$store.commit(CHANGECOUNT, 5)//提交一个名为changeCount的mutation,第二个可选参数表示载荷,也可以是一个对象传入,也可以将type和载荷写成一个对象传入{type: 'changeCount', payload: 5}

				 this.$store.dispatch('fatchList');//提交一个包含异步请求的Action
				 console.log(this.count)

			}
		}

点击按钮获得数据:


不过我们最终的目的是要通过action来执行异步并且修改state,所以还要定义一个mutation事件,这个事件在action的异步完成获取到数据后执行:

mutations: {
		[CHANGECOUNT](state, payload){//第二个参数就是组件中传递过来的载荷
			state.count += payload;
		},
		[FATCHLIST](state, products){
			// state.products = products;//可以像这样直接赋值,但是一般不会这么做,因为多数情况是分页加载(添加数据)
			state.products = [...state.products, ...products];//利用扩展运算符这样解决了上面写法的小问题
		}
	},
	actions: {//做异步操作,成功后commit mutation
		[FATCHLIST]({commit}){//回调函数的参数是一个和store具有相同属性的对象,但是一般不直传store,需要什么属性直接结构出来
			//这里用express在本地快速模拟了后台响应数据,不过要配置代理,在
			axios.get('/api/carList').then(res =>{
				commit(FATCHLIST, res.data.data);
			})
		}
	}

这里同样已经将mutation事件名在外部文件中定义成常量并引入了,做了替换。

当点击按钮时,执行fatch请求一次数据,然后执行mutation事件修改一次state,从而渲染一次view:


同样的也有mapActions和mapMutations辅助函数(语法糖):

<template>
	<div class="user">
		<button @click="CHANGECOUNT(5)">改变count</button>
		{{count}}
		<button  @click="handleCount2">获取list</button>
		<hr/>
		<ul>
			<li style="background:green">我要买的:</li>
			<li v-for="(v, i) in tobuy">{{v.title}}</li>
		</ul>
		<ul>
			<li style="background:orange">我不买的:</li>
			<li v-for="(v, i) in nottobuy">{{v.title}}</li>
		</ul>
	</div>
</template>

<script>
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex';//引入语法糖对象
import {CHANGECOUNT} from '../vuex/mutation-types';//引入mutation事件类型名称
	export default{
		data(){
			return {

			}
		},
		computed: {
			// count(){
			// 	return this.$store.state.count;
			// }
			// 当计算属性的key和store的state的属性名相同时可以用mapState,都需要es7...对象扩展运算符:
			...mapState(['count'])//数组语法
			// 当计算属性的key和srote的state的属性名不相同时:用对象语法,此时计算属性名称为counter
			// ...mapState({
			// 	counter: state => state.count
			// })
			,
			tobuy(){//同样state的衍生状态也可以使用语法糖,引入mapGetters,语法跟mapState一样
				return this.$store.getters.tobuy;
			},
			nottobuy(){
				return this.$store.getters.nottobuy;
			}
		},
		methods: {
			// handleCount(){
			// 	 this.$store.commit(CHANGECOUNT, 5)//提交一个名为changeCount的mutation,第二个可选参数表示载荷,也可以是一个对象传入,也可以将type和载荷写成一个对象传入{type: 'changeCount', payload: 5}

			// 	 // this.$store.dispatch('fatchList');//提交一个包含异步请求的Action
			// },

			// ...mapActions(['fatchList']),//view事件函数名称和action事件名称一致时的数组语法
			// 名称不一致时对象语法:
			...mapActions({
				handleCount2: 'fatchList'
			}),

			//mapMutations语法糖有个坑,就是mutation要在view层的事件函数中进行传参(载荷)
			...mapMutations([CHANGECOUNT])
			// ...mapMutations({
			// 	handleCount: CHANGECOUNT
			// })
		}
	}
</script>

<style>
	.user{
		background: red;
	}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值