|
| 1 | +<cn> |
| 2 | +#### 可伸缩列 |
| 3 | +集成 [vue-draggable-resizable](https://github.com/mauricius/vue-draggable-resizable) 来实现可伸缩列。 |
| 4 | +</cn> |
| 5 | + |
| 6 | +<us> |
| 7 | +#### Resizable column |
| 8 | +Implement resizable column by integrate with [vue-draggable-resizable](https://github.com/mauricius/vue-draggable-resizable). |
| 9 | +</us> |
| 10 | + |
| 11 | +<template> |
| 12 | + <a-table bordered :columns="columns" :components="components" :dataSource="data"> |
| 13 | + <template v-slot:action> |
| 14 | + <a href="javascript:;">Delete</a> |
| 15 | + </template> |
| 16 | + </a-table> |
| 17 | +</template> |
| 18 | + |
| 19 | +<script> |
| 20 | +import Vue from 'vue'; |
| 21 | +import VueDraggableResizable from 'vue-draggable-resizable'; |
| 22 | +
|
| 23 | +Vue.component('vue-draggable-resizable', VueDraggableResizable); |
| 24 | +const columns = [ |
| 25 | + { |
| 26 | + title: 'Date', |
| 27 | + dataIndex: 'date', |
| 28 | + width: 200, |
| 29 | + }, |
| 30 | + { |
| 31 | + title: 'Amount', |
| 32 | + dataIndex: 'amount', |
| 33 | + width: 100, |
| 34 | + }, |
| 35 | + { |
| 36 | + title: 'Type', |
| 37 | + dataIndex: 'type', |
| 38 | + width: 100, |
| 39 | + }, |
| 40 | + { |
| 41 | + title: 'Note', |
| 42 | + dataIndex: 'note', |
| 43 | + width: 100, |
| 44 | + }, |
| 45 | + { |
| 46 | + title: 'Action', |
| 47 | + key: 'action', |
| 48 | + scopedSlots: { customRender: 'action' }, |
| 49 | + }, |
| 50 | +]; |
| 51 | +const data = [ |
| 52 | + { |
| 53 | + key: 0, |
| 54 | + date: '2018-02-11', |
| 55 | + amount: 120, |
| 56 | + type: 'income', |
| 57 | + note: 'transfer', |
| 58 | + }, |
| 59 | + { |
| 60 | + key: 1, |
| 61 | + date: '2018-03-11', |
| 62 | + amount: 243, |
| 63 | + type: 'income', |
| 64 | + note: 'transfer', |
| 65 | + }, |
| 66 | + { |
| 67 | + key: 2, |
| 68 | + date: '2018-04-11', |
| 69 | + amount: 98, |
| 70 | + type: 'income', |
| 71 | + note: 'transfer', |
| 72 | + }, |
| 73 | +]; |
| 74 | +const draggingMap = {}; |
| 75 | +columns.forEach(col => { |
| 76 | + draggingMap[col.key] = col.width; |
| 77 | +}); |
| 78 | +const draggingState = Vue.observable(draggingMap); |
| 79 | +const ResizeableTitle = (h, props, children) => { |
| 80 | + let thDom = null; |
| 81 | + const { key, ...restProps } = props; |
| 82 | + const col = columns.find(col => { |
| 83 | + const k = col.dataIndex || col.key; |
| 84 | + return k === key; |
| 85 | + }); |
| 86 | + if (!col.width) { |
| 87 | + return <th {...restProps}>{children}</th>; |
| 88 | + } |
| 89 | + const onDrag = (x, y) => { |
| 90 | + draggingState[key] = 0; |
| 91 | + col.width = Math.max(x, 1); |
| 92 | + }; |
| 93 | +
|
| 94 | + const onDragstop = () => { |
| 95 | + draggingState[key] = thDom.getBoundingClientRect().width; |
| 96 | + }; |
| 97 | + return ( |
| 98 | + <th {...restProps} v-ant-ref={r => (thDom = r)} width={col.width} class="resize-table-th"> |
| 99 | + {children} |
| 100 | + <vue-draggable-resizable |
| 101 | + key={col.key} |
| 102 | + class="table-draggable-handle" |
| 103 | + w={10} |
| 104 | + x={draggingState[key] || col.width} |
| 105 | + z={1} |
| 106 | + axis="x" |
| 107 | + draggable={true} |
| 108 | + resizable={false} |
| 109 | + onDragging={onDrag} |
| 110 | + onDragstop={onDragstop} |
| 111 | + ></vue-draggable-resizable> |
| 112 | + </th> |
| 113 | + ); |
| 114 | +}; |
| 115 | +export default { |
| 116 | + name: 'App', |
| 117 | + data() { |
| 118 | + this.components = { |
| 119 | + header: { |
| 120 | + cell: ResizeableTitle, |
| 121 | + }, |
| 122 | + }; |
| 123 | + return { |
| 124 | + data, |
| 125 | + columns, |
| 126 | + }; |
| 127 | + }, |
| 128 | +}; |
| 129 | +</script> |
| 130 | +<style lang="less"> |
| 131 | +.resize-table-th { |
| 132 | + position: relative; |
| 133 | + .table-draggable-handle { |
| 134 | + height: 100% !important; |
| 135 | + bottom: 0; |
| 136 | + left: auto !important; |
| 137 | + right: -5px; |
| 138 | + cursor: col-resize; |
| 139 | + touch-action: none; |
| 140 | + } |
| 141 | +} |
| 142 | +</style> |
0 commit comments