维护el-table列,循环生成el-table

1、lib/setting.js(维护table列)

javascript 复制代码
const columns=[
	{ label: '类型', prop: 'energyName', width: '150', isText: true },
	{ label: '消耗量(t或10⁴m³)', prop: 'inputNum', isInput: true },
	{
	  label: 'CO₂',
	  children: [
		// { label: '核算因子', prop: 'co2FactorValue', width: '120', isShow: false },
		{ label: '排放量', prop: 'co2Value', width: '120' },
		{ label: '排放因子', prop: 'co2FactorType', isSelect: true }
	  ]
	},
	{
	  label: 'CH₄',
	  children: [
		// { label: '核算因子', prop: 'ch4FactorValue', width: '120' },
		{ label: '排放量', prop: 'ch4Value', width: '120' },
		{ label: '排放因子', prop: 'ch4FactorType', isSelect: true }
	  ]
	},
	{
	  label: 'N₂O',
	  children: [
		{ label: '排放量', prop: 'n2oValue', width: '120' },
		{ label: '排放因子', prop: 'n2oFactorType', isSelect: true }
	  ]
	}
  ]

2、customTable.vue

html 复制代码
<template>
	<slot name="title"> </slot>
<!-- show-summary  -->
	<el-table :data="tableData" show-summary style="width: 99%;" class="elTable">
		<el-table-column v-for="(column, index) in columns" :key="index" :prop="column.prop" :label="column.label" :width="column.width">
			<template v-if="!column.children" #default="scope">
				<div>
					{{ column.isText ? scope.row[column.prop] : "" }}
					<el-input v-if="column.isInput" v-model="scope.row[column.prop]" @change="inputNum(scope.row)" :disabled="props.isDetail"/>
					<input-select-module v-if="column.isSelect"></input-select-module>
				</div>
			</template>
			<template v-if="column.children">
				<el-table-column v-for="(subColumn, subIndex) in column.children"  :key="subIndex" :prop="subColumn.prop" :label="subColumn.label" :width="subColumn.width">
					<template #default="scope">
						<el-input v-if="subColumn.isInput" v-model="scope.row[subColumn.prop]" :disabled="props.isDetail"/>
						<input-select-module v-if="subColumn.isSelect" v-model:row="scope.row" v-model:disabled="props.isDetail" v-model:subColumn="subColumn.prop" @changeFactorValue="changeFactorValue(scope.row, scope.row[subColumn.prop])"></input-select-module>
					</template>
				</el-table-column>
			</template>
		</el-table-column>
	</el-table>
</template>

做了个自定义组件

组件描述:选择值为缺省值时,该组件为下拉框,选择值为自测值时,组件为输入框

html 复制代码
<template>
  <div>
    <!-- v-model="props.inputVal" -->
    <el-input type="text" v-model="props.row[props.subColumn]" @change="changeInput(props.row[props.subColumn])"
      id="input-select" @click="click" :readonly="inputReadonly" style="position: relative" />
    <div class="dropdown" :style="dropdownStyle">
      <div class="dropdown-item" data-value="自测值" @click="clickdropdown('自测值')">自测值</div>
      <div class="dropdown-item" data-value="缺省值" @click="clickdropdown('缺省值')">缺省值</div>
    </div>
  </div>
</template>

<script setup>
import { ref, defineEmits, watch } from 'vue'

const props = defineProps({
  subColumn: {
    type: String,
    required: true
  },
  row: {
    type: Object,
    required: true
  },
  disabled: {
    type: Boolean,
  },
})

const emit = defineEmits(['changeFactorType'])

const inputReadonly = ref(true)
const dropdownStyle = ref({ display: 'none' })

window.addEventListener('click', (event) => {
  if (!props.disabled) {
    if (event.target.id != 'input-select') {
      dropdownStyle.value = { display: 'none' }
    } else {
    }
  }
})
window.addEventListener('scroll', function () {
  for (var i = 0; i < document.getElementsByClassName("dropdown").length; i++) {
    document.getElementsByClassName("dropdown")[i].style.display = 'none';
  }
}, true)

const click = (event) => {
  debugger
  if (!props.disabled) {
    for (var i = 0; i < document.getElementsByClassName('dropdown').length; i++) {
      document.getElementsByClassName('dropdown')[i].style.display = 'none'
    }

    var rect = event.target.getBoundingClientRect();

    // 打印元素的位置
    let top=rect.top+32;
    let left=rect.left-10;
    dropdownStyle.value = {
        display: 'block',
        position: 'fixed',
        top:top+'px',
        left:left+"px",
        border: '#909399 1px solid',
        'border-radius': '4px',
        background: '#fff',
        'z-index': '100',
        width: '150px'
      }
  }
}

// 选择自测值,缺省值,控制下拉框显隐
// 选择:缺省值-计算方式:消耗量*默认核算因子
// 选择:自测值-排放因子输入框清空,手动填写
const clickdropdown = (val) => {

  dropdownStyle.value = { display: 'none' }
  if (val == '缺省值') {
    props.row[props.subColumn] = val
    props.subColumn == 'co2FactorType'
      ? (props.row.co2Value = props.row.inputNum * props.row.co2FactorValue)
      : props.subColumn == 'ch4FactorType'
        ? (props.row.ch4Value = props.row.inputNum * props.row.ch4FactorValue)
        : (props.row.n2oValue = props.row.inputNum * props.row.n2oFactorValue)
    inputReadonly.value = true
    dropdownStyle.value = { display: 'none' }
  } else if (val == '自测值') {
    props.subColumn == 'co2FactorType'
      ? (props.row.co2Value = '')
      : props.subColumn == 'ch4FactorType'
        ? (props.row.ch4Value = '')
        : (props.row.n2oValue = '')
    props.row[props.subColumn] = ''
    inputReadonly.value = false
    dropdownStyle.value = { display: 'none' }
  }
}

// 排放因子为自测值时,计算排放量,计算公式:消耗量 * 排放因子
const changeInput = (value) => {
  if (value != '自测值' && value != '缺省值') {
    if (!/^-?\d+(\.\d+)?$/.test(value)) {
      ElMessage.error('输入不合法')
      props.row[props.subColumn] = ''
      props.subColumn == 'co2FactorType'
        ? (props.row.co2Value = '')
        : props.subColumn == 'ch4FactorType'
          ? (props.row.ch4Value = '')
          : (props.row.n2oValue = '')
    } else if (props.row.inputNum != '') {
      props.subColumn == 'co2FactorType'
        ? (props.row.co2Value = props.row.inputNum * value)
        : props.subColumn == 'ch4FactorType'
          ? (props.row.ch4Value = props.row.inputNum * value)
          : (props.row.n2oValue = props.row.inputNum * value)
    }
  }
}

</script>

<style>
.dropdown {
  border: #3f3f3f 1px solid;
  position: absolute;
  width: 120px;
}

.dropdown-item {
  cursor: pointer;
  text-indent: 8px;
}
</style>
相关推荐
别拿曾经看以后~8 分钟前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
川石课堂软件测试13 分钟前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
JerryXZR28 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
problc43 分钟前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
待磨的钝刨3 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
Devil枫6 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
weixin_422201307 小时前
element plus el-form自定义验证输入框为纯数字函数
element plus·el-from·el-input·纯数字·验证器
GIS程序媛—椰子7 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js