| New file |
| | |
| | | <template> |
| | | <div style="width: 100%;height: 100%;" > |
| | | <!-- 正常区域的框 --> |
| | | <div class="vxe-table--cell-area" ref="cellarea"> |
| | | <span class="vxe-table--cell-main-area"></span> |
| | | <span class="vxe-table--cell-active-area"></span> |
| | | </div> |
| | | <vxe-grid |
| | | max-height="100%" |
| | | @filter-change="filterChanged" |
| | | class="mytable-scrollbar" |
| | | ref="xGrid" |
| | | v-bind="gridOptions" |
| | | v-on="gridEvents" |
| | | @scroll ="scrollEvnt" |
| | | |
| | | > |
| | | <!-- @toolbar-button-click="toolbarButtonClickEvent"--> |
| | | <!-- 下拉显示所有信息插槽--> |
| | | <template #content="{ row }"> |
| | | <ul class="expand-wrapper"> |
| | | <li v-for="(item,key) in row"> |
| | | <span style="font-weight: bold">{{key+': '}}</span> |
| | | <span>{{ item }}</span> |
| | | </li> |
| | | </ul> |
| | | </template> |
| | | |
| | | <!--左边固定显示的插槽--> |
| | | <template #button_slot="{ row }"> |
| | | <el-button @click="gaveParent(row,'edit')" link type="primary" size="small">编辑</el-button> |
| | | <el-button @click="gaveParent(row,'delete')" link type="primary" size="small">删除</el-button> |
| | | </template> |
| | | |
| | | <template #num1_filter="{ column, $panel }"> |
| | | <div> |
| | | <div v-for="(option, index) in column.filters" :key="index"> |
| | | <input type="type" v-model="option.data" @input="changeFilterEvent($event, option, $panel)"/> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | |
| | | </vxe-grid> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import {ref, reactive, defineEmits, onMounted, nextTick, toRef, watch} from 'vue' |
| | | import {VxeGridProps, VXETable} from 'vxe-table' |
| | | import request from "@/utils/request" |
| | | import deepClone from "@/utils/deepClone"; |
| | | import {ElMessage} from "element-plus"; |
| | | import router from "@/router"; |
| | | //prop接收父组件函数 |
| | | |
| | | |
| | | |
| | | let props = defineProps({ |
| | | tableProp:{ |
| | | String, |
| | | default: '' |
| | | } |
| | | }) |
| | | |
| | | //子方法调用父方法 |
| | | let emit = defineEmits([ |
| | | 'getChildren', |
| | | 'getFilterChildren', |
| | | 'getCheckList', |
| | | ]) |
| | | const gaveParent = (row,type)=> { |
| | | emit('getChildren',row,type) |
| | | } |
| | | //页脚求和 |
| | | const sumNum = (list, field) => { |
| | | let count = 0 |
| | | list.forEach(item => { |
| | | count += Number(item[field]) |
| | | }) |
| | | return count.toFixed(2) |
| | | } |
| | | |
| | | const changeFilterEvent = (event, option, $panel,) => { |
| | | // 手动触发筛选 |
| | | $panel.changeOption(event, !!option.data, option) |
| | | } |
| | | |
| | | //触发筛选条件 |
| | | function filterChanged(column){ |
| | | let value = column.datas[0]!=undefined?column.datas[0]:'' |
| | | value = value===''?'n*':value.trim() |
| | | props.tableProp.filter[column.field]=value |
| | | } |
| | | const xGrid = ref() |
| | | const gridOptions = reactive({ |
| | | border: "full",//表格加边框 |
| | | keepSource: true,//保持源数据 |
| | | align: 'center',//文字居中 |
| | | stripe:true,//斑马纹 |
| | | rowConfig: {isCurrent: true, isHover: true,height: 50},//鼠标移动或选择高亮 |
| | | id: 'demo_1', |
| | | showFooter: true,//显示脚 |
| | | printConfig: {}, |
| | | importConfig: {}, |
| | | exportConfig: {}, |
| | | scrollY:{ enabled: true , gt: 40},//开启虚拟滚动 |
| | | showOverflow:true, |
| | | columnConfig: { |
| | | resizable: true, |
| | | useKey: true |
| | | }, |
| | | filterConfig: { //筛选配置项 |
| | | remote: true |
| | | }, |
| | | customConfig: { |
| | | storage: true |
| | | }, |
| | | editConfig: { |
| | | trigger: 'click', |
| | | mode: 'row', |
| | | showStatus: true |
| | | }, |
| | | columns:props.tableProp.title,//表头参数 |
| | | toolbarConfig: { |
| | | buttons: props.tableProp.buttons, |
| | | // buttons: [ |
| | | // { code: 'myInsert', name: '新增' }, |
| | | // { code: 'deleteList', name: '删除' }, |
| | | // { code: 'checkList', name: '提交' }, |
| | | // // { code: 'mySave', name: '保存', status: 'success' }, |
| | | // //{ code: 'myExport', name: '导出数据', type: 'text', status: 'warning' }, |
| | | // // { |
| | | // // name: '禁用按钮', |
| | | // // disabled: false, |
| | | // // dropdowns: [ |
| | | // // { code: 'other1', name: '下拉的按钮1', type: 'text', disabled: false }, |
| | | // // { code: 'other2', name: '下拉的按钮2', type: 'text', disabled: true }, |
| | | // // { code: 'other3', name: '下拉的按钮3', type: 'text', disabled: false } |
| | | // // ] |
| | | // // } |
| | | // ], |
| | | // tools: [ |
| | | // { code: 'myPrint', name: '自定义打印' } |
| | | // ], |
| | | import: false, |
| | | export: true, |
| | | print: true, |
| | | zoom: true, |
| | | custom: true |
| | | }, |
| | | data: props.tableProp.datas,//table body实际数据 |
| | | footerMethod ({ columns, data }) {//页脚函数 |
| | | return[ |
| | | columns.map((column, columnIndex) => { |
| | | if (columnIndex === 0) { |
| | | return '合计:' |
| | | } |
| | | if (props.tableProp.footList.includes(column.field)) { |
| | | return sumNum(data, column.field) |
| | | } |
| | | return '' |
| | | }) |
| | | ] |
| | | } |
| | | |
| | | }) |
| | | const gridEvents = { |
| | | toolbarButtonClick ({ code }) { |
| | | const $grid = xGrid.value |
| | | if ($grid) { |
| | | switch (code) { |
| | | case 'checkList': { |
| | | if($grid.getCheckboxRecords().length==0){ |
| | | VXETable.modal.message( '请选择一条数据!') |
| | | return |
| | | } |
| | | emit('getCheckList',$grid.getCheckboxRecords()) |
| | | break |
| | | } |
| | | case 'deleteList': { |
| | | $grid.removeCheckboxRow() |
| | | break |
| | | } |
| | | case 'myInsert': { |
| | | $grid.insert({}) |
| | | break |
| | | } |
| | | case 'mySave': { |
| | | const { insertRecords, removeRecords, updateRecords } = $grid.getRecordset() |
| | | VXETable.modal.message({ content: `新增 ${insertRecords.length} 条,删除 ${removeRecords.length} 条,更新 ${updateRecords.length} 条`, status: 'success' }) |
| | | break |
| | | } |
| | | case 'myExport': { |
| | | $grid.exportData({ |
| | | type: 'csv' |
| | | }) |
| | | break |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | toolbarToolClick ({ code }) { |
| | | const $grid = xGrid.value |
| | | if ($grid) { |
| | | switch (code) { |
| | | case 'myPrint': { |
| | | $grid.print() |
| | | break |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | } |
| | | |
| | | |
| | | |
| | | /* |
| | | //鼠标滑动选中 |
| | | let isSelecting = ref(false) // 是否正在进行选择操作,默认为false |
| | | let selectionStart = reactive({ rowIndex: -1, cellIndex: -1 }) // 选择操作起始单元格位置 |
| | | let selectionEnd = reactive({ rowIndex: -1, cellIndex: -1 }) // 选择操作结束单元格位置 |
| | | |
| | | onMounted(() => { |
| | | addListener() |
| | | }) |
| | | |
| | | |
| | | |
| | | let cellarea = ref() |
| | | let leftfixedcellarea = ref() |
| | | let rightfixedcellarea = ref() |
| | | |
| | | //返回table的ref名称 |
| | | const getTablexGrid = () => { |
| | | return xGrid.value |
| | | } |
| | | |
| | | const addListener = () => { |
| | | //添加多选列 |
| | | nextTick(() => { |
| | | window.addEventListener("mousedown", tableOutDestroyAreaBox)//给window添加鼠标按下事件,判断是否在表格外,是销毁 |
| | | window.addEventListener("mouseup", tbodymouseup)//给window添加鼠标松开事件 |
| | | let tbody = getTablexGrid().$el.querySelector(".vxe-table--main-wrapper table tbody")//获取tbody区域 |
| | | |
| | | if (tbody) { |
| | | tbody.addEventListener("mousedown", tbodymousedown)//给表格中的tbody添加鼠标按下事件 |
| | | tbody.addEventListener("mousemove", tbodymousemove)//给表格中的tbody添加鼠标移动事件 |
| | | tbody.addEventListener("mouseout", throttle(tbodymouseout, 50))//给表格中的tbody添加鼠标移出事件 |
| | | tbody.addEventListener("click", tableCellClick)//添加左键单击事件 |
| | | tbody.oncontextmenu = tableCellMenuClick//添加右键菜单事件 |
| | | } |
| | | |
| | | let bodyWrapper = getTablexGrid().$el.querySelector(".vxe-table--main-wrapper .vxe-table--body-wrapper")//获取正常区域的body |
| | | if (bodyWrapper) { |
| | | //注意这里的ref名称,这里是非fixed区域的框的名称 |
| | | bodyWrapper.appendChild(cellarea.value)//添加范围框元素 |
| | | } |
| | | setTimeout(() => { |
| | | //#region 左侧固定列 |
| | | let leftfixedtbody = getTablexGrid().$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-left-wrapper .vxe-table--body-wrapper table tbody")//获取fixedtbody区域 |
| | | |
| | | if (leftfixedtbody) { |
| | | leftfixedtbody.addEventListener("mousedown", tbodymousedown)//给表格中的leftfixedtbody添加鼠标按下事件 |
| | | leftfixedtbody.addEventListener("mousemove", tbodymousemove)//给表格中的leftfixedtbody添加鼠标移动事件 |
| | | leftfixedtbody.addEventListener("mouseout", throttle(tbodymouseout, 50))//给表格中的leftfixedtbody添加鼠标移出事件 |
| | | leftfixedtbody.addEventListener("click", tableCellClick)//添加单击事件 |
| | | leftfixedtbody.oncontextmenu = tableCellMenuClick//添加右键菜单事件 |
| | | } |
| | | |
| | | let leftFixedBodyWrapper = getTablexGrid().$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-left-wrapper .vxe-table--body-wrapper") |
| | | if (leftFixedBodyWrapper) { |
| | | //注意这里的ref名称,这里是fixed区域的框的名称 |
| | | leftFixedBodyWrapper.appendChild(leftfixedcellarea.value) |
| | | } |
| | | //#endregion |
| | | |
| | | //#region 右侧固定列 |
| | | let rightfixedtbody = getTablexGrid().$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-right-wrapper .vxe-table--body-wrapper table tbody")//获取fixedtbody区域 |
| | | |
| | | if (rightfixedtbody) { |
| | | rightfixedtbody.addEventListener("mousedown", tbodymousedown)//给表格中的rightfixedtbody添加鼠标按下事件 |
| | | rightfixedtbody.addEventListener("mousemove", tbodymousemove)//给表格中的rightfixedtbody添加鼠标移动事件 |
| | | rightfixedtbody.addEventListener("mouseout", throttle(tbodymouseout, 50))//给表格中的rightfixedtbody添加鼠标移出事件 |
| | | rightfixedtbody.addEventListener("click", tableCellClick)//添加单击事件 |
| | | rightfixedtbody.oncontextmenu = tableCellMenuClick//添加右键菜单事件 |
| | | } |
| | | |
| | | let rightFixedBodyWrapper = getTablexGrid().$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-right-wrapper .vxe-table--body-wrapper") |
| | | if (rightFixedBodyWrapper) { |
| | | //注意这里的ref名称,这里是fixed区域的框的名称 |
| | | rightFixedBodyWrapper.appendChild(rightfixedcellarea.value) |
| | | } |
| | | //#endregion |
| | | |
| | | }, 100) |
| | | |
| | | }) |
| | | } |
| | | const tbodymousedown = (event) => { |
| | | event.stopPropagation(); // 阻止冒泡 |
| | | getTablexGrid().closeMenu(); // 手动关闭右键菜单 |
| | | |
| | | if (event.button === 0) { // 左键按下 |
| | | // 记录选择操作起始位置 |
| | | selectionStart = getCellPosition(event.target); // 设置选择操作起始单元格位置 |
| | | isSelecting.value = true; // 标记为正在选择操作 |
| | | } |
| | | }; |
| | | |
| | | //鼠标移动事件 |
| | | //todo 这里要节流操作,只在结束时触发一次 |
| | | const tbodymousemove = (event: MouseEvent) => { |
| | | if (event.button === 0) {//左键移动 |
| | | if (!isSelecting.value) return//如果当前非正在选择操作,直接退出 |
| | | //记录选择操作结束位置 |
| | | selectionEnd = getCellPosition(event.target) |
| | | |
| | | //设置样式,并显示范围框 |
| | | setselectedCellArea() |
| | | |
| | | } |
| | | } |
| | | |
| | | //鼠标按键结束事件,添加在了window中 |
| | | const tbodymouseup = (event: MouseEvent) => { |
| | | if (event.button === 0) {//左键松开 |
| | | isSelecting.value = false//标记为停止选择操作 |
| | | } |
| | | } |
| | | |
| | | let outevent = ref()//移动事件,不保存,循环定时器内无法监听到新的事件 |
| | | |
| | | //鼠标移出表格事件,只在移动的时候会触发,暂停移动不触发 |
| | | const tbodymouseout = (event: MouseEvent) => { |
| | | outevent.value = event//保存移动事件 |
| | | |
| | | if (isSelecting.value) {//如果正在执行选中操作 |
| | | const timer = setInterval(() => {//开启循环定时器 |
| | | if (isSelecting.value) {//判断当前是否正在选择 |
| | | //获取表格元素 |
| | | var table = getTablexGrid().$el.querySelector(".vxe-table--body-wrapper table")//获取非固定列(和固定列)的table元素 |
| | | if (outevent.value.clientX > table.parentElement.getBoundingClientRect().right - 30) {//判断鼠标x轴是否超出表格右侧,向右滚动 |
| | | var maxScrollPosition = table.parentElement.scrollWidth - table.parentElement.clientWidth//获取滚动条最大位置 |
| | | if (table.parentElement.scrollLeft < maxScrollPosition) {//如果没到滚动条最大位置,执行滚动 |
| | | table.parentElement.scrollLeft += 10//执行水平滚动条向右滚动 |
| | | } |
| | | } else if (outevent.value.clientX < table.parentElement.getBoundingClientRect().left + 30) {//判断鼠标x轴是否超出表格左侧,向左滚动 |
| | | if (table.parentElement.scrollLeft > 0) {//如果没到滚动条最大位置,执行滚动 |
| | | //鼠标移出表格,滚动水平滚动条 |
| | | table.parentElement.scrollLeft -= 10//执行水平滚动条向右滚动 |
| | | } |
| | | } |
| | | |
| | | |
| | | } else { |
| | | clearInterval(timer)//清除循环定时器 |
| | | } |
| | | }, 200)//这里设置滑动速度 |
| | | |
| | | } |
| | | |
| | | } |
| | | |
| | | //节流函数,todo//改为全局 |
| | | const throttle = (fn: Function, delay: number) => { |
| | | const canRun = ref(true) |
| | | return (...args: any[]) => { |
| | | if (!canRun.value) return |
| | | canRun.value = false |
| | | setTimeout(() => { |
| | | fn(...args) |
| | | canRun.value = true |
| | | }, delay) |
| | | } |
| | | } |
| | | |
| | | // 获取单元格位置(rowIndex, cellIndex) |
| | | const getCellPosition = (cell: any) => { |
| | | |
| | | |
| | | while (cell.tagName !== 'TD') {//将cell指向TD元素 |
| | | cell = cell.parentElement |
| | | } |
| | | |
| | | let visibleColumn = getTablexGrid().getTableColumn().visibleColumn//获取处理条件之后的全量表头列 |
| | | const cellIndex = visibleColumn.findIndex((col: { id: any; }) => {//返回colid相等的visibleColumn全量表头列的索引 |
| | | return col.id == cell.getAttribute("colid") |
| | | }) |
| | | |
| | | let visibleData = getTablexGrid().getTableData().visibleData//获取处理条件之后的全量表体数据 |
| | | |
| | | const rowIndex = visibleData.findIndex((row: { _X_ROW_KEY: any; }) => {//返回rowid相等的visibleData全量表体数据 |
| | | return row._X_ROW_KEY == cell.parentElement.getAttribute("rowid")//返回rowid相等的visibleData全量表体数据的索引 |
| | | }) |
| | | return { rowIndex, cellIndex } |
| | | |
| | | } |
| | | |
| | | //设置框打开 |
| | | const setselectedCellArea = () => { |
| | | |
| | | |
| | | |
| | | var activeElement = getTablexGrid().$el.querySelector(".vxe-table--main-wrapper .vxe-table--body-wrapper .vxe-table--cell-active-area")//正常区域选中边框激活的元素(仅是边框) |
| | | var mainElement = getTablexGrid().$el.querySelector(".vxe-table--main-wrapper .vxe-table--body-wrapper .vxe-table--cell-main-area")//正常区域选中边框内整个范围的元素 |
| | | |
| | | var leftFixedActiveElement = getTablexGrid().$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-left-wrapper .vxe-table--body-wrapper .vxe-table--cell-active-area")//左侧固定列选中边框激活的元素(仅是边框) |
| | | var leftFixedMainElement = getTablexGrid().$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-left-wrapper .vxe-table--body-wrapper .vxe-table--cell-main-area")//左侧固定列选中边框内整个范围的元素 |
| | | |
| | | var rightFixedActiveElement = getTablexGrid().$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-right-wrapper .vxe-table--body-wrapper .vxe-table--cell-active-area")//右侧固定列选中边框激活的元素(仅是边框) |
| | | var rightFixedMainElement = getTablexGrid().$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-right-wrapper .vxe-table--body-wrapper .vxe-table--cell-main-area")//右侧固定列选中边框内整个范围的元素 |
| | | |
| | | |
| | | var elements = [activeElement, mainElement, leftFixedActiveElement, leftFixedMainElement, rightFixedActiveElement, rightFixedMainElement] |
| | | let area = getAreaBoxPosition() |
| | | if (area) { |
| | | var { width, height, left, top, right } = area |
| | | } else { |
| | | return |
| | | } |
| | | elements.forEach((element, index) => { |
| | | if (element) {//设置显示范围框的内部元素的样式 |
| | | element.style.width = `${width}px` |
| | | element.style.height = `${height}px` |
| | | element.style.top = `${top}px` |
| | | element.style.display = "block" |
| | | if (index <= elements.length - 1 - 2) {//如果不是rightFixedActiveElement或rightFixedMainElement |
| | | element.style.left = `${left}px` |
| | | } else { |
| | | element.style.right = `${right}px` |
| | | } |
| | | } |
| | | }) |
| | | |
| | | //显示范围框 |
| | | openAreaBox() |
| | | } |
| | | |
| | | //根据开始位置和结束位置的索引计算框的width,height,left,top(左侧固定列和正常区域和右侧固定列使用) |
| | | const getAreaBoxPosition = () => { |
| | | let startRowIndex = selectionStart.rowIndex//获取选中起始行索引 |
| | | let endRowIndex = selectionEnd.rowIndex//获取选中结束行索引 |
| | | let startColumnIndex = selectionStart.cellIndex//获取选中起始列索引 |
| | | let endColumnIndex = selectionEnd.cellIndex//获取选中结束列索引 |
| | | let visibleColumn = getTablexGrid().getTableColumn().visibleColumn//获取处理条件之后的全量表头列 |
| | | let visibleData = getTablexGrid().getTableData().visibleData//获取处理条件之后的全量表体数据 |
| | | if (startColumnIndex < 0 || endColumnIndex < 0 || startRowIndex < 0 || endRowIndex < 0) return |
| | | var maxColumnIndex = visibleColumn.length - 1//最大列索引 |
| | | var maxRowIndex = visibleData.length - 1//最大行索引 |
| | | if (endColumnIndex > maxColumnIndex) {//到最后一列,指向最后一列 |
| | | endColumnIndex = maxColumnIndex |
| | | } |
| | | if (endRowIndex > maxRowIndex) {//到最后一行,指向最后一行 |
| | | endRowIndex = maxRowIndex |
| | | } |
| | | let width = 0, height = 0, left = 0, top = 0, right = 0 |
| | | visibleColumn.forEach((col: { renderWidth: number; }, index: number) => { |
| | | if (startColumnIndex <= endColumnIndex) {//开始列索引小于结束列索引,即从左往右选择 |
| | | if (index < startColumnIndex) { |
| | | left += col.renderWidth//距离表格整体左侧边框距离 |
| | | } |
| | | if (index > endColumnIndex) {//数据索引大于结束列,这里获取距离后面数据的宽度 |
| | | right += col.renderWidth//距离表格整体右侧边框距离,加上当前列 |
| | | } |
| | | if (startColumnIndex <= index && index <= endColumnIndex) {//开始列索引大于数据索引 和 结束列索引小于数据索引,这里获取选中区域的宽度 |
| | | width += col.renderWidth//选中区域的宽度 |
| | | } |
| | | } else {//从右往左选择 |
| | | if (index < endColumnIndex) { |
| | | left += col.renderWidth//距离表格整体左侧边框距离 |
| | | } |
| | | if (index > startColumnIndex) {//数据索引大于开始列,这里获取距离后面数据的宽度 |
| | | right += col.renderWidth//距离表格整体右侧边框距离,加上当前列 |
| | | } |
| | | if (startColumnIndex >= index && index >= endColumnIndex) {//开始列索引大于数据索引 和 结束列索引小于数据索引,这里获取选中区域的宽度 |
| | | width += col.renderWidth//选中区域的宽度 |
| | | } |
| | | } |
| | | |
| | | }) |
| | | if (startRowIndex <= endRowIndex) {//开始行索引小于结束行索引,即从上往下选择 |
| | | height = (endRowIndex - startRowIndex + 1) * gridOptions.rowConfig!.height!//选中区域的高度 |
| | | top = startRowIndex * gridOptions.rowConfig!.height!//距离表格整体顶部边框距离 |
| | | } else { |
| | | height = (startRowIndex - endRowIndex + 1) * gridOptions.rowConfig!.height!//选中区域的高度 |
| | | top = endRowIndex * gridOptions.rowConfig!.height!//距离表格整体顶部边框距离 |
| | | } |
| | | |
| | | |
| | | |
| | | return { width, height, left, top, right } |
| | | |
| | | } |
| | | |
| | | //显示范围框 |
| | | const openAreaBox = () => { |
| | | var element = xGrid.value.$el.querySelector(".vxe-table--main-wrapper .vxe-table--body-wrapper .vxe-table--cell-area") |
| | | if (element) { |
| | | element.style.display = "block" |
| | | } |
| | | element = xGrid.value.$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-left-wrapper .vxe-table--body-wrapper .vxe-table--cell-area") |
| | | if (element) { |
| | | element.style.display = "block" |
| | | } |
| | | element = xGrid.value.$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-right-wrapper .vxe-table--body-wrapper .vxe-table--cell-area") |
| | | if (element) { |
| | | element.style.display = "block" |
| | | } |
| | | } |
| | | |
| | | //表格外销毁范围框 |
| | | const tableOutDestroyAreaBox = (event: MouseEvent) => { |
| | | try{ |
| | | var element = getTablexGrid().$el.querySelector(".vxe-table--render-wrapper") |
| | | }catch (err){ |
| | | |
| | | } |
| | | |
| | | if (element) { |
| | | if (event.clientX < element.getBoundingClientRect().left || event.clientX > element.getBoundingClientRect().right |
| | | || event.clientY > element.getBoundingClientRect().top || event.clientY < element.getBoundingClientRect().bottom |
| | | ) { |
| | | destroyAreaBox() |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | //销毁范围框 |
| | | const destroyAreaBox = () => { |
| | | var element = getTablexGrid().$el.querySelector(".vxe-table--main-wrapper .vxe-table--body-wrapper .vxe-table--cell-area") |
| | | if (element) { |
| | | element.style.display = "none" |
| | | } |
| | | element = getTablexGrid().$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-left-wrapper .vxe-table--body-wrapper .vxe-table--cell-area") |
| | | if (element) { |
| | | element.style.display = "none" |
| | | } |
| | | element = getTablexGrid().$el.querySelector(".vxe-table--fixed-wrapper .vxe-table--fixed-right-wrapper .vxe-table--body-wrapper .vxe-table--cell-area") |
| | | if (element) { |
| | | element.style.display = "none" |
| | | } |
| | | } |
| | | |
| | | //表格单元格点击事件 |
| | | const tableCellClick = (e: MouseEvent) => { |
| | | |
| | | if (!isSelecting.value) {//非选中状态 |
| | | try { |
| | | selectionStart = getCellPosition(e.target)//获取单元格位置 |
| | | selectionEnd = selectionStart//结束位置也是自己 |
| | | //设置样式 |
| | | setselectedCellArea() |
| | | } catch (error) { |
| | | |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | //表格右键点击事件 |
| | | const tableCellMenuClick = (e: MouseEvent) => { |
| | | if (!isSelecting.value) {//非选中状态 |
| | | let currentCellPosition = getCellPosition(e.target)//获取单元格位置 |
| | | var horizontalFlag//是否在范围框的水平判断标记 |
| | | var verticalFlag//是否在范围框的垂直判断标记 |
| | | if (selectionStart.cellIndex <= selectionEnd.cellIndex) {//如果是从左往右选取 |
| | | horizontalFlag = selectionStart.cellIndex <= currentCellPosition.cellIndex && currentCellPosition.cellIndex <= selectionEnd.cellIndex |
| | | } else {//从右往左选取 |
| | | horizontalFlag = selectionEnd.cellIndex <= currentCellPosition.cellIndex && currentCellPosition.cellIndex <= selectionStart.cellIndex |
| | | } |
| | | if (selectionStart.rowIndex <= selectionEnd.rowIndex) {//如果是从上往下选取 |
| | | verticalFlag = selectionStart.rowIndex <= currentCellPosition.rowIndex && currentCellPosition.rowIndex <= selectionEnd.rowIndex |
| | | } else {//从下往上选取 |
| | | verticalFlag = selectionEnd.rowIndex <= currentCellPosition.rowIndex && currentCellPosition.rowIndex <= selectionStart.rowIndex |
| | | } |
| | | |
| | | if (horizontalFlag && verticalFlag) { //判断如果不在选中区域内,触发表格左键单击事件,更新截取单元格,否则如果在正常触发右键菜单 |
| | | |
| | | } else { |
| | | selectionStart = getCellPosition(e.target)//获取单元格位置 |
| | | selectionEnd = selectionStart//结束位置也是自己 |
| | | //设置样式 |
| | | setselectedCellArea() |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | | const toolbarButtonClickEvent = ({ code }: { code: any }) => { |
| | | switch (code) { |
| | | case "getcellselctdata": |
| | | //我给大家打印处理: |
| | | console.log("是否正在进行滑动选中操作:", isSelecting.value) |
| | | //左上角坐标 |
| | | console.log("单元格起始位置:索引:", selectionStart) |
| | | //右下角坐标 |
| | | console.log("单元格结束位置:索引:", selectionEnd) |
| | | |
| | | //这里需要是visibleData |
| | | let tableData = getTablexGrid().getTableData().visibleData//获取处理条件之后的全量表体数据 |
| | | let rowStart = selectionStart.rowIndex//获取选中起始行索引 |
| | | let rowEnd = selectionEnd.rowIndex//获取选中结束行索引 |
| | | let selectRows = tableData.filter((col, index: number) => {//col参数不能改否则会获取不到数据 |
| | | //这里修改从右下往左上拖动的数据显示 |
| | | if (rowStart <= rowEnd) { |
| | | return rowStart <= index && rowEnd >= index |
| | | } else { |
| | | return rowStart >= index && rowEnd <= index |
| | | } |
| | | }) |
| | | console.log("鼠标选中行:", JSON.stringify(selectRows)) |
| | | |
| | | //这里需要是visibleColumn |
| | | let colStart = selectionStart.cellIndex//获取选中起始列索引 |
| | | let colEnd = selectionEnd.cellIndex//获取选中结束列索引 |
| | | let tableColumn = getTablexGrid().getTableColumn().visibleColumn//获取处理条件之后的全量表头列 |
| | | let selectCols = tableColumn.filter((col, index: number) => {//col参数不能改否则会获取不到数据 |
| | | //这里修改从右下往左上拖动的数据显示 |
| | | if (colStart <= colEnd) { |
| | | return colStart <= index && colEnd >= index |
| | | } else { |
| | | return colStart >= index && colEnd <= index |
| | | } |
| | | |
| | | }) |
| | | console.log("鼠标选中列:", JSON.stringify(selectCols)) |
| | | break |
| | | } |
| | | } |
| | | */ |
| | | |
| | | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .vxe-grid { |
| | | /* 禁用浏览器默认选中 */ |
| | | -webkit-user-select: none; |
| | | -moz-user-select: none; |
| | | -ms-user-select: none; |
| | | user-select: none; |
| | | } |
| | | |
| | | |
| | | /*滚动条整体部分*/ |
| | | .mytable-scrollbar ::-webkit-scrollbar { |
| | | width: 10px; |
| | | height: 10px; |
| | | } |
| | | /*滚动条的轨道*/ |
| | | .mytable-scrollbar ::-webkit-scrollbar-track { |
| | | background-color: #FFFFFF; |
| | | } |
| | | /*滚动条里面的小方块,能向上向下移动*/ |
| | | .mytable-scrollbar ::-webkit-scrollbar-thumb { |
| | | background-color: transparent; |
| | | border-radius: 5px; |
| | | border: 1px solid #F1F1F1; |
| | | box-shadow: inset 0 0 6px rgba(0,0,0,.3); |
| | | } |
| | | .mytable-scrollbar ::-webkit-scrollbar-thumb:hover { |
| | | background-color: #ffffff; |
| | | } |
| | | .mytable-scrollbar ::-webkit-scrollbar-thumb:active { |
| | | background-color: white; |
| | | } |
| | | /*边角,即两个滚动条的交汇处*/ |
| | | .mytable-scrollbar ::-webkit-scrollbar-corner { |
| | | background-color: #FFFFFF; |
| | | } |
| | | </style> |
| | | |