UNPKG

element-nice-ui

Version:

A Component Library for Vue.js.

280 lines (236 loc) 7.21 kB
import Vue from 'vue' import { treeMap } from './util' import { openDB, Store } from './db' import ElCheckbox from 'element-nice-ui/packages/checkbox' /** * 创建列数据 * @param {Object} options 配置 * @param {string} options.tableCode 表格标识 * @param {boolean} options.checkable 可选择的 */ export default function createColumns(options) { return new Vue({ data() { const state = { tableCode: '', align: 'center', defaultWidth: 100, allColumns: [], /** 左侧固定列 */ leftFixedColumns: [], /** 静态列 */ staticColumns: [], /** 右侧固定列 */ rightFixedColumns: [], storeName: 'table', _db: null, checkable: false, checked: [], selectable: false, selected: null, showAsTree: false, /** 可选中列的列宽 */ _checkableColumnWidth: 60, /** 可展开的列宽 */ _treeExpandableColumnWidth: 60, /** 默认列 */ defaultColumns: null } options && Object.keys(options).forEach(key => { if (options[key] === undefined) return state[key] = options[key] }) return state }, computed: { /** 初始左侧偏移量, 根据当前的表格可否选择和可否展开来决定 */ initialOffsetLeft() { let offsetLeft = 0 if (this.checkable) { offsetLeft += this.$data._checkableColumnWidth } return offsetLeft }, // 渲染函数用来缓存checkable和showAsTree计算 /** 渲染额外表头 */ extraFixedHeaders() { // 防止样式出现一瞬间的错乱 if (!this.allColumns.length) return [] let nodeList = [] let style = { 'text-align': 'center', left: '0' } if (this.checkable) { // 全选 nodeList.push( <th class='el-new-table__left-fixed' style={style}> <ElCheckbox /> </th> ) } else if (this.selectable) { nodeList.push(<th class='el-new-table__left-fixed' style={style}></th>) } return nodeList }, /** 渲染额外的列组 */ extraColumns() { // 防止样式出现一瞬间的错乱 if (!this.allColumns.length) return [] let extraCols = [] if (this.checkable || this.selectable) { extraCols.push({ _id: 1000, width: 40, fixed: 'left', _offsetLeft: 0 }) } return extraCols } }, methods: { async connectDB() { const { storeName } = this const db = await openDB('el-element', 1, db => { if (!db.objectStoreNames.contains(storeName)) { db.createObjectStore(storeName, { keyPath: 'code' }) } }) this.$data._db = db }, getStore() { return new Store(this.$data._db, this.storeName, 'readwrite') }, /** * 改造表头, 主要是加入一些自定义属性, 比如唯一标识等等 * @param {any[]} columns 列信息 */ initColumns(columns) { let id = 0 this.allColumns = treeMap(columns, column => { column._id = id++ column.visible = true if (!column.align) { column.align = this.align } // 让列可响应 if (!column.fixed) { column.fixed = '' } }).map(column => { // 只针对一级列设置 if (!column.width && !column.minWidth) { column.width = this.defaultWidth } return column }) }, /** * 设置左右固定列和静态列的布局, 并且存入数据库中 */ setColumnsLayout() { let leftFixedColumns = [] let staticColumns = [] let rightFixedColumns = [] // 列分组 this.allColumns.forEach(column => { if (column.visible === false) return if (!column.fixed) { return staticColumns.push(column) } if (column.fixed === 'left') { leftFixedColumns.push(column) } else if (column.fixed === 'right') { rightFixedColumns.push(column) } }) // 根据列宽定义所有左固定列的左偏移量 (需加上额外的固定列) this.extraColumns.concat(leftFixedColumns).reduce((acc, cur) => { cur._offsetLeft = acc return acc + cur.width }, 0) // 根据列宽定义所有列的右偏移量 rightFixedColumns.reduceRight((acc, cur) => { cur._offsetRight = acc return acc + cur.width }, 0) this.leftFixedColumns = leftFixedColumns this.staticColumns = staticColumns this.rightFixedColumns = rightFixedColumns }, add() { this.tableCode && this.getStore().add({ code: this.tableCode, columns: this.allColumns.map(item => { let ret = { ...item } delete ret.formatter return ret }) }) }, delete() { this.tableCode && this.getStore().delete(this.tableCode) }, /** 保存至数据库 */ save() { this.tableCode && this.getStore().put({ code: this.tableCode, columns: this.allColumns.map(item => { let ret = { ...item } delete ret.formatter return ret }) }) }, /** 初始化, 在table组件中监听表头调用 */ async init(columns) { if (!columns && this.defaultColumns) { columns = this.defaultColumns } if (!this.defaultColumns) { this.defaultColumns = columns } let { tableCode } = this // 未启用数据库保存 if (!tableCode) { this.initColumns(columns) this.setColumnsLayout() return } // 启用数据库保存 await this.connectDB() let record = await this.getStore().get(this.tableCode) // 查到该条数据, 不用进行初始化 if (record) { // 查到数据后需要和当前的数据做对比, 一旦列的长度不一致则使用当前列初始化 if (record.columns.length !== columns.length) { this.initColumns(columns) this.setColumnsLayout() this.save() return } // 列长度未发生改变 this.allColumns = record.columns.map((column, index) => { if (columns[index].formatter) { column.formatter = columns[index].formatter } return column }) this.setColumnsLayout() } // 未查到该条数据 else { this.initColumns(columns) this.setColumnsLayout() this.add() } } } }) }