vue基于elementUI集成搜索与分页的grid组件

文件grid.vue为表格组件
index.vue为使用grid组件的demo
result.json为结果的json文件
在grid组件中想要回调父组件中的方法需要在grid组件中声明:
v-on:onDataBound="onDataBound"
onDataBound=回调名称
"onDataBound"=回调的方法
command数据列中的回调方法均会返回当前列的数据
toolbar数据列中的回调方法均会返回复选框的选中数据id

<template>
  <div class="table-box" v-loading="loading"
       element-loading-text="拼命加载中"
       element-loading-spinner="el-icon-loading"
       element-loading-background="rgba(255,255,255,0.5)">
    <div class="toolbar" v-if="toolbar">
      <el-button v-for="item in toolbar" size="mini" round :type="item.type" :key="item.name"
                 @click="itemMethod(item.click,checkedLists)">
        {{item.text}}
      </el-button>
    </div>
    <table>
      <thead>
      <tr>
        <th v-if="check" width="5px">
          <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange"></el-checkbox>
        </th>
        <th v-if="command">
          操作
        </th>
        <th v-for="column in columns"
            @click="sortBy(column.name)"
            :class="{ active: sortKey == column.name }"
            :key="column.name" :width="column.width">
          {{ column.title}}
          <span class="arrow" :class="sortOrders[column.name] > 0 ? 'asc' : 'dsc'">
          </span>
        </th>
      </tr>
      <tr>
        <td v-if="check"></td>
        <td v-if="command"></td>
        <td v-for="column in columns" :key="column.name">
          <el-input class="searchInput"
                    @keyup.enter.native="enterSerachInput"
                    :name="column.name"></el-input>
        </td>
      </tr>
      </thead>
      <tbody>
      <tr v-for="entry in filteredData" v-if="filteredData.length >0"
          :key="entry.name">
        <td v-if="check">
          <el-checkbox-group v-model="checkedLists" @change="handleCheckedChange">
            <el-checkbox :key="entry.id" :label="entry.id"></el-checkbox>
          </el-checkbox-group>
        </td>
        <td v-if="command">
          <el-tooltip class="item" effect="dark"
                      :content='com.tooltip' placement="right-start"
                      :disabled="!com.tooltip" v-for="com in command" :key="com.name">
            <a style="cursor: pointer" v-html="com.text" :name="com.name" @click="itemMethod(com.click,entry)"
               :id="com.name+entry.id">
              {{com.text}}
            </a>
          </el-tooltip>
        </td>
        <td v-for="column in columns" :key="column.name">
          <el-tooltip class="item" effect="dark"
                      :content='entry[column.name]' placement="right-start"
                      :disabled="!column.tooltip">
            <span>{{entry[column.name]}}</span>
          </el-tooltip>
        </td>
      </tr>
      </tbody>
    </table>
    <div>
      <el-pagination
        layout="prev, pager, next"
        :total="totalCount"
        :page-size="requestInfo.pageSize"
        @current-change="pageChange"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
const checkBoxOptions = []
export default {
  name: 'grid',
  props: {
    data: Object,
    columns: Array,
    check: Boolean,
    requestInfo: Object,
    command: Array,
    toolbar: Array,
    loading: Boolean
  },
  data: function () {
    var sortOrders = {}
    this.columns.forEach(function (key) {
      sortOrders[key.name] = 1
    })
    return {
      sortKey: '',
      sortOrders: sortOrders,
      searchValus: new Map(),
      isIndeterminate: false,
      checkAll: false,
      checkedLists: [],
      filter: {},
      filters: {}
    }
  },
  computed: {
    // 数据
    filteredData: function () {
      var sortKey = this.sortKey
      var order = this.sortOrders[sortKey] || 1
      var data = this.data.data
      if (sortKey) {
        data = data.slice().sort(function (a, b) {
          a = a[sortKey]
          b = b[sortKey]
          return (a === b ? 0 : a > b ? 1 : -1) * order
        })
      }
      return data
    },
    // 总页数
    totalCount: function () {
      var total = 0
      if (undefined !== this.data.total) {
        total = this.data.total
      }
      return total
    }
  },
  filters: {
    capitalize: function (str) {
      return str.charAt(0).toUpperCase() + str.slice(1)
    }
  },
  methods: {
    sortBy: function (key) {
      this.sortKey = key
      this.sortOrders[key] = this.sortOrders[key] * -1
    },
    // 搜索框失去焦点的时候
    serachInputBlur (event) {
      const obj = event.path[0]
      const oldVal = this.searchValus.get(obj.name)
      // 如果数据已经修改则发起请求
      if (oldVal !== obj.value) {
        if (obj.value !== '') {
          const filterContent = {}
          filterContent['operator'] = 'contains'
          filterContent['value'] = obj.value
          filterContent['field'] = obj.name
          this.filters[obj.name] = filterContent
        } else {
          delete this.filters[obj.name]
        }
        const filters = []
        for (var key in this.filters) {
          filters.push(this.filters[key])
        }
        this.filter['logic'] = 'and'
        this.filter['filters'] = filters
        this.$emit(this.requestInfo.callMethod, 1, this.filter)
      }
    },
    // 搜索框获取焦点的时候
    serachInputFocu (event) {
      const obj = event.path[0]
      this.searchValus.set(obj.name, obj.value)
    },
    // 在搜索框着输入确认键的事件
    enterSerachInput (e) {
      var keyCode = window.event ? e.keyCode : e.which
      if (keyCode === 13) {
        this.serachInputBlur(window.event)
        this.serachInputFocu(window.event)
      }
    },
    // 页面更新事件
    pageChange (page) {
      // 需要在gird中定义v-on:this.requestInfo.callMethod="你的方法"
      this.$emit(this.requestInfo.callMethod, page, this.filter)
    },
    // 全选复选框事件
    handleCheckAllChange (val) {
      this.checkedLists = val ? checkBoxOptions : []
      this.isIndeterminate = false
    },
    // 单选事件
    handleCheckedChange (value) {
      let checkedCount = value.length
      this.checkAll = checkedCount === checkBoxOptions.length
      this.isIndeterminate = checkedCount > 0 && checkedCount < checkBoxOptions.length
    },
    // 点击事件的调用
    itemMethod (callMethod, item) {
      // 需要在gird中定义v-on:callMethod="你的方法"
      this.$emit(callMethod, item)
    }
  },
  watch: {
    // 监听数据的变化,改变复选框的数据
    filteredData (a, b) {
      a.forEach(function (info) {
        checkBoxOptions.push(info.id)
      })
    }
  },
  mounted () {
    // 如果有配置初始化回调的话回调父级指定方法
    if (this.requestInfo.dataBound) {
      this.$emit(this.requestInfo.dataBound)
    }
  }
}
</script>

<style scoped lang="stylus">
  body {
    font-family: Helvetica Neue, Arial, sans-serif;
    font-size: 14px;
    color: #444;
  }

  .table-box {
    display: grid;
    grid-template-rows: 35px 1fr 50px;
  }

  table {
    border: 2px solid #e2efef;
    border-radius: 3px;
    background-color: #fff;
    width: 100%;
  }

  th {
    background-color: #e2efef;
    cursor: pointer;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    color black
  }

  tr:hover {
    background-color: #f9f9f9;
  }

  th, td {
    padding: 10px 7px;
  }

  td /deep/ .el-checkbox__label {
    position absolute
    top -9999px
    left -9999px
  }

  th.active .arrow {
    opacity: 1;
  }

  .arrow {
    display: inline-block;
    vertical-align: middle;
    width: 0;
    height: 0;
    margin-left: 5px;
    opacity: 0.66;
  }

  .arrow.asc {
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-bottom: 4px solid black;
  }

  .arrow.dsc {
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 4px solid black;
  }

  .searchInput /deep/ .el-input__inner {
    height 27px
  }

  .toolbar {
    float left
    padding-left 10px
    background #f9f9f9
    line-height 25px
    display: flex;
    align-items: Center;
  }

</style>
<template>
  <grid
    :data="gridData"
    :columns="gridColumns"
    :check="check"
    :requestInfo="requestInfo"
    :command="command"
    :toolbar="toolbar"
    :loading="loading"
    v-on:callGetInfo="callGetInfo"
    v-on:editInfo="editInfo"
    v-on:create="create"
    v-on:onDataBound="onDataBound"
  >
  </grid>
</template>

<script>
import axios from 'axios'
import {mapState} from 'vuex'
import Grid from '../components/grid'

export default {
  components: {Grid},
  name: 'index',
  data () {
    return {
      // 请求信息
      requestInfo: {
        // 刷新页面的回调方法
        'callMethod': 'callGetInfo',
        // 每页大小
        'pageSize': 18,
        // 数据初始化完成后的回调
        'dataBound': 'onDataBound'
      },
      // 列信息
      gridColumns: [
        // 名称,标题,是否使用tooltip,宽度
        {name: 'linkMan', title: '名称', tooltip: true, width: '120px'},
        {name: 'linkPhone', title: '联系电话'},
        {name: 'organizationCode', title: '组织机构编码'},
        {name: 'organizationName', title: '组织机构名称'},
        {name: 'remaker', title: '备注'}
      ],
      // 列数据
      gridData: {},
      // 是否显示载入图标
      loading: false,
      // 列按钮信息
      command: [
        {name: 'opEdit', text: '<span class="el-icon-location"></span>', tooltip: '编辑', click: 'editInfo'}
      ],
      // 自定义事件回调方法
      callMethods: {'callGetInfo': 'callGetInfo', 'editInfo': 'editInfo'},
      // 是否显示复选框
      check: true,
      // 上方工具条
      toolbar: [
        {name: 'opCreate', text: '超小按钮', click: 'create', type: 'primary'}
      ]
    }
  },
  methods: {
    callGetInfo (page, filter) {
      const param = {}
      if (page === undefined) {
        page = 1
      }
      param['page'] = page
      param['pageSize'] = this.requestInfo.pageSize
      param['filter'] = filter
      this.loading = true
      //{"total":44,"data":[{"id":16,"organizationName":"信息管理部","linkMan":"王伟华","linkPhone":"13435784959","address":null,"remaker":null,"serverFlag":0,"organizationCode":"xgb","version":0},{"id":17,"organizationName":"管理员","linkMan":"王伟华","linkPhone":"13435784959","address":null,"remaker":null,"serverFlag":0,"organizationCode":"admin","version":0},{"id":18,"organizationName":"管理员","linkMan":"王伟华","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":0},{"id":19,"organizationName":"\t管理员","linkMan":"王伟华20","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":1},{"id":20,"organizationName":"\t管理员","linkMan":"王伟华21","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":2},{"id":21,"organizationName":"\t管理员","linkMan":"王伟华22","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":3},{"id":22,"organizationName":"\t管理员","linkMan":"王伟华23","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":4},{"id":23,"organizationName":"\t管理员","linkMan":"王伟华24","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":5},{"id":24,"organizationName":"\t管理员","linkMan":"王伟华25","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":6},{"id":25,"organizationName":"\t管理员","linkMan":"王伟华26","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":7},{"id":26,"organizationName":"\t管理员","linkMan":"王伟华27","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":8},{"id":27,"organizationName":"\t管理员","linkMan":"王伟华28","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":9},{"id":28,"organizationName":"\t管理员","linkMan":"王伟华29","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":10},{"id":29,"organizationName":"\t管理员","linkMan":"王伟华30","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":11},{"id":30,"organizationName":"\t管理员","linkMan":"王伟华31","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":12},{"id":31,"organizationName":"\t管理员","linkMan":"王伟华32","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":13},{"id":32,"organizationName":"\t管理员","linkMan":"王伟华33","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":14},{"id":33,"organizationName":"\t管理员","linkMan":"王伟华34","linkPhone":"13435784959","address":"","remaker":"","serverFlag":0,"organizationCode":"admin","version":15}],"aggregates":{}}
      axios.post('/apis/base/organization/loadData?token=' + this.token, param, {headers: {'Content-Type': 'application/json'}})
        .then((res) => {
          const result = res.data
          console.log(JSON.stringify(result))
          this.loading = false
          this.gridData = result
        })
    },
    editInfo (item) {
      console.log(item)
    },
    create (checkedInfo) {
      console.log(checkedInfo)
    },
    onDataBound () {
      console.log('onDataBound')
    }
  },
  computed: {
    ...mapState({
      token: 'token'
    })
  },
  mounted () {
    this.callGetInfo(1)
  }
}
</script>
<style scoped lang="stylus">

</style>
{
	"total": 44,
	"data": [{
		"id": 16,
		"organizationName": "信息管理部",
		"linkMan": "王伟华",
		"linkPhone": "13435784959",
		"address": null,
		"remaker": null,
		"serverFlag": 0,
		"organizationCode": "xgb",
		"version": 0
	}, {
		"id": 17,
		"organizationName": "管理员",
		"linkMan": "王伟华",
		"linkPhone": "13435784959",
		"address": null,
		"remaker": null,
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 0
	}, {
		"id": 18,
		"organizationName": "管理员",
		"linkMan": "王伟华",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 0
	}, {
		"id": 19,
		"organizationName": "\t管理员",
		"linkMan": "王伟华20",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 1
	}, {
		"id": 20,
		"organizationName": "\t管理员",
		"linkMan": "王伟华21",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 2
	}, {
		"id": 21,
		"organizationName": "\t管理员",
		"linkMan": "王伟华22",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 3
	}, {
		"id": 22,
		"organizationName": "\t管理员",
		"linkMan": "王伟华23",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 4
	}, {
		"id": 23,
		"organizationName": "\t管理员",
		"linkMan": "王伟华24",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 5
	}, {
		"id": 24,
		"organizationName": "\t管理员",
		"linkMan": "王伟华25",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 6
	}, {
		"id": 25,
		"organizationName": "\t管理员",
		"linkMan": "王伟华26",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 7
	}, {
		"id": 26,
		"organizationName": "\t管理员",
		"linkMan": "王伟华27",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 8
	}, {
		"id": 27,
		"organizationName": "\t管理员",
		"linkMan": "王伟华28",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 9
	}, {
		"id": 28,
		"organizationName": "\t管理员",
		"linkMan": "王伟华29",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 10
	}, {
		"id": 29,
		"organizationName": "\t管理员",
		"linkMan": "王伟华30",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 11
	}, {
		"id": 30,
		"organizationName": "\t管理员",
		"linkMan": "王伟华31",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 12
	}, {
		"id": 31,
		"organizationName": "\t管理员",
		"linkMan": "王伟华32",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 13
	}, {
		"id": 32,
		"organizationName": "\t管理员",
		"linkMan": "王伟华33",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 14
	}, {
		"id": 33,
		"organizationName": "\t管理员",
		"linkMan": "王伟华34",
		"linkPhone": "13435784959",
		"address": "",
		"remaker": "",
		"serverFlag": 0,
		"organizationCode": "admin",
		"version": 15
	}],
	"aggregates": {}
}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值