Store的解耦:
官方提供的是将Vuex注册在src/main.js下,但是为了后来项目store的解藕,我们采取一步到位式配置,参考辉哥React教案中react+redux的设计模式。
1.修改主store.js
,用来集中管理主分支数据,其他分支数据通过import
注入
import Vue from 'vue' // 引入 vue
import Vuex from 'vuex' // 引入vuex
// 引入分支store
import table from '@/page/table/store.js'
// 使用Vuex
Vue.use(Vuex);
// 创建并导出Vuex实例
export default new Vuex.Store({
strict: true,
devtools: true,
plugins: [],
modules: {
table
}
});
2.在src
下创建 page
文件夹,用来存放各自路由组件,page
中一个文件夹对应一个路由(也就是对应一个页面
3.按”2步骤“在page中创建若干子文件夹,文件夹由以下构成:
index.vue
-
images
( 存放静态图片资源 -
service.js
( 处理数据异步接口 -
store.js
( 管理组件自己的store
4.当我们创建完一个page
的index.vue
后一定要去/router
文件夹中的index.js
中注册路由。
import Vue from 'vue'
import Router from 'vue-router'
// 注册路由
import HelloWorld from '@/components/HelloWorld'
import Table from '@/page/table/index'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/Table',
name: 'Table',
component: Table
}]
})
5.在config
文件夹中创建的request.js
export const ip = 'http://127.0.0.1:8081';
export default function request(method, url, body, history) {
method = method.toUpperCase();
if (method === 'GET') {
//fetch的GET不允许有body,参数只能放在url中
body = undefined;
} else {
body = body && JSON.stringify(body);
}
return fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: body
}).then((res) => {
if (res.status === 401) {
history.push('/');
return Promise.reject('Unauthorized.');
} else {
return res.json();
}
});
}
export const get = url => request('GET', url);
export const post = (url, body) => request('POST', url, body);
6.修改service.js
// 只负责异步数据的export
// 相当于dva三大金刚service
import request from '@/../config/request'
import { ip } from '@/../config/request'
/*
* @Description: 获取表单数据
* @param: getMessageAcount
* @return: message
*/
export async function get_table(params) {
let url = ip + '/web/user/rest/getMessageAcount'
return request("POST", url, {
cmd: 'getMessageAcount',
type: 'request',
request: {
description: params.description
}
})
}
7.修改page
目录下分支store.js
// 引入service的异步接口
import { get_table } from './service.js'
// 初始化分支数据
const state = {
table: [ ]
}
// 在vuex中通过mutations更新store
const mutations = {
get_table_success(state, payload) {
// 相当于redux中更新reducer
state.table = payload;
},
get_table_failed() { }
}
const actions = {
// 异步请求await 需要加async ,相同于dva中的call
async get_async(context, payload) {
// 异步操作,等待service的返回值
const record = await get_table(payload);
if (record.response && record.response.res) {
// 后台返回true的数据
let result = record.response.message;
// 括号内指向mutations内的方法
context.commit("get_table_success", result);
} else {
// 后台返回false的数据
context.commit(" get_table_failed");
}
}
}
export default {
namespaced: true, // 声明分模块的store需要加上
state,
mutations,
actions
};
8.修改page
目录中index.vue
<template>
<div class="hello">
<button v-on:click.stop="async_action()">异步请求</button>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {};
},
methods: {
async_action() {
// 括号参数分为两部分:
// 斜杠前为对应的分支模块,斜杠后为分支模块对应的actions
// 格式:模块名/模块中的mutations
// 同样可以携带参数
let description = "这是参数";
this.$store.dispatch("table/get_async", description);
}
}
};
</script>
9.此时通过按钮点击已经完成了异步数据的获取以及更新到了store
,接下来是如何进行页面渲染,在vuex
中有一个类似于 mapDispatchToState
的方法叫做 mapState
, 下面是使用方法:
...mapState({
a: "a"
}),
...mapState({
_state: state => state
}), // 捕获外部状态 此时获取的是完整的store
...mapState(["test"]), // 抓取test分支模块的完整数据
...mapState("test", ["isLogin”]) // 抓取test分支下的 “isLogin" 属性
以上都是 mapState
的使用方法,但日常使用来说 后两者使用度更高。
来让我们接着完成index.vue
中的模块
<template>
<div class="hello">
<button v-on:click.stop="async_action()">异步请求</button>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "HelloWorld",
data() {
return {};
},
methods: {
async_action() {
// 括号参数分为两部分,斜杠前为对应的分支,斜杠后为分支对应的actions
// 格式:模块名/模块中的mutations
// 同样可以携带参数
let description = "这是参数";
this.$store.dispatch("table/get_async", description);
}
},
// 注入外部store 类似于connect
computed: {
...mapState(["table"])
// ...mapState(['x']), 可以注入多个不同模块的store,根据实际情况注入
// ...mapState(['xx']),
// ...mapState(['xxx']),
}
};
</script>
完成以上步骤已经实现了 页面发起异步请求->后台处理并返回数据->更新store->数据注入页面 一整套单向数据流。