赞
踩
业务场景:表格中只有特定某一行的的单元格可以编辑,列很多,为每个列写个插槽要写很多重复代码,所以这里使用动态插槽,简化代码量。显示编辑图标,点击编辑图标隐藏。失去焦点保存调后台接口。
解决办法:
1、后端返回的数据里可以编辑的行数据添加属性 edit: true;不可编辑的行数据里添加属性 edit: false;
2、把列数组里的插槽和field提取出来为循环使用做准备,如果直接使用导入进来的columns无法显示,所以需要处理后使用。
列名文件示例columns.js
- export const columns1 = [
- {
- title: '名称',
- field: "heatSourceName",
- align: 'left',
- width: "160",
- slots: { header: 'header_heatSourceName', default: '_heatSourceName' },
- },
- {
- title: "日流量(t/h)",
- field: "supTemp",
- width: "140",
- align: 'right',
- sortable: false,
- editRender: { autofocus: '.vxe-input--inner' },
- slots: { default: '_supTemp', edit: 'edit_supTemp' },
- },
- {
- title: "日热量(GJ/h)",
- field: "supPres",
- width: "140",
- align: 'right',
- sortable: false,
- editRender: { autofocus: '.vxe-input--inner' },
- slots: { default: '_supPres', edit: 'edit_supPres' },
- },
- {
- title: "日压力(Mpa)",
- field: "instFlowSup",
- width: "160",
- align: 'right',
- sortable: false,
- editRender: { autofocus: '.vxe-input--inner' },
- slots: { default: '_instFlowSup', edit: 'edit_instFlowSup' },
- }, ...]

HTML写法
- <vxe-grid ref="xGrid1" v-bind="gridOptions1" :span-method="spanMethods">
- <template #header_heatSourceName>
- <div class="first-col">
- <div class="first-col-top">指标</div>
- <div class="first-col-bottom">热源</div>
- </div>
- </template>
- <!-- 分割线,动态插槽写法 -->
- <template v-for="item in defaultSlots1" :key="item.field" v-slot:[item.slot]="{ row }">
- <div style="display: flex; align-items: center;`justify-content: ${row[item.field] === 'heatSourceName' ? flex-start : flex-end}`"
- v-if="row.edit && timeInfo === timeInfo1">
- <i class="vxe-cell--edit-icon vxe-icon-edit" style="margin-right: 5px;"></i>{{ row[item.field] }}
- </div>
- <div v-else>
- {{ row[item.field] }}
- </div>
- </template>
- <template v-for="item in editSlots1" :key="item.field" v-slot:[item.slot]="{ row }">
- <div v-if="row.edit && timeInfo === timeInfo1">
- <vxe-input v-model="row[item.field]" type="number" :min="0" :max="99999999"></vxe-input>
- </div>
- <div v-else>
- {{ row[item.field] }}
- </div>
- </template>
- <!-- 分割线,下面为常规写法 -->
- <!-- <template #_supTemp="{ row }">
- <div style="display: flex; align-items: center;justify-content: flex-end;"
- v-if="row.edit && timeInfo === timeInfo1">
- <i class="vxe-cell--edit-icon vxe-icon-edit" style="margin-right: 5px;"></i>{{ row.supTemp }}
- </div>
- <div v-else>
- {{ row.supTemp }}
- </div>
- </template>
- <template #edit_supTemp="{ row }">
- <div v-if="row.edit && timeInfo === timeInfo1">
- <vxe-input v-model="row.supTemp" type="number" :min="0" :max="99999999"></vxe-input>
- </div>
- <div v-else>
- {{ row.supTemp }}
- </div>
- </template>
- <template #_supPres="{ row }">
- <div style="display: flex; align-items: center;justify-content: flex-end;"
- v-if="row.edit && timeInfo === timeInfo1">
- <i class="vxe-cell--edit-icon vxe-icon-edit" style="margin-right: 5px;"></i>{{ row.supPres }}
- </div>
- <div v-else>
- {{ row.supPres }}
- </div>
- </template>
- <template #edit_supPres="{ row }">
- <div v-if="row.edit && timeInfo === timeInfo1">
- <vxe-input v-model="row.supPres" type="number" :min="0" :max="99999999"></vxe-input>
- </div>
- <div v-else>
- {{ row.supPres }}
- </div>
- </template>
- <template #_waterCnp="{ row }">
- <div style="display: flex; align-items: center;justify-content: flex-end;"
- v-if="row.edit && timeInfo === timeInfo1">
- <i class="vxe-cell--edit-icon vxe-icon-edit" style="margin-right: 5px;"></i>{{ row.waterCnp }}
- </div>
- <div v-else>
- {{ row.waterCnp }}
- </div>
- </template>
- <template #edit_waterCnp="{ row }">
- <div v-if="row.edit && timeInfo === timeInfo1">
- <vxe-input v-model="row.waterCnp" type="number" :min="0" :max="99999999"></vxe-input>
- </div>
- <div v-else>
- {{ row.waterCnp }}
- </div>
- </template> -->
- </vxe-grid>

Js写法
- <script>
- import {
- defineComponent,
- ref,
- reactive,
- toRefs,
- computed,
- watch,
- onMounted,
- nextTick,
- } from 'vue'
- import { columns1 } from './columns.js';
- import moment from 'moment'
- import { useAppStoreWithOut } from '@/store/modules/app'
-
- export default defineComponent({
- setup() {
- const appStore = useAppStoreWithOut();
- const state = reactive({
- timeInfo: moment(appStore.getSysTime).subtract(1, 'day').format('YYYY年MM月DD日'),
- timeInfo1: moment(appStore.getSysTime).subtract(1, 'day').format('YYYY年MM月DD日'),
- gridOptions1: {
- border: true,
- height: '100%',
- showFooter: false,
- showOverflow: true,
- 'column-config': { resizable: false },
- 'edit-config': {
- trigger: 'click', mode: 'cell', showIcon: false },
- 'scroll-y': { enable: true, mode: 'wheel' },
- columns: computed(() => {
- // 拼接序号列
- return columns1;
- }),
- data: computed(() => {
- let data = [
- {
- "heatSourceName": "Leo源",
- "supTemp": null,
- "supPres": null,
- "instFlowSup": null,
- "retTemp": null,
- "retPres": null,
- "muwInstFlow": null,
- "heatCnp": null,
- "waterCnp": null,
- "muwaccFlow": null,
- "accHeat": null
- },
- {
- "heatSourceName": "晋源",
- "supTemp": "86.89",
- "supPres": null,
- "instFlowSup": "1028.31",
- "retTemp": "41.51",
- "retPres": "0.111",
- "muwInstFlow": "514.64",
- "heatCnp": "7923.92",
- "waterCnp": "396.58",
- "muwaccFlow": "29207293.83",
- "accHeat": "680.0334"
- },
- {
- "heatSourceName": "龙山",
- "supTemp": "86.90",
- "supPres": null,
- "instFlowSup": "514.24",
- "retTemp": "41.50",
- "retPres": null,
- "muwInstFlow": "515.29",
- "heatCnp": "3960.97",
- "waterCnp": "395.64",
- "muwaccFlow": "1148264.05",
- "accHeat": "166.2449"
- }
- ]
- data.forEach((item, index) => {
- if (index === 1 || index === 2) {
- item.edit = true
- } else {
- item.edit = false
- }
- });
- return data
- }),
- },
- // 合并单元格方法,这里只合并第一行和第二行
- spanMethods({ row, $rowIndex, column, data }) {
- let fields = ["retTemp"]
- let cellValue = row[column.property]
- if ($rowIndex == 2 || $rowIndex == 3) {
- if (cellValue && fields.includes(column.property)) {
- let prevRow = data[$rowIndex - 1]
- let nextRow = data[$rowIndex + 1]
-
- if (prevRow && prevRow[column.property] === cellValue) {
- return { rowspan: 0, colspan: 0 }
- } else {
- let countRowspan = 1
- while (nextRow && nextRow[column.property] === cellValue) {
- nextRow = data[++countRowspan + $rowIndex]
- }
- if (countRowspan > 1) {
- return { rowspan: countRowspan, colspan: 1 }
- }
- }
- }
- }
- })
-
- // 提取默认插槽
- const defaultSlots1 = computed(() => {
- return columns1.map((column, index) => {
- return {
- slot: column.slots.default,
- field: column.field,
- }
- })
- })
- // 提取编辑插槽
- const editSlots1 = computed(() => {
- return columns1.map((column, index) => {
- return {
- slot: column.slots.edit,
- field: column.field
- }
- })
- })
- }
-
-
- return {
- ...toRefs(state),
- defaultSlots1,
- editSlots1,
- }
- },
-
- })
- </script>

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。