前端主要的任务是向用户获取数据或者向用户展示数据。现在我们还没有向服务器取数据,数据本身应该是存储在服务器上的。只是现在还没有连接服务器,先在本地按格式模拟些数据。
常用组件
在这里,我们用到了 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
网友评论