Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何在vuex中管理Mock数据 #2

Open
sueRimn opened this issue Jun 25, 2019 · 0 comments
Open

如何在vuex中管理Mock数据 #2

sueRimn opened this issue Jun 25, 2019 · 0 comments
Labels
code Snippet 代码片段记录 Vue vue的一些小知识片断

Comments

@sueRimn
Copy link
Owner

sueRimn commented Jun 25, 2019

在vuex中管理mock数据

关于vuex的简单理解在这篇文章中已经提过了,如何在vuex中管理mock数据呢。

1561452530347

这是效果界面,所用的数据是mock模拟所得,使用vuexstore存储管理模拟数据。

1561452908386

这是我的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数据

1561454034810

关于如何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文件,封装请求。

1561453905769

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>
@sueRimn sueRimn added Vue vue的一些小知识片断 code Snippet 代码片段记录 labels Sep 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code Snippet 代码片段记录 Vue vue的一些小知识片断
Projects
None yet
Development

No branches or pull requests

1 participant