Elctron-vue實戰(三)— Vuex管理Mock數據

關於vuex的簡單理解在這篇文章中已經提過了,如何在vuex中管理mock數據呢。

效果圖
這是效果界面,所用的數據是mock模擬所得,使用vuexstore存儲管理模擬數據。
在這裏插入圖片描述
這是我的store目錄結構,分成幾個模塊,以其中planList模塊爲例進行講解。

1.配置Vuex

modules文件夾中新建一個文件planList.js,然後在modules/index.js中導入


import planList from './planList'
const files = require.context('.', false, /\.js$/)
const modules = {
  planList // 模塊名
}

files.keys().forEach(key => {
  if (key === './index.js') return
  modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
})

export default modules

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import modules from './modules'
// const strict = process.env.NODE_ENV !== 'production'
const strict = false // 當爲嚴格模式下時,一切的更改狀態的動作都只能在mutation中進行,否則報錯
Vue.use(Vuex)

export default new Vuex.Store({
  modules,
  strict: strict
})

然後在主文件main.js中引用:

import store from './store'

new Vue({
  components: {
    App
  },
  router,
  store,
  template: '<App/>'
}).$mount('#app')

2.Mock數據

在這裏插入圖片描述
關於如何mock數據可以去官網查看,這裏只粘貼部分代碼,不再多說

// data/planList.js
import Mock from 'mockjs'
const Random = Mock.Random
const List = []
const count = 300

for (let i = 0; i < count; i++) {
  List.push(Mock.mock({
    id: Random.integer(6000, 6999), // 編號
    airline: Random.string('upper', 2), // 航空公司
    flightNum: Random.string('upper', 2) + Random.integer(1000, 9999), // 航班號
    'cityCode|1': ['京', '津', '冀', '晉', '內蒙古', '遼', '吉', '黑', '滬', '蘇', '浙', '皖', '閩', '贛', '魯', '豫', '鄂', '湘', '粵', '桂', '瓊', '川', '貴', '雲', '渝', '藏', '陝', '甘', '青', '寧', '新'], // 城市簡碼
    
  }))
}

export { List }

然後攔截數據,這裏使用的是axios-mock-adapter,可以使用npm install axios-mock-adapter -D進行安裝,然後在mock.js中引入:

import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'
import { List } from './data/planList'

let _planList = List

export default {
  bootstrap () {
    let mock = new MockAdapter(axios)

    // mock success request
    mock.onGet('/success').reply(200, {
      msg: 'success'
    })

    // mock error request
    mock.onGet('/error').reply(500, {
      msg: 'failure'
    })
      
    // 獲取列表(分頁)
    mock.onGet('/flight/getListPage').reply(config => {
      let { page, pageSize, id } = config.params
      let mockList = _planList.filter(item => {
        if (id && item.name.indexOf(id) === -1) return false
        return true
      })
      let total = mockList.length
      mockList = mockList.filter((u, index) => index < pageSize * page && index >= pageSize * (page - 1))
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve([200, {
            total: total,
            list: mockList
          }])
        }, 1000)
      })
    })
  }
}

3.封裝axios

新建一個api文件夾,建立request.js文件,封裝請求。
在這裏插入圖片描述

import axios from 'axios'
import { Message } from 'element-ui'
import store from '../store'

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
// 創建axios實例
const instance = axios.create({
  baseURL: process.env.BASE_API, // api的base_url
  timeout: 3000 // 請求超時時間
})
// request攔截器
instance.interceptors.request.use(config => {
  if (store.getters.token) {
    config.headers['X-Token'] = store.getters.token// 讓每個請求攜帶自定義token 請根據實際情況自行修改
  }
  return config
}, error => {
  console.log(error) // for debug
  Promise.reject(error)
})

// 響應攔截器
instance.interceptors.response.use(
  response => {
  /**
  * code不是200時拋錯 可結合自己業務進行修改
  */
    const res = response.data
    if (res.code !== 200) {
      Message({
        message: res.message,
        type: 'error',
        duration: 5 * 1000
      })

      return Promise.reject('error')
    } else {
      return response.data
    }
  },
  error => {
    console.log('err' + error)// for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default function (method, url, data = null) {
  method = method.toLowerCase()
  if (method === 'post') {
    return instance.post(url, data)
  } else if (method === 'get') {
    return instance.get(url, {
      params: data
    })
  } else if (method === 'delete') {
    return instance.delete(url, {
      params: data
    })
  } else if (method === 'put') {
    return instance.put(url, data)
  } else {
    console.error('未知的method' + method)
    return false
  }
}

然後在api.js中封裝接口:

// import request from './request'
import axios from 'axios'

let baseURL = ''
// 獲取計劃列表
export const getPlanList = params => {
  return axios.get(`${baseURL}/flight/planList`, { params: params })
}

// 獲取列表分頁
export const getPlanListPage = params => {
  return axios.get(`${baseURL}/flight/getListPage`, { params: params })
}

// index.js中導入
import * as api from './api'

export default api

4.vuex中管理mock數據

modules/planList.js中調用接口,將獲取到的mock數據保存在本地state中,然後組件中調用相應的數據進行渲染顯示即可:

import { getPlanListPage } from '@/api/api' // 接口
import { GET_PLAN_LIST } from './mutation-type' // mutation類型常量化 在mutation-type.js中進行配置即可,也可以不用這樣寫,詳情可見官方文檔

export default {
  namespaced: true,// 啓動命名空間
  state: {// 聲明本地管理的狀態
    list: {
      tableData: [],
      total: 0,
      currentPage: 1,
      pageSize: 20,
      listLoading: false,
      id: ''
    }
  },
  getters: {
    list: state => state.list
  },
  mutations: {
    [GET_PLAN_LIST]: state => {
      let para = {
        page: state.list.currentPage,
        pageSize: state.list.pageSize,
        id: state.list.id
      }
      state.list.listLoading = true
      getPlanListPage(para)
        .then(res => {
          console.log(res.data)
          // 將獲取的數據保存在state中全局使用
          state.list.total = res.data.total
          state.list.tableData = res.data.list
          state.list.listLoading = false
        })
        .catch(error => {
          console.log(error)
        })
    }
  },
  actions: { // 異步響應
    getPlanList: context => {
      context.commit('GET_PLAN_LIST')
    }
  }
}

5.組件中獲取狀態

import { mapGetters, mapActions, mapMutations } from 'vuex'
mounted () {
    this.getPlanList() // 掛載
  },
  computed: {
    ...mapGetters('planList', ['list'])
  },
  methods: {
    ...mapActions('planList', ['getPlanList']),
    ...mapMutations('planList', ['GET_PLAN_LIST']),
    // 顯示每頁多少條數據
    handleSizeChange (val) {
      this.list.pageSize = val
      this.list.currentPage = 1
      this.GET_PLAN_LIST()
    },
    // 當前頁
    handleCurrentChange (val) {
      this.list.currentPage = val
      this.GET_PLAN_LIST()
    }
  }
<!-- 這裏只粘貼了表格的代碼 從list中調用數據-->
        <el-table 
          :data="list.tableData" 
          highlight-current-row 
          style="width: 100%;margin-bottom: 20px;"
          height="800px"
          v-loading="list.listLoading"
          size="medium"
          class="planListTable el-table__column-filter-trigger"
          @cell-dblclick="rowDbClick"
          >
          <!-- <el-input placeholder="搜索" v-model="filters" clearable></el-input> -->
          <el-table-column fixed type="index" align="center" min-width="50px"></el-table-column>
          <el-table-column fixed  label="編號" align="center" min-width="85" sortable resizable>
            <div slot-scope="scope" >
              <el-input size="small" v-model="scope.row.id" @change="handleEdit(scope.$index, scope.row)"></el-input>
              <span>{{scope.row.id}}</span>
            </div>
          </el-table-column>
          <el-table-column fixed prop="airline" label="航空公司" align="center" min-width="120" sortable resizable></el-table-column>
          <el-table-column fixed prop="flightNum" label="航班號" align="center" min-width="120" sortable resizable></el-table-column>
          <el-table-column prop="cityCode" label="城市簡碼" align="center" min-width="120" sortable resizable></el-table-column>
        </el-table>

        <el-col :span="24" class="">
          <el-pagination 
            background
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="list.currentPage"
            :page-sizes="[20, 50, 100]"
            :page-size="list.pageSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="list.total"
            style="float:right;"
            >
          </el-pagination>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章