mock+vue-cli+element-ui完成数据模拟及表格数据分页

1. 环境准备


实现本案例之前,需要以下环境

  • node.js
  • cnpm/yarn
  • vue-cli

node.js及cnpm点击此处查看参考

配置好的环境如下图所示:

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第1张图片

2. 项目创建


vue环境搭建好以后,可使用vue-cli命令创建项目,创建项目的命令如下:

vue create mock-element-table

项目的创建过程如下:

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第2张图片

等待安装成功,vue项目创建成功后如图所示:

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第3张图片

3. 依赖插件安装


在本案例中,需要用到以下依赖插件:

  • Element: 一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库
  • Axios :一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
  • Mock.js: 生成随机数据,拦截Ajax 请求 开始 前后端分离 让前端攻城师独立于后端进行开发。 增加单元测试的真实性 通过随机数据,模拟各种场景。

各个组件安装的命令如下:

vue add element #通过vue-cli添加element插件
cnpm i mockjs --save #安装mock.js
cnpm i axios --save #安装axios

安装过程如下图所示:

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第4张图片

安装成功后可在项目根目录package.json找到下列依赖:

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第5张图片

4. 项目运行


找到根目录下的package.json,鼠标右键选择,找到"Show npm Scripts",然后双击"serve"命令,运行vue项目

在浏览器中输入地址:http://localhost:8080,查看项目运行效果

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第6张图片

5. 创建mock模拟数据


5.1 添加工具函数

分页数据请求为get请求,请求的参数将会被封装在url中,故需要一个工具函数将url中的参数转换成对象。在src目录下创建一个util目录,在目录中添加一个js文件名为util.js

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第7张图片

util.js文件中添加获取url参数对象方法

/**
 * 获取url参数对象
 */
export const getQueryParameters = (options) => {
    const url = options.url
    
    //分隔url,获取参数
    const search = url.split('?')[1]
    if (!search) {
        return {}
    }
    
    //将参数转换成对象
    return JSON.parse('{"' + decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"') + '"}')
}

5.2 创建mock函数

在src目录下分别创建mock文件夹,然后src/mock目录下创建student.jsindex.js

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第8张图片

创建后的工程目录如下所示:

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第9张图片

src/mock/student.js中,模拟json数据

import Mock from 'mockjs'
import {getQueryParameters} from "../util/util"

//对外输出对应的数据接口
export  default ()=>{

    Mock.mock(/\/student\/studentPagedList/,'get',(params)=>{
        const paramObj=getQueryParameters(params)

        const classList=['计算机一班','软件工程','网络工程']

        const studentList=[]

        const totalCount=500

        const pageIndex=parseInt(paramObj.pageIndex)
        const pageSize=parseInt(paramObj.pageSize)
        const totalPage=Math.ceil(totalCount/pageSize)//向上取整

        const startNo=(pageIndex-1)*pageSize+1//计算开始Id
        const endNo=pageIndex<totalPage?pageIndex*pageSize:totalCount

        for(let i=startNo;i<=endNo;i++){
            studentList.push(Mock.mock({
                studentId:i,
                studentName:Mock.mock('@cname'),
                studentNo:Mock.mock('@natural(17434010103,17434010300)'),
                gender:Mock.mock('@natural(1,2)'),
                age:Mock.mock('@natural(18,22)'),
                registerTime:Mock.Random.date('yyyy-MM-dd'),
                address:Mock.Random.city(true),
                className:Mock.Random.pick(classList)
            }))
        }

        return {
            total:totalCount,
            data:studentList
        }

    })
}

src/mock/index.js中,添加mock请求拦截

import student from "./student"

student({mock:true})

在项目根目录main.js中,引入mock

//引入mock文件
import './mock'

6. 创建api


对于mock中模拟的数据,可通过axios访问api来获取对应的数据。

6.1 创建api访问方法

在项目的src目录下,创建api文件夹,并在文件夹中创建student.js

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第10张图片

/src/api/student.js中,创建api访问方法

import request from 'axios'

//获取学生分页列表数据
export const getStudentPagedList=(pageIndex,pageSize,params)=>request({
    url:'/student/studentPagedList',
    method: 'get',
    params:{
        ...params,
        pageIndex,
        pageSize
    }
})

6.2 测试api数据访问

打开src/App.vue,通过created()生命周期钩子函数访问获取数据的api,再从浏览器控制台中获取模拟的数据。

import HelloWorld from './components/HelloWorld.vue'
import {getStudentPagedList} from "./api/student"

export default {
  name: 'app',
  created(){
    getStudentPagedList(1,10).then(res=>{
      debugger
    })
  },
  components: {
    HelloWorld
  }
}

开启浏览器调试模式,在控制台中查看对应的数据

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第11张图片

7. Element数据绑定


测试mock模拟的数据没有问题后,将数据绑定至Element的表格组件中。

7.1 页面布局

在页面中,采用Element的栅格化来完成布局。打开项目根目录的App.vue,完成以下布局

<template>
  <div id="app">

    
    <el-card header="学员管理">
      <el-row>

        
        <el-col :span="24">el-col>

        
        <el-col :span="24">el-col>

        
        <el-col :span="24">el-col>

        
        <el-col :span="24">el-col>
      el-row>
    el-card>
  div>
template>

<script>
import {getStudentPagedList} from "./api/student"

export default {
  name: 'app',
  created(){
    getStudentPagedList(1,10).then(res=>{
      debugger
    })
  }
}
script>

<style>
html,body{
  background: #f4f4f4;
}
style>

经过上述布局后页面展示效果如图:

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第12张图片

7.2 列表搜索栏

在搜索栏中,可根学员姓名和班级对列表数据进行筛选,在data选项中添加一个query对象,用于存储列表的查询条件,同时,定义搜索事件与重置事件。

注意:

由于本案例使用mock模拟数据,故无法实现搜索功能,在实际开发对接后台后,可由后台业务逻辑对数据进行筛选,在通过API返回符合条件的数据。


<el-col :span="24">
	<el-form :inline="true" :model="query" size="small">
		<el-form-item label="姓名">
			<el-input v-model="query.studentName" placeholder="请输入..."/>
		el-form-item>
		<el-form-item label="班级">
              <el-select v-model="query.classId" placeholder="请选择">
                	<el-option label="计算机一班" value="1">el-option>
                	<el-option label="软件工程" value="2">el-option>
                	<el-option label="通信工程" value="3">el-option>
              el-select>
         el-form-item>
	<el-form-item>
		<el-button size="small" type="primary" 
               	   icon="el-icon-search" @click="handldQuery">查询el-button>
		<el-button size="small" 
                   icon="el-icon-refresh" @click="resetQuery">重置el-button>
	 el-form-item>
   el-form>
el-col>
data(){
    return{
      //列表搜索数据
      query:{
        studentName:'',
        classId:null
      }
    }
},
methods:{

    //执行查询事件
    handldQuery(){
      this.$message({
        message:`查询姓名为${this.query.studentName}、
                 班级Id为${this.query.classId}的学员数据`,
        type:'success'
      })
    },

    //重置查询条件
    resetQuery(){
      this.query.studentName=''
      this.query.classId=null
    }
}

其实现效果如下:

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第13张图片

7.3 Element列表数据绑定

在Element中,列表的组件为,通过绑定data属性可以绑定需要展示的数据后,在el-table-column中用prop属性来定义表格的列名。可以使用width属性来定义列宽。

注意:

列表数据源通过created()生命周期钩子函数获取,然后将其绑定在data


<el-col :span="24">
    <el-table :data="studentList" stripe @selection-change="handleSelectionChange">
        <el-table-column  type="selection" width="55"/>
        <el-table-column prop="studentId" label="学生Id" width="80"/>
        <el-table-column prop="studentName" label="学生姓名" width="120"/>
        <el-table-column prop="studentNo" label="学号" width="150"/>
        <el-table-column prop="gender" label="性别" width="80">
           <template slot-scope="scope">
              <el-tag v-if="scope.row.gender===1" size="small">el-tag>
              <el-tag v-else size="small" type="success">el-tag>
            template>
         el-table-column>
         <el-table-column prop="age" label="年龄" width="80"/>
         <el-table-column prop="className" label="班级" width="120"/>
         <el-table-column prop="registerTime" label="注册时间"  width="150"/>
         <el-table-column prop="address" label="地址"/>
         <el-table-column label="操作" width="180">
            <template slot-scope="scope">
          		<el-button size="small" type="text" 
                           icon="el-icon-view">查看el-button>
          		<el-button size="small" type="text" 
                           icon="el-icon-edit">编辑el-button>
          		<el-button size="small" type="text" 
                           icon="el-icon-delete">删除el-button>
             template>
         el-table-column>
    el-table>
el-col>
import {getStudentPagedList} from "./api/student"

export default {
  name: 'app',
  created(){
    getStudentPagedList(1,10).then(res=>{
      this.studentList=res.data.data
    })
  },
  data(){
    return{
      //列表搜索数据
      query:{
        studentName:'',
        classId:null
      },
      //学生数据源
      studentList:[],
      //选中的数据
      selectedStudentList:[],
    }
  },
  methods:{

    //执行查询事件
    handldQuery(){
      this.$message({
        message:`查询姓名为${this.query.studentName}、
                 班级Id为${this.query.classId}的学员数据`,
        type:'success'
      })
    },

    //重置查询条件
    resetQuery(){
      this.query.studentName=''
      this.query.classId=null
    },
      
    //选中状态改变事件
    handleSelectionChange(selectedList){
      this.selectedStudentList=selectedList
    }
  }
}

数据绑定后的展示效果如下:

mock+vue-cli+element-ui完成数据模拟及表格数据分页_第14张图片

7.4 Element列表分页

在Element中,可使用el-pagination来实现分页效果,在el-pagination中设置 设置layout,表示需要显示的内容,用逗号分隔,布局元素会依次显示。prev表示上一页,next为下一页,pager表示页码列表,除此以外还提供了jumpertotalsize和特殊的布局符号->->后的元素会靠右显示,jumper表示跳页元素,total表示总条目数,size用于设置每页显示的页码数量。 size-changecurrent-change事件来处理页码大小和当前页变动时候触发的事件。 page-sizes接受一个整型数组,数组元素为展示的选择每页显示个数的选项,[5,10,20,30,50]表示五个选项,每页显示 5 个,10 个,20 个,30个或者 50 个。 page-size表示当前每页显示的数据项。

注意:

  1. 通过api获取的数据会返回数据总记录条数的数据total,在获取数据时,将total写入到data

  2. 在获取数据时,需要传入两个参数pageIndexpageSize,将data中的page作为参数传递

  3. 在分页选项(页数或每页显示数量)发生改变时,需要重新加载分页数据,故将created()中通过Api获取数方法进行封装,以便在其他地方调用。


<el-col :span="24">
    <el-pagination
              background
              :page-sizes="pageSizes"
              :page-size="page.pageSize"
              layout="total,sizes,prev,pager,next,jumper"
              @size-change="sizeChange"
              @current-change="currentChange"
              :total="page.total"
      >
      el-pagination>
el-col>
import {getStudentPagedList} from "./api/student"

export default {
  name: 'app',
  created(){
    this.loadData()
  },
  data(){
    return{
      //列表搜索数据
      query:{
        studentName:'',
        classId:null
      },
      //学生数据源
      studentList:[],
      //选中的数据
      selectedStudentList:[],
      //分页数据
      page:{
        pageSize:5,
        currentPage:1,
        pageSizes:[5,10,20,30,50],
        total:0
      }
    }
  },
  methods:{

    //执行查询事件
    handldQuery(){
      this.$message({
        message:`查询姓名为${this.query.studentName}、
                 班级Id为${this.query.classId}的学员数据`,
        type:'success'
      })
    },

    //重置查询条件
    resetQuery(){
      this.query.studentName=''
      this.query.classId=null
    },
      
    //选中状态改变事件
    handleSelectionChange(selectedList){
      this.selectedStudentList=selectedList
    },

    //每页数据条数改变事件
    sizeChange(pageSize){
      this.page.pageSize=pageSize
      this.loadData()
    },

    //当前页数据改变事件
    currentChange(currentPage){
      this.page.currentPage = currentPage
      this.loadData()
    },

    //数据加载事件
    loadData(){
      getStudentPagedList(this.page.currentPage,this.page.pageSize).then(res=>{
        this.studentList=res.data.data
        this.page.total=res.data.total
      })
    }
  }
}

分页最终演示效果如图:

7.5 添加及批量删除

在列表页中,可新增数据,选中多条数据并进行删除

注意:

删除多条时,可通el-table中的selection-change事件获取当前选中的数据,然后进行删除


<el-col :span="24">
     <el-button type="primary" 
                icon="el-icon-circle-plus-outline" size="small">新增el-button>
      <el-button type="danger" icon="el-icon-delete" size="small">批量删除el-button>
el-col>
import {getStudentPagedList} from "./api/student"

export default {
  name: 'app',
  created(){
    this.loadData()
  },
  data(){
    return{
      //列表搜索数据
      query:{
        studentName:'',
        classId:null
      },
      //学生数据源
      studentList:[],
      //选中的数据
      selectedStudentList:[],
      //分页数据
      page:{
        pageSize:5,
        currentPage:1,
        pageSizes:[5,10,20,30,50],
        total:0
      }
    }
  },
  methods:{

    //执行查询事件
    handldQuery(){
      this.$message({
        message:`查询姓名为${this.query.studentName}、
                 班级Id为${this.query.classId}的学员数据`,
        type:'success'
      })
    },

    //重置查询条件
    resetQuery(){
      this.query.studentName=''
      this.query.classId=null
    },

    //选中状态改变事件
    handleSelectionChange(selectedList){
      this.selectedStudentList=selectedList
    },

    //每页数据条数改变事件
    sizeChange(pageSize){
      this.page.pageSize=pageSize
      this.loadData()
    },

    //当前页数据改变事件
    currentChange(currentPage){
      this.page.currentPage = currentPage
      this.loadData()
    },

    //数据加载事件
    loadData(){
      getStudentPagedList(this.page.currentPage,this.page.pageSize).then(res=>{
        this.studentList=res.data.data
        this.page.total=res.data.total
      })
    },

    //新增按钮点击事件
    handleAdd(){
      this.$message({
        message:'添加新学员',
        type:'success'
      })
    },

    //批量删除
    handleBatchDelete(){
      this.$message.error("批量删除数据")
    }
  }
}

7.6 列表中按钮事件处理

在列表中,可对当前行的数据进行操作,在el-table-columntemplate中,可通过Scope slot可以获取当前行的数据。

<el-table-column label="操作" width="180">
    <template slot-scope="scope">
         <el-button size="small" type="text" icon="el-icon-view" 
                    @click="handleView(scope)">查看el-button>
         <el-button size="small" type="text" icon="el-icon-edit" 
                    @click="handleEidt(scope)">编辑el-button>
         <el-button size="small" type="text" icon="el-icon-delete" 
                    @click="handleDelete(scope)">删除el-button>
     template>
el-table-column>
methods:{
    //查看
    handleView(scope){
      this.$message({
        type:'success',
        message:`查看姓名为${scope.studentName}的学生信息`
      })
    },
    
    //编辑
    handleEdit(scope){
      this.$message({
        type:'success',
        message:`编辑姓名为${scope.studentName}的学生信息`
      })
    },
    
    //删除
    handleView(scope){
      this.$message({
        type:'success',
        message:`删除姓名为${scope.studentName}的学生信息`
      })
    }
}

本案例同步源码下载:

github

gitee

你可能感兴趣的:(#Vue进阶篇)