IVIEW-ADMIN表格行编辑

iview-admin的行编辑官方并没有给出代码demo,
希望做到如同easyi-ui可编辑行组件类似
最终效果图如下
在这里插入图片描述

先定义编辑文本

  1. 可编辑文本组件
<template>
  <div class="input-edit-outer">
    <div v-if="!isEditting" class="input-edit-con">
      <span class="value-con">{{ newValue ? newValue : '-' }}</span></div>
    <div v-else class="input-editting-con">
      <Input :value="newValue" @input="handleInput" class="input-edit-input"/>
    </div>
  </div>
</template>

<script>
export default {
  name: 'EditTable',
  data(){
  	return {
  		newValue:''
  	}
  },
  props: {
    edittingCellId: [String, Number],
    id: [String, Number],
    params: Object,
    value:[String, Number]
  },
  computed: {
    isEditting () {
      return this.edittingCellId === `editting-${this.params.index}-${this.id}`
    }
  },
  methods: {
    handleInput (val) {
      this.$emit('input', val)
    }
  },
  mounted(){
  	this.newValue = this.value
  }
}
</script>

<style lang="less" scoped>
.input-edit-outer{
  height: 100%;
  .input-edit-con{
    height: 100%;
    .value-con{
      vertical-align: middle;
    }
  }
  .input-editting-con{
    .input-edit-input{
      width: ~"calc(100% - 60px)";
    }
  }
}
</style>

  1. 可编辑下拉组件
<template>
  <div class="select-edit-outer">
    <div v-if="!isEditting" class="select-edit-con">
      <span class="value-con">{{ displayText ? displayText : '-' }}</span>
    </div>
    <div v-else class="select-editting-con">
      <Select :value="displayValue" class="select-edit-input" @on-change="onChange">
        <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>
   		</Select>
    </div>
  </div>
</template>

<script>
export default {
  name: 'SelectTable',
  data(){
  	return{
  		displayText : '',
  		displayValue : '',
  		selectOptions:[]
  	}
  },
  props: {
    edittingCellId: [String, Number],
    params: Object,
    value:[String, Number],
    id:[String, Number],
    options:Array
  },
  computed: {
    isEditting () {
      return this.edittingCellId === `editting-${this.params.index}-${this.id}`
    }
  },
  methods: {
    onChange (val) {
      this.$emit('on-change', val)
    }
  },
  mounted(){
  	this.displayValue = this.value
  	this.displayText = this.options.find(ele => ele.value == this.value).label//根据value值获取options的对应的值
  },
  watch:{
  	
  }
}
</script>

<style lang="less" scoped>
.select-edit-outer{
  height: 100%;
  .select-edit-con{
    height: 100%;
    .value-con{
      vertical-align: middle;
    }
  }
  .select-editting-con{
    .select-edit-input{
      width: ~"calc(100% - 60px)";
    }
  }
}
</style>

3.父组件

<style lang="less">
  @import './dynamicLogLevel.less';
</style>

<template>
  <div class="dynamicLogLevel">
		<Row>
		<tables ref="tables" editable :border="true" size="small" 
      	v-model="tableData" :columns="columns" 
       :simple="simple" />
  	</Row>
  	<Modal ref="createModal" :closable="false" draggable v-model="createModal" width="300">
  		<div slot="header">
  			<span>{{ createTitle }}</span>
  		</div>
			<Form ref="createForm" :model="createForm" :rules="ruleValidate" >
				<Row>
						<FormItem prop="logger">
							<Input type="text" v-model="createForm.logger" :maxlength="50" placeholder="logger名"></Input>
						</FormItem>
					</Col>
				</Row>
				<Row>
						<FormItem prop="loggerLevel">
							<Select v-model="createForm.loggerLevel" filterable placeholder="请选择日志级别">
	              <Option value="DEBUG">DEBUG</Option>
                <Option value="INFO">INFO</Option>
                <Option value="ERROR">ERROR</Option>
							</Select>
						</FormItem>
				</Row>
				<Row>
						<FormItem prop="loggerState">
							<Select v-model="createForm.loggerState" filterable placeholder="请选择有效状态">
	              <Option value="TRUE">TRUE</Option>
                <Option value="FALSE">FALSE</Option>
							</Select>
						</FormItem>
				</Row>
			</Form>
			<div slot="footer" align="center">
				<Button type="default" size="large" @click="cancle('createForm')">取消</Button>
				<Button type="primary" size="large" @click="query('createForm')">新建配置</Button>
			</div>
  	</Modal>
  </div>
</template>

<script>
import Tables from '_c/tables'
import EditTable from '_c/editTable'
import SelectTable from '_c/selectTable'
import InputTable from '_c/inputTable'
import { getHostsData, getRecordData } from '@/api/data'
import config from '@/config'

export default{
  name: 'hosts',
  components: {
    Tables
  },
  data () {
    return {
      simple:false,
      columns: [
        {
        	title: ' ',
        	width:120,
    			align: 'left',
	        render: (h, params) => {
	        		let isExpand = params.row.isExpand
	        		let isDown = params.row.isDown
	        		let level = params.row.level
	        		let marginLeft = '0'
	        		let iconType = !isDown ? 'ios-arrow-forward' : 'ios-arrow-down'
	        		//根据level是第几层去判断样式以及调用的方法
	        		switch (level){
	        			case 1:
	        				marginLeft = '0'
	        				break;
	        			case 2:
	        				marginLeft = '15px'
	        				break;
	        			case 3:
	        				marginLeft = '30px'
	        				iconType = 'md-create'
	        			default:
	        				break;
	        		}
	        		if(!isExpand && level != 3){
		            return h('div',{style:{cursor: 'pointer'}},[
					            	h('Icon',{props:{type:iconType},style:{marginLeft:marginLeft},on:{click: (e) => {e.stopPropagation();this.doWhich(level, params)}}})
		            			])
	        		}else if(level === 3){
	        			//当level 为3时,返回的是操作按钮
				        return h(EditTable, {
				          props: {
				            edittingCellId: this.edittingCellId,
				            params:params,
				            id:params.row.id
				          },
				          style:{
				          	marginLeft:'30px'
				          },
				          on: {
				            'on-start-edit-table': (newParams) => {
				            	this.editedParams = params
		    							this.edittingCellId = `editting-${newParams.index}-${params.row.id}`//此值要确保是唯一值
				            },
				            'on-cancel-edit-table': (newParams) => {
		    							this.edittingCellId = ''
				            },
				            'on-save-edit-table': (newParams) => {
		    							this.edittingCellId = ''
											this.onSaveEditRow()
				            }
				          }
				        })
	        		}else{
	        			return ''
	        		}
	        }
        },
        {title: '项目名', key: 'jobName', sortable:true, align: 'center'},
        {
        	title: '级别', 
        	key: 'levelState', 
        	sortable:true, 
        	align: 'center',
        	render:(h, params) =>{
		        return h(SelectTable, {
		          props: {
		            edittingCellId: this.edittingCellId,
		            params:params,
		            value:params.row.levelState,
							  options: [{
							  	value: 'DEBUG',
							  	label: 'DEBUG'
							  }, {
							  	value: 'INFO',
							  	label: 'INFO'
							  }, {
							  	value: 'ERROR',
							  	label: 'ERROR'
							  }]
		          },
		          on: {
		            'on-select-change': (val) => {
		            	//监听返回的select事件,将select值返回到修改后的editedParams
		            	this.editedParams.row.levelState = val
		            }
		          }
		        })
				  }
        },
        {
        	title: '生效状态', 
        	key: 'disableState', 
        	sortable:true, 
        	align: 'center',
        	render:(h, params) =>{
		        return h(SelectTable, {
		          props: {
		            edittingCellId: this.edittingCellId,
		            params:params,
		            value:params.row.disableState,
							  options: [{
							  	value: 'TRUE',
							  	label: 'TRUE'
							  }, {
							  	value: 'FALSE',
							  	label: 'FALSE'
							  }]
		          },
		          on: {
		            'on-select-change': (val) => {
		            	//监听返回的select事件,将select值返回到修改后的editedParams
		            	this.editedParams.row.disableState = val
		            }
		          }
		        })
				  }
        },
        {
        	title:'操作',
        	width:150,
        	render:(h, params) =>{
	        		let level = params.row.level
	        		let iconType = 'md-copy'
	        		//根据level是第几层去判断样式以及调用的方法
	        		switch (level){
	        			case 1:
	        				iconType = 'ios-copy'
	        				break;
	        			case 2:
	        				iconType = 'ios-document'
	        				break;
	        			default:
	        				break;
	        		}
	        		if(level === 3){
	        			return h('div', [
						        		h('div',{style:{display:'inline-block'},on:{click : (e)=>{e.stopPropagation();}}},[
						            h('Poptip', {props: {confirm: true,title: '你确定要删除吗?'},on: {'on-ok': (e) => {this.handleDelete (params)}}}, [
						                h('Icon',{props:{type: 'md-trash',size:'20',color:'#2399E5'},style:{cursor:'pointer'}})
						              ])
						        		])
						          ])
	        		}else{
	            	return h('div',{style:{cursor: 'pointer'}},[
				            	h('Icon',{props:{type:iconType,size:20},style:{color:'#2399E5'},on:{click: (e) => {e.stopPropagation();this.doCopy(level, params)}}})
	            			])
	        		}
	        }
        }
      ],
      tableData: [],
      edittingCellId:'',
	    editedParams:{},//编辑中的行对象
	    createModal:false,
	    createTitle:'新增动态日志配置',
	    createForm:{
	    	logger:'',
	    	loggerLevel:'',
	    	loggerState:''
	    },
	    ruleValidate:{
	        logger: [
	            { required: true, message: 'logger名不能为空', trigger: 'blur' }
	        ],
	        loggerLevel: [
	            { required: true, message: '日志级别不能为空', trigger: 'blur' }
	        ],
	        loggerState: [
	            { required: true, message: '有效状态不能为空', trigger: 'blur' }
	        ]
	    },
	    createLevel:'',
	    createParams:{}
    }
  },
  mounted () {
    this.getHostsDatas();
  },
  methods: {
//	删除当前行
  	handleDelete(param){
  		console.log("param=删除当前行操作")
  	},
    getHostsDatas(){
      getHostsData().then(res => {
        let tableDatas = res.data.data
        tableDatas.map( item =>{
        	item.isExpand = false//默认数据中加上是否展开属性,默认不展开
        	item.level = 1 //默认第一次加载的数据为第一层数据,总共三层,第一层第二层可以展开,第三层是修改
        	item.isDown = false//默认行数据向下展开图标不向下
        })
        this.tableData = tableDatas
        this.dataCount = res.data.total
      })
    },
		expandRow1(params){
			//判断当前行是否展开,如果未展开,执行以下方法,先展开再请求接口加载到tabledata中当前data index 后
			if(!this.tableData[params.index].isDown){
				getRecordData().then(res => {
	      	return res.data
	      }).then( data => {
	      	this.tableData[params.index].isDown = true
	      	let newArrayData = data
	      	this.tableData[params.index].totals = newArrayData.length //将展开操作查询到的数据总条数加到当前行数据的totals上
	      	newArrayData.map( item =>{
	      		item.isExpand = false
	        	item.level = 2 //默认第一次加载的数据为第一层数据,总共三层,第一层第二层可以展开,第三层是修改
	        	item.upLevelIndex = params.index
	      	})
					newArrayData.map( (value, key) =>{
						this.tableData.splice(params.index + key + 1, 0, value)
					})
	      })
			}else{//如果当前行已展开,则隐藏
				this.tableData[params.index].isDown = false
				this.tableData.splice(params.index + 1, params.row.totals)
			}
		},
		expandRow2(params){
			//判断当前行是否展开,如果未展开,执行以下方法,先展开再请求接口加载到tabledata中当前data index 后
			if(!this.tableData[params.index].isDown){
				getRecordData().then(res => {
	      	return res.data
	      }).then( data => {
	      	this.tableData[params.index].isDown = true
	      	let newArrayData = data
	      	//将展开操作查询到的数据总条数加到当前行数据的上一级(level 1)的totals上
	      	this.tableData[params.row.upLevelIndex].totals += parseInt(newArrayData.length) 
	      	//将展开操作查询到的数据总条数加到当前行数据的totals上
	      	this.tableData[params.index].totals = newArrayData.length
	      	newArrayData.map( item =>{
	      		item.isExpand = false
	      		//默认第一次加载的数据为第一层数据,总共三层,第一层第二层可以展开,第三层是修改
	        	item.level = 3 
	        	item.upLevelIndex = params.index
	      	})
					newArrayData.map( (value, key) =>{
						this.tableData.splice(params.index + key + 1, 0, value)
					})
	      })
			}else{//如果当前行已展开,则隐藏
	      //将展开操作查询到的数据总条数加到当前行数据的上一级(level 1)的totals上
	      this.tableData[params.row.upLevelIndex].totals -= parseInt(params.row.totals)
				this.tableData[params.index].isDown = false
				this.tableData.splice(params.index + 1, params.row.totals)
			}
		},
		doWhich(level, params){
			switch (level){
				//调用1级的展开方法
				case 1:
					console.log("expandRow1")
					this.expandRow1(params)
					break;
				//调用2级的展开方法
				case 2:
					console.log("expandRow2")
					this.expandRow2(params)
					break;
				//调用3级的修改方法
				case 3:
					console.log("update")
					break;
				//不调用任何方法并页面提示报错
				default:
					this.$Modal.error({
	            title: "方法错误",
	            content: "方法调用错误,请刷新重试!"
	        });
					break;
			}
		},
		onSaveEditRow(){
      console.log("editedParams="+JSON.stringify(this.editedParams))
		},
		//给当前行添加下级日志文件,如果level为1级则给下面所有的项目名IP都新增,如果是2级则只给自己当前下面IP新增
		doCopy(level, params){
			this.createModal = true
			this.createLevel = level
			this.createParams = params
		},
		cancle(name){
			this.createModal = false
			this.$refs[name].resetFields()
		},
		query(name){
	    this.$refs[name].validate((valid) => {
	        if (valid) {
	        		this.createModal = false
							this.$refs[name].resetFields()
	        } else {
	            this.$Message.error('请填写正确信息!');
	        }
	    })
		}
  },
  watch:{
  	
  }
}
</script>


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值