美文网首页
Vue实例:医院统一信息平台(获取数据)

Vue实例:医院统一信息平台(获取数据)

作者: 碧波之心 | 来源:发表于2018-06-24 15:51 被阅读375次

    前端主要的任务是向用户获取数据或者向用户展示数据。现在我们还没有向服务器取数据,数据本身应该是存储在服务器上的。只是现在还没有连接服务器,先在本地按格式模拟些数据。

    常用组件

    在这里,我们用到了 vuex来保存页面状态,比如页面当前的筛选值,分页的当前页等。

    npm i vuex -S
    

    这里用到了时间,实际上在大多项目中都会频繁地使用。项目中用moment.js处理时间相关的操作。

    npm i moment -S
    

    模拟数据

    前后端分离的架构中,前端开发避不开建立模拟数据。而且访问模拟数据与访问服务端真实数据的开发要保持一致,即在很少改动的情况下就可以切换到真实数据的访问。看到mock的方案很不错。来体验一把。
    安装组件

    npm i axios mockjs -S
    

    在src下建立文件夹mock并且在mock文件夹下建立index.js、user/users.js


    mock

    index.js:

    import Mock from 'mockjs'
    import UserApi from './user/users'
    
    Mock.mock(/\/user\/list/, 'get', UserApi.list)
    
    export default Mock
    

    user/users.js(生成100条用户数据):

    import Mock from 'mockjs'
    import moment from 'moment'
    import RequestUtil from '@/utils/request'
    
    const List = []
    const count = 100
    
    for (let i = 0; i < count; i++) {
      List.push(Mock.mock({
        id: '@increment',
        name: Mock.Random.cname(),
        phone: null,
        birthday: null,
        createTime: moment().valueOf(),
        updateTime: moment().valueOf()
      }))
    }
    
    export default {
      list: config => {
        const { name, pageOffset = 1, pageSize = 20, sort } = RequestUtil.param2Obj(config.url)
    
        let mockList = List.filter(item => {
          if (name && item.title.indexOf(name) < 0) return false
          return true
        })
    
        if (sort === '-id') {
          mockList = mockList.reverse()
        }
    
        const pageList = mockList.filter((item, index) => index < pageSize * pageOffset && index >= pageSize * (pageOffset - 1))
    
        return {
          first: pageOffset === 1,
          last: pageOffset >= List.length / pageSize,
          totalPages: List.length / pageSize,
          totalElements: List.length,
          number: pageOffset - 1,
          size: mockList.length,
          numberOfElements: (pageSize * pageOffset) + mockList.length,
          content: pageList
        }
      }
    }
    

    最后在main.js中引入

    import '@/mock'
    

    数据请求

    用axios请求数据,目录如下,请求数据相关的都放到request文件夹中。


    请求数据

    base.js中,向服务器请求的全局配置,拦截器等公共信息

    import axios from 'axios'
    import { Message } from 'element-ui'
    
    // create an axios instance
    const service = axios.create({
      baseURL: 'http://localhost:3000', // api的base_url
      timeout: 5000 // request timeout
    })
    
    // request interceptor
    service.interceptors.request.use(config => {
      return config
    }, error => {
      // Do something with request error
      console.log(error) // for debug
      Promise.reject(error)
    })
    
    // respone interceptor
    service.interceptors.response.use(response => {
      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 service
    

    user/user.js:

    import service from '@/request/base'
    
    export default {
      list (query) {
        return service({
          url: '/user/list',
          method: 'get',
          params: query
        })
      }
    }
    

    @/project/admin/pages/user/user.vue中请求数据

    <script>
    import UserService from '@/request/user/user'
    export default {
      name: 'UserUser',
      data () {
        return {
          list: []
        }
      },
      created: function () {
        this.listUser()
      },
      watch: {
      },
      methods: {
        listUser () {
          UserService.list().then(data => {
            console.log(data)
            this.list = [].concat(data.content)
          })
        }
      }
    }
    </script>
    
    <template>
      <el-main>
        user list
      </el-main>
    </template>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    </style>
    

    可以在调试中看到,数据已经得到数据


    取到数据

    页面状态

    store分为全局和项目的,全局的状态放在@/store/index.js中,这里存放当前用户、token、权限等信息。暂时先不处理。

    import 'babel-polyfill'
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const state = {
    }
    
    const mutations = {
    }
    
    const actions = {
    }
    
    const getters = {
    }
    
    export default new Vuex.Store({
      state,
      mutations,
      actions,
      getters
    })
    

    项目的store存放在@/project/admin/store中。修改main.js,加入两个store

    import Vue from 'vue'
    import App from '@/components/App'
    import router from './router'
    import store from '@/store'
    import adminStore from 'admin/store'
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    import '@/mock'
    
    Vue.config.productionTip = false
    Vue.use(ElementUI)
    store.registerModule('adminStore', adminStore)
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store,
      components: { App },
      template: '<App/>'
    })
    
    store

    @/project/admin/store/modules/user/user.js记录user.vue界面的状态。目前需要记录的状态是用户的分页信息

    import _ from 'lodash'
    
    const state = {
      pagination: {
        sort: null,
        order: null,
        size: 20,
        total: 0,
        current: 1,
        layout: 'total, sizes, prev, pager, next, jumper',
        sizes: [10, 20, 30]
      }
    }
    
    const mutations = {
      setPagination (state, pagination) {
        pagination = pagination || {}
        state.pagination = _.defaultsDeep(pagination, state.pagination)
      }
    }
    
    const actions = {
      updatePagination ({commit, state}, payload) {
        return new Promise(function (resolve, reject) {
          commit('setPagination', payload)
          resolve()
        })
      }}
    
    const getters = {
      pagination: function (state) {
        return state.pagination
      }
    }
    
    export default {
      namespaced: true,
      state,
      mutations,
      actions,
      getters
    }
    

    数据展示

    最后,修改user.vue将数据列表展示出来


    显示效果
    <script>
    import moment from 'moment'
    import UserService from '@/request/user/user'
    import { mapGetters } from 'vuex'
    const curstore = 'adminStore/UserUserStore'
    export default {
      name: 'UserUser',
      computed: mapGetters(curstore, {
        pagination: 'pagination'
      }),
      data () {
        return {
          listLoading: false,
          list: []
        }
      },
      created: function () {
        this.listUser()
      },
      watch: {
      },
      methods: {
        listUser () {
          let self = this
          self.listLoading = true
          UserService.list({
            pageOffset: self.pagination['current'],
            pageSize: self.pagination['size']
          }).then(data => {
            self.list = [].concat(data.content)
            self.$store.dispatch(curstore + '/updatePagination', {total: data['totalElements'] || 0})
            self.listLoading = false
          }, err => {
            console.log(err)
            self.listLoading = false
          })
        },
        handleCurrentChange: function (val) {
          var self = this
          self.$store.dispatch(curstore + '/updatePagination', {current: val}).then(function () {
            self.listUser()
          })
        },
        handleSizeChange: function (val) {
          var self = this
          self.$store.dispatch(curstore + '/updatePagination', {size: val}).then(function () {
            self.listUser()
          })
        },
        dateFormatter: function (row, column, cellValue, index) {
          if (cellValue) {
            return moment(cellValue).format('YYYY年MM月DD日')
          } else {
            return ''
          }
        }
      }
    }
    </script>
    
    <template>
      <el-container>
        <el-main class="scrollbar-wrap nopadding">
          <el-scrollbar class="full-scrollbar">
            <!-- 列表 -->
            <el-table :data="list" border v-loading.body="listLoading" stripe style="width: 100%;">
              <el-table-column type="index" width="60" align='center'></el-table-column>
              <el-table-column prop="name" label="姓名" width="120"></el-table-column>
              <el-table-column prop="phone" label="电话"></el-table-column>
              <el-table-column prop="birthday" label="生日"></el-table-column>
              <el-table-column prop="createTime" label="创建时间" :formatter="dateFormatter" width="180"></el-table-column>
              <el-table-column label="操作" width="120">
                <template slot-scope="scope">
                  <el-button size="small" type="text" style="color: #FF4949;">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-scrollbar>
        </el-main>
        <el-footer height="35px">
          <!--分页-->
          <el-col :span="24" class="admin-toolbar toolbar">
            <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pagination.current" :page-sizes="pagination.sizes" :page-size="pagination.size" :layout="pagination.layout" :total="pagination.total"></el-pagination>
          </el-col>
        </el-footer>
      </el-container>
    </template>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    </style>
    

    总结

    这节使用了vuex、mock、moment.js组件。通过这些组件实现本地模拟数据的生成及调用。最后用element-ui的table展示数据。
    git地址:https://gitee.com/biboheart/huip-vue.git

    相关文章

      网友评论

          本文标题:Vue实例:医院统一信息平台(获取数据)

          本文链接:https://www.haomeiwen.com/subject/clyjyftx.html