【Vue課序4】保姆級:Vuex異步數據獲取

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中創建若干子文件夾,文件夾由以下構成:

  1. index.vue
  2. images ( 存放靜態圖片資源
  3. service.js ( 處理數據異步接口
  4. store.js ( 管理組件自己的store

4.當我們創建完一個pageindex.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->數據注入頁面 一整套單向數據流。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章