搞定获取数据后,在来看一下提交数据,比如注册用户、点赞等等,这就需要往 action 函数传递参数了,这也是 store 使用比较高频的方式。
现在通过登录这个功能来让我们看一下如何通过传递参数去请求数据
登录功能
API
- Api Url
https://www.fastmock.site/mock/a9b15cd4db90d4e03ed76cd3c76d9197/f6/login - Api Method
post - Api 请求参数
{
"username": "string",
"password": "string"
}
- 返回模型
{
"success": boolean,
"data": {
"username": "string",
"email": "string"
}
}
登录成功
测试参数是
{
"username": "admin",
"password": "123456"
}
提交参数后,返回结果是:
{
"success": true,
"data": {
"username": "admin",
"email": "[email protected]"
}
}
Store 定义
继续按照我们之前的顺序,state、mutation、action
state
根据上面的 api 定义,登录成功后会返回 user 对象,那么我们可以把 user 作为 state 属性来定义
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
user: {}
}
});
mutation
我们需要定一个 setUser mutation 函数用于更新 user
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
user: {}
},
mutations: {
setUser(state, payload) {
state.user = payload;
}
}
});
action
由于这次的 api 是 post 参数,所以我们需要使用 axios.post
const response = await axios.post('api...', {
username: 'admin',
password: '123456'
});
现在我们完善一下 action,这次我们需要在增加一下参数,接收外部传递过来的参数
完整的代码如下:
import Vue from "vue";
import Vuex from "vuex";
import axios from "axios";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
user: {}
},
mutations: {
setUser(state, payload) {
state.user = payload;
}
},
actions: {
login: async ({ commit }, param) => {
// 执行远程请求
const response = await axios.post(
"https://www.fastmock.site/mock/a9b15cd4db90d4e03ed76cd3c76d9197/f6/login",
{
username: param.username,
password: param.password
}
);
if (response.data.success) {
commit("setUser", response.data.data);
}
}
}
});
运用
我们最后在 User.vue 文件中添加 store 的依赖和配置,这里我们要把逻辑稍微的处理一下,大家仔细看看 vue 文件
<template>
<div>
<div>
<label>用户名</label>
<input type="text" v-model="username" />
</div>
<div>
<label>密码</label>
<input type="password" v-model="password" />
</div>
<button @click="onLogin">登录</button>
<div v-if="loginError">登录失败</div>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
export default {
data() {
return {
username: "",
password: "",
loginError: false
};
},
computed: {
...mapState({
user: state => state.user
})
},
methods: {
...mapActions(["login"]),
async onLogin() {
// 执行 store 的登录 action
await this.login({
username: this.username,
password: this.password
});
if (this.user && this.user.username) {
// 登录成功,随便跳转一下
window.location.href = "https://m.baidu.com";
} else {
// 登录失败
this.loginError = true;
}
}
}
};
</script>
可以发现使用 store 的 action 的时候有点不一样的是:我们只需要给 action 函数传递第二个参数就可以了,因为第一个参数是 Vuex 的上下文,框架会自动注入的
// store action 定义
actions: {
login: async ({ commit }, param) => {
// 省略
}
}
// vue 中调用
await this.login({
username: this.username,
password: this.password
});