shu-c-view
Version:
rollup 打包vue@2.7组件库框架
300 lines (297 loc) • 8.78 kB
JavaScript
/**
* @desc 拖拽grid
*/
import sortablejs from 'sortablejs'; // 表格排序组件
import _get from 'lodash/get';
import _map from 'lodash/map';
import _isEmpty from 'lodash/isEmpty';
import _isNil from 'lodash/isNil';
import _isArray from 'lodash/isArray';
import _set from 'lodash/set';
import _assign from 'lodash/assign';
import _has from 'lodash/has';
import _omit from 'lodash/omit';
import { BaseTBar } from '../grid/t-bar/index.js';
import { BaseGridSearch } from '../grid/search/index.js';
import { BaseGridPagination } from '../grid/pagination/index.js';
import { BaseGrid } from '../grid/index.js';
import { devConsole } from '../helper/util.js';
import { BaseDragGridTable } from './table.js';
const BaseDragGrid = {
name: 'BaseDragGrid',
extends: BaseGrid,
model: {
prop: 'dragValue',
event: 'dragChange'
},
props: {
// 排序字段-需要值是唯一的
sortField: {
type: String,
default: 'id'
},
// 拖动的动画效果时间-毫秒
animation: {
type: Number,
default: 150
},
// 是否可拖放排序相当于一个开关
disabled: {
type: Boolean,
default: false
},
// 拖动到某一行时对应那行的样式类
ghostClass: {
type: String,
default: 'sortable-ghost'
},
// 不需要拖动的列,默认所有列都可以拖动
ignoreColumns: {
type: Array,
default() {
return [];
}
},
// 按住行多长时间后才能启用拖动-毫秒
delay: {
type: Number,
default: 0
}
},
watch: {
disabled() {
if (!_isNil(this.sortable)) {
this.sortable.destroy(); // 销毁
this.sortable = null;
setTimeout(() => {
this.setSort();
}, 0);
}
}
},
data() {
this.oldList = []; // 默认排序
this.dragEvents = {
onDragStart: 'onDragStart', // 拖拽开始事件
onDragEnd: 'onDragEnd' // 拖拽结束事件
};
this.list = [];
this.sortable = null;
return {
newList: [] // 最新的排序
};
},
beforeDestroy() {
if (!_isNil(this.sortable)) {
this.sortable.destroy(); // 销毁
this.sortable = null;
}
},
methods: {
/**
* @desc 获取默认排序
*/
getOldSort() {
return this.oldList;
},
/**
* @desc 在数据加载成功的时候触发
* @param {Array} table
* @method
*/
onLoadSuccess(table) {
if (_isEmpty(this.oldList)) {
const data = table;
this.list = data;
this.oldList = _map(data, v => _get(v, this.sortField));
this.newList = this.oldList.slice();
this.$nextTick(() => {
this.setSort();
});
}
setTimeout(() => {
this.$emit(this.events.onLoadSuccess, table);
}, 0);
},
/**
* @desc 设置排序
*/
setSort() {
const el = this.getElTable().$el.querySelectorAll(
'.el-table__body-wrapper > table > tbody'
)[0];
if (_isNil(el)) {
return;
}
// http://www.sortablejs.com/options.html
this.sortable = sortablejs.create(el, {
sort: true, // boolean 定义是否列表单元是否可以在列表容器内进行拖拽排序
delay: this.delay, // 按住行多长时间后才能启用拖动-毫秒
animation: this.animation, // ms, number 单位:ms,定义排序动画的时间
disabled: this.disabled, // boolean 定义是否此sortable对象是否可用,为true时sortable对象不能拖放排序等功能,为false时为可以进行排序,相当于一个开关;
ghostClass: this.ghostClass, // Class name for the drop placeholder,
filter: '.ignore-elements',
setData(dataTransfer) {
// to avoid Firefox bug
// Detail see : https://github.com/RubaXa/Sortable/issues/1012
dataTransfer.setData('Text', '');
},
// 开始拖拽
onStart: () => {
this.$emit(this.dragEvents.onDragStart);
},
// 结束拖拽
onEnd: evt => {
const replaceRow = this.list[evt.newIndex]; // 拖动后替换的行
const targetRow = this.list.splice(evt.oldIndex, 1)[0]; // 拖动的行
this.list.splice(evt.newIndex, 0, targetRow); // 将拖动行插入到替换行的前面
// for show the changes, you can delete in you code
const tempIndex = this.newList.splice(evt.oldIndex, 1)[0];
this.newList.splice(evt.newIndex, 0, tempIndex);
this.$emit(
this.dragEvents.onDragEnd,
targetRow,
replaceRow,
this.newList
);
}
});
}
},
render(h) {
// v-if
if (!this.isRender) {
return h();
}
const style = {};
// v-show
if (!this.isDisplay) {
_set(style, 'display', 'none');
}
return h(
'base-border-layout',
{
ref: `${this._uid}-base-grid`,
style,
class: _assign(
{ 'base-drag-grid': true },
_get(this.$props, 'ctCls', {})
),
props: {
northHeight: 'auto',
westWidth: '0px',
eastWidth: '0px',
southHeight: this.isShowPagination ? '36px' : '0px',
isPadding: false
}
},
[
h(
'base-border-layout',
{
slot: 'north',
props: {
northHeight: 'auto',
southHeight: 'auto',
isPadding: false
}
},
[
h(
BaseGridSearch,
{
slot: 'north',
scopedSlots: {
searchScope: () => {
if (_has(this.$scopedSlots, 'searchScope')) {
return this.$scopedSlots.searchScope(this.currentRow);
}
return h();
}
}
},
[h('template', { slot: 'default' }, this.$slots.search)]
),
h(
BaseTBar,
{
slot: 'south',
scopedSlots: {
tBarScope: () => {
if (_has(this.$scopedSlots, 'tBarScope')) {
return this.$scopedSlots.tBarScope(this.currentRow);
}
return h();
}
}
},
[h('template', { slot: 'default' }, this.$slots.tBar)]
)
]
),
h(
BaseDragGridTable,
{
slot: 'center',
props: {
api: this.api,
queryParams: this.queryParams,
columns: this.columns,
isReloadGrid: this.isReloadGrid,
isSelectedFirstRow: this.isSelectedFirstRow,
isShowIndex: this.isShowIndex,
indexLabel: this.indexLabel,
selectMode: this.selectMode,
loadFilter: this.loadFilter,
loadResponseFilter: this.loadResponseFilter,
slotNode: this.tableAttributes.slotNode,
tableAttributes: this.tableAttributes,
options: this.options,
pagingParams: this.pagingParams,
buttons: this.buttons,
isFixedIndex: this.isFixedIndex,
isFixedSelection: this.isFixedSelection,
columnTool: this.columnTool,
sortField: this.sortField,
ignoreColumns: this.ignoreColumns
}
},
[]
),
h(
BaseGridPagination,
{
slot: 'south',
props: {
currentPage: this.currentPage,
pageSize: this.pageSize,
pagingItems: this.paginationAttributes.pagingItems,
paginationAttributes: _omit(this.paginationAttributes, [
'currentPage',
'pageSize',
'isShowPagination',
'pagingItems'
]),
total: this.total,
isShowPagination: this.isShowPagination
}
},
[]
)
]
);
}
};
BaseDragGrid.install = function(Vue, ElComponents) {
// 用于按需加载的时候独立使用
devConsole(`按需加载独立组件:${BaseDragGrid.name}`);
if (_isArray(ElComponents) && !_isEmpty(ElComponents)) {
for (let i = 0; i < ElComponents.length; i += 1) {
if (ElComponents[i].name !== BaseDragGrid.name) {
Vue.use(ElComponents[i]);
}
}
}
Vue.component(BaseDragGrid.name, BaseDragGrid);
};
export { BaseDragGrid };