本次封裝基於 antd
風格, 實現高度可配置的表格封裝配置。原本想經過 vue.extends
去封裝的,奈何幾個月沒寫過 vue
,並且對 vue
的 extends
不熟悉因此放棄了...javascript
以前有小夥伴確實引用了個人代碼,發現封裝出現了一些紕漏,對此十分抱歉,以前封裝的太倉促了。幾個月前的代碼,如今從新封裝又有了新的體會。css
更新時間 【2018.11.09】,效果以下:html
columns
: 必選, 列描述數據對象, ArraydataSource
: 必選, 數據數組options
: 必選, 表格參數控制, maxHeight、stripe 等等..fetch
: 獲取數據的 Functionpagination
: 分頁信息,不傳則不顯示分頁row-click
:當某一行被點擊時會觸發該事件selection-change
: 當選擇項發生變化時會觸發該事件其餘說明我在代碼註釋中寫的很清楚了,請自行查看。vue
根據條件渲染: 只經過 render
去判斷參數不一樣而渲染不同的表格數據。 render
函數能夠渲染任何你想要的組件java
值得注意的是,this
對象的綁定不要出錯了,若是須要更多加強的功能,各位能夠自行添加...react
<template>
<div>
<h2>Home</h2>
<CommonTable :columns="columns" :dataSource="tableData" :options="options" :fetch="fetchTableData" :pagination="pagination" @row-click="handleRowClick" @selection-change="handleSelectionChange" />
</div>
</template>
<script> import axios from 'axios' import CommonTable from '../components/Table' export default{ components:{ CommonTable }, data(){ return { columns: [ { prop: 'id', label: '編號', width: 60 }, { prop: 'title', label: '標題', // render 能夠根據你想要渲染的方式渲染 // jsx 不提供 v-model 指令,若你想要使用,,推薦使用插件 babel-plugin-jsx-v-model // jsx https://github.com/vuejs/babel-plugin-transform-vue-jsx render: (row, index) => { return ( <span style="color: blue" onClick={e => this.handleClick(e, row)}>{row.title}</span> ) } }, { prop: 'author', label: '做者' }, { button: true, label: '按鈕組', group: [{ // you can props => type size icon disabled plain name: '編輯', type: 'warning', icon: 'el-icon-edit', plain: true, onClick: (row, index) => { // 箭頭函數寫法的 this 表明 Vue 實例 console.log(row, index) } }, { name: '刪除', type: 'danger', icon: 'el-icon-delete', disabled: false, onClick(row) { // 這種寫法的 this 表明 group 裏的對象 this.disabled = true console.log(this) } }] } ], tableData: [ { id: 1, title: '標題1', author: '郭大大' }, { id: 2, title: '標題2', author: '郭大大2' } ], pagination: { total: 0, pageIndex: 1, pageSize: 15 }, options: { mutiSelect: true, index: true, // 顯示序號, 多選則 mutiSelect loading: false, // 表格動畫 initTable: true, // 是否一掛載就加載數據 } } }, methods: { handleClick(e, row){ //transform-vue-jsx 的nativeOnClick 失效 , 因此採用 event.cancelBubble 控制點擊事件的冒泡... 若是點擊事件不影響你的點擊行事件,能夠不傳 e.cancelBubble = true // 中止冒泡,不然會觸發 row-click console.log(row) }, fetchTableData() { this.options.loading = true axios.post('https://www.easy-mock.com/mock/5b3f80edfa972016b39fefbf/example/tableData', { pageIndex: this.pagination.pageIndex, pageSize: this.pagination.pageSize }).then(res => { const { list, total } = res.data.data this.tableData = list this.pagination.total = total this.options.loading = false }).catch((error) => { console.log(error) this.options.loading = false }) }, handleRowClick(row, event, column){ // 點擊行的事件,同理能夠綁定其餘事件 console.log('click row:',row, event, column) }, handleSelectionChange(selection){ console.log(selection) } } } </script>
複製代碼
<template>
<div>
<el-table v-loading="options.loading" :data="dataSource" :max-height="options.maxHeight" :stripe="options.stripe" :border="options.border" @row-click="handleRowClick" @selection-change="handleSelectionChange" header-row-class-name="table-header-row">
<!--selection選擇框-->
<el-table-column v-if="options.mutiSelect" type="selection" style="width:50px" align="center"></el-table-column>
<!--序號-->
<el-table-column v-if="options.index" label="序號" type="index" width="50" align="center"></el-table-column>
<!--數據列-->
<template v-for="(column, index) in columns">
<el-table-column :key="index" :prop="column.prop" :label="column.label" :align="column.align||'center'" :width="column.width" :fixed="column.fixed">
<template slot-scope="scope">
<template v-if="!column.render">
{{scope.row[column.prop]}}
</template>
<!-- render -->
<template v-else>
<RenderDom :row="scope.row" :index="index" :render="column.render" />
</template>
<!-- render button -->
<template v-if="column.button">
<template v-for="(btn, i) in column.group">
<el-button :key="i" :type="btn.type" :size="btn.size || 'mini'" :icon="btn.icon" :disabled="btn.disabled" :plain="btn.plain" @click.stop="btn.onClick(scope.row, scope.$index)" >{{btn.name}}</el-button>
</template>
</template>
<!-- slot 你能夠其餘經常使用項 -->
</template>
</el-table-column>
</template>
</el-table>
<!-- 分頁 -->
<el-pagination v-if="pagination" :total="pagination.total" :page-sizes="[20, 50, 100, 500, 5000]" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleIndexChange" style="margin-top: 20px;text-align: right" ></el-pagination>
</div>
</template>
<script> export default { components: { RenderDom: { functional: true, // 函數式組件 - 無 data 和 this 上下文 => better render props: { row: Object, index: Number, render: Function }, /** * @param {Function} createElement - 原生建立dom元素的方法, 棄用,推薦使用 jsx * @param {Object} ctx - 渲染的節點的this對象 * @argument 傳遞參數 row index */ render(createElement, ctx){ const { row, index } = ctx.props return ctx.props.render(row, index) } } }, props:{ dataSource: Array, options: Object, // 表格參數控制 maxHeight、stripe 等等... columns: Array, fetch: Function, // 獲取數據的函數 pagination: Object // 分頁,不傳則不顯示 }, created() { // 傳入的options覆蓋默認設置 this.$parent.options = Object.assign({ maxHeight: 500, stripe: true, // 是否爲斑馬紋 border: true }, this.options) this.options.initTable && this.fetch() }, methods: { handleSizeChange(size) { // 切換每頁顯示的數量 this.pagination.pageSize = size this.fetch() }, handleIndexChange(current) { // 切換頁碼 this.pagination.pageIndex = current this.fetch() }, handleSelectionChange(selection) { this.$emit('selection-change', selection) }, handleRowClick(row, event, column) { this.$emit('row-click', row, event, column) } } } </script>
<style> .el-table th, .el-table tr.table-header-row { background: #e5c5d2; /* 示例, 對錶格樣式上的修飾 */ } </style>
複製代碼
上述代碼封裝完整性可能不是這麼高,但思路在呢,若是須要更多配置,各位能夠在進行增強...ios
吐槽一下,原本是想 props
數據來重寫 table
參數,相似 react
:git
<Home>
<ComonTable {...props} > </Home>
// ComonTable
<el-table {...props.options}>
</el-table> 複製代碼
因此想到繼承,本身又不熟悉。 並且發現 vue
展開綁定多個屬性是不能夠的: 多是我沒 google
到。若是能夠,請大佬告知一聲,謝謝github