修改表格

This commit is contained in:
zouzhibing 2022-05-18 18:07:29 +08:00
parent f30a6d298a
commit 8c256aafcb
4 changed files with 237 additions and 193 deletions

View File

@ -25,7 +25,12 @@ const tableRouter = {
name: 'inline-table', name: 'inline-table',
meta: { title: '行内编辑', noCache: true } meta: { title: '行内编辑', noCache: true }
}, },
{
path: 'edit-table',
component: () => import('@/views/table/edit.vue'),
name: 'edit-table',
meta: { title: '可编辑表格', noCache: true }
},
] ]
} }

View File

@ -5,12 +5,12 @@ import { parseTime } from './uniele'
*/ */
export function formatDate(cellValue) { export function formatDate(cellValue) {
if (cellValue == null || cellValue == "") return ""; if (cellValue == null || cellValue == "") return "";
var date = new Date(cellValue) var date = new Date(cellValue)
var year = date.getFullYear() var year = date.getFullYear()
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
} }
@ -330,7 +330,7 @@ export function makeMap(str, expectsLowerCase) {
? val => map[val.toLowerCase()] ? val => map[val.toLowerCase()]
: val => map[val] : val => map[val]
} }
export const exportDefault = 'export default ' export const exportDefault = 'export default '
export const beautifierConf = { export const beautifierConf = {
@ -387,4 +387,28 @@ export function camelCase(str) {
export function isNumberStr(str) { export function isNumberStr(str) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
} }
// // 深度克隆 array 数组或 json 对象,返回克隆后的副本
export const deepObjClone = function(obj){
let weakMap = new WeakMap()
function clone (obj){
if(obj==null){return obj}
if(obj instanceof Date){ return new Date(obj) }
if(obj instanceof RegExp){ return new RegExp(obj)}
if(typeof obj !== 'object') return obj
if(weakMap.get(obj)){
return weakMap.get(obj)
}
var copy = new obj.constructor
weakMap.set(obj,copy)
for(var key in obj){
if(Object.prototype.hasOwnProperty.call(obj, key)){
var value = obj[key];
copy[key] = clone(value);
}
}
return copy;
}
return clone (obj)
};

View File

@ -5,7 +5,7 @@
<el-icon style="margin-right: 4px"><plus /></el-icon> </el-button> <el-icon style="margin-right: 4px"><plus /></el-icon> </el-button>
</div> </div>
<el-table :data="transData" style="width: 100%" row-key="id" border> <el-table :data="transData" style="width: 100%" row-key="id" border>
<template v-for="item in columns" > <template v-for="item,index in columns" >
<el-table-column v-if="item.type" :type="item.type" :width="item.width" :align="item.align" :fixed="item.fixed" :label="item.label"/> <el-table-column v-if="item.type" :type="item.type" :width="item.width" :align="item.align" :fixed="item.fixed" :label="item.label"/>
<el-table-column <el-table-column
v-else v-else
@ -68,35 +68,33 @@
type="primary" type="primary"
size="small" size="small"
icon="Edit" icon="Edit"
@click="scope.row.edit=!scope.row.edit" @click="edit(scope.row)"
> >
编辑 编辑
</el-button> </el-button>
<el-popover <el-popover
trigger="click" placement="top"
v-model:visible="scope.row.visible" placement="top" :width="160"> width="160"
v-model="scope.row.visible">
<p style="display: flex;align-items: center;margin-bottom: 10px"> <p style="display: flex;align-items: center;margin-bottom: 10px">
<el-icon color="#faad14" style="margin-right: 10px"><warning-filled /></el-icon> </p> <i class="el-icon-warning" style="margin-right: 10px;color: #faad14"></i>
删除此行</p>
<div style="text-align: right; margin: 0"> <div style="text-align: right; margin: 0">
<el-button size="small" @click="scope.row.visible = false" <el-button size="small" @click.stop="cancelVisible(scope.row)"
>取消</el-button >取消</el-button
> >
<el-button size="small" type="primary" @click="deleteAction(scope.row)" <el-button size="small" type="primary" @click.stop="deleteConfigAction(scope.row)"
>确定</el-button >确定</el-button
> >
</div> </div>
<template #reference> <el-button slot="reference" @click.stop="deleteAction(scope.row)" type="danger" size="small">删除</el-button>
<el-button
icon="Delete"
@click="scope.row.visible = true" type="danger" size="small">删除</el-button>
</template>
</el-popover> </el-popover>
<el-button <el-button
v-if="scope.row.edit" v-if="scope.row.edit"
type="primary" type="primary"
size="small" size="small"
icon="Edit" icon="Edit"
@click="cancelEdit(scope.row)" @click.stop="cancelEdit(scope.row)"
> >
取消 取消
</el-button> </el-button>
@ -109,160 +107,167 @@
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script>
import {computed, onMounted, ref, watch} from "vue"; import {deepObjClone} from '@/utils/index'
import {deepObjClone} from '@/utils/index' export default {
import { ElMessage,ElMessageBox } from 'element-plus' props:{
import { reactive } from 'vue' columns:{
const emit = defineEmits(['del','add','onChange']) type:Array,
let transData = ref([]) default:()=>[]
},
let props = defineProps({ data:{
columns:{ type:Array,
type:Array, default:()=>[]
default:()=>[] },
editableKeys:{
type:Array,
default:()=>[]
},
mode:{
type:String,
default:'bottom'
}
}, },
data:{ data(){
type:Array, return{
default:()=>[] obj:{},
}, transData:[],
editableKeys:{ visible:false,
type:Array, listLoading:false,
default:()=>[] formInline:{
}, user: '',
mode:{ region: '',
type:String,
default:'bottom'
}
})
const getData = ()=>{
let arr = deepObjClone(transData.value)
for(let item of arr){
for(let attr in item){
if(attr.includes('te__mp')){
delete item[attr]
} }
} }
} },
emit('onChange',arr) watch:{
} 'data':{
handler(val){
let obj={} let arr = deepObjClone(val)
for(let item of props.columns){ //
props.data.forEach(it=>{ for(let item of arr){
if(!obj[item.name]){ if(this.editableKeys.includes(item.id)){
obj[item.name] = null item.edit = true
} }
}) for(let attr in item){
} let temp = `${attr}te__mp`
item[temp] = item[attr]
const reset = ()=>{ }
transData.value = props.data
getData()
}
onMounted(()=>{
watch(()=>props.data,(val)=>{
// //
transData.value = deepObjClone(val)
//
for(let item of transData.value){
if(props.editableKeys.includes(item.id)){
item.edit = true
} }
// //
this.transData = arr
for(let attr in item){ },
let temp = `${attr}te__mp` deep:true,
item[temp] = item[attr] immediate:true
}
} }
// console.log('transData',transData) },
},{ created(){
immediate:true,
deep:true
})
}) let obj={}
for(let item of this.columns){
this.data.forEach(it=>{
if(!obj[item.name]){
obj[item.name] = null
const visible = ref(false) }
})
const handleSizeChange = (val: number) => {
console.log(`${val} items per page`)
}
const listLoading = ref(false)
//
const confirmEdit = (row)=>{
row.edit = false
for(let attr in row){
if(attr.includes('te__mp')){
row[(attr)] = row[(attr.replace('te__mp',''))]
} }
} this.obj = obj
getData() },
} methods:{
// cancelVisible(row){
const cancelEdit = (row)=>{ this.$set(row,'visible',false)
row.edit=!row.edit },
for(let attr in row){ getData(){
if(!attr.includes('te__mp')){ let arr = deepObjClone(this.transData)
row[attr] = row[(attr+'te__mp')] for(let item of arr){
for(let attr in item){
if(attr.includes('te__mp')){
delete item[attr]
}
}
}
this.$emit('onChange',arr)
},
reset(){
this.transData = this.data
this.getData()
},
handleSizeChange(val){
console.log(`${val} items per page`)
},
//
confirmEdit(row){
this.$set(row,'edit',false)
for(let attr in row){
if(attr.includes('te__mp')){
row[(attr)] = row[(attr.replace('te__mp',''))]
}
}
this.getData()
},
//
cancelEdit (row){
this.$set(row,'edit',false)
for(let attr in row){
if(!attr.includes('te__mp')){
if(attr!=='edit'){
row[attr] = row[(attr+'te__mp')]
}
}
}
},
edit(row){
this.$set(row,'edit',!row.edit)
},
deleteProver(row){
row.visible = true
this.$set(row,'visible',true)
let obj1 = Object.assign({},row)
obj1.visible = true
},
deleteConfigAction(row){
this.$set(row,'visible',false)
this.transData = this.transData.filter((item)=>item.id!==row.id)
this.$emit('del',row)
},
deleteAction (row){
},
add(){
let id = ~~(Math.random() * 1000000).toFixed(0)
let obj1 = Object.assign({},this.obj,{
id:id,
edit:true,
visible:false,
})
for(let attr in obj1){
let temp = `${attr}te__mp`
obj1[temp] = obj1[attr]
}
if(this.mode==='bottom'){
this.transData.push(obj1)
}
if(this.mode==='top'){
this.transData.unshift(obj1)
}
},
filterOption(item,scope){
let obj = item.options.find(ite=>ite.value===scope.row[item.name])
if(obj){
return obj.label
}
return '--'
} }
} }
} }
const formInline = reactive({
user: '',
region: '',
})
const onSubmit = () => {
console.log('submit!')
}
const deleteAction = (row)=>{
row.visible = false
transData.value = transData.value.filter((item)=>item.id!==row.id)
emit('del',row)
}
const add = ()=>{
let id = ~~(Math.random() * 1000000).toFixed(0)
let obj1 = Object.assign({},obj,{
id:id,
edit:true,
visible:false,
})
for(let attr in obj1){
let temp = `${attr}te__mp`
obj1[temp] = obj1[attr]
}
if(props.mode==='bottom'){
transData.value.push(obj1)
}
if(props.mode==='top'){
transData.value.unshift(obj1)
}
}
const filterOption = (item,scope)=>{
let obj = item.options.find(ite=>ite.value===scope.row[item.name])
if(obj){
return obj.label
}
return '--'
}
defineExpose({
reset
})
</script> </script>
<style scoped> <style scoped>
.edit-input { .edit-input {

View File

@ -1,5 +1,5 @@
<template> <template>
<div> <div class="app-container">
<div style="display: flex;justify-content: flex-end"> <div style="display: flex;justify-content: flex-end">
<el-radio-group v-model="radio"> <el-radio-group v-model="radio">
<el-radio label="top">添加到顶部</el-radio> <el-radio label="top">添加到顶部</el-radio>
@ -26,11 +26,8 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script >
import EditTable from './components/edit.vue' import EditTable from './components/edit.vue'
import { ElMessage,ElMessageBox } from 'element-plus'
import {ref} from "vue";
const table = ref()
const column = [ const column = [
{ name: 'title', { name: 'title',
label: '活动名称', label: '活动名称',
@ -84,7 +81,7 @@
update_at: '2020-05-27T08:19:22Z', update_at: '2020-05-27T08:19:22Z',
}, },
{ {
id: 624291229, id: 6242922222,
title: '活动名称三', title: '活动名称三',
readonly: '活动名称三', readonly: '活动名称三',
decs: '这个活动真好玩', decs: '这个活动真好玩',
@ -93,7 +90,7 @@
update_at: '2020-05-27T08:19:22Z', update_at: '2020-05-27T08:19:22Z',
}, },
{ {
id: 624291229, id: 62425491229,
title: '活动名称四', title: '活动名称四',
readonly: '活动名称四', readonly: '活动名称四',
decs: '这个活动真好玩', decs: '这个活动真好玩',
@ -102,7 +99,7 @@
update_at: '2020-05-27T08:19:22Z', update_at: '2020-05-27T08:19:22Z',
}, },
{ {
id: 624291229, id: 62429281229,
title: '活动名称五', title: '活动名称五',
readonly: '活动名称五', readonly: '活动名称五',
decs: '这个活动真好玩', decs: '这个活动真好玩',
@ -111,7 +108,7 @@
update_at: '2020-05-27T08:19:22Z', update_at: '2020-05-27T08:19:22Z',
}, },
{ {
id: 624291229, id: 62429091229,
title: '活动名称六', title: '活动名称六',
readonly: '活动名称六', readonly: '活动名称六',
decs: '这个活动真好玩', decs: '这个活动真好玩',
@ -120,7 +117,7 @@
update_at: '2020-05-27T08:19:22Z', update_at: '2020-05-27T08:19:22Z',
}, },
{ {
id: 624291229, id: 62421191229,
title: '活动名称七', title: '活动名称七',
readonly: '活动名称五', readonly: '活动名称五',
decs: '这个活动真好玩', decs: '这个活动真好玩',
@ -129,7 +126,7 @@
update_at: '2020-05-27T08:19:22Z', update_at: '2020-05-27T08:19:22Z',
}, },
{ {
id: 624291229, id: 6242222291229,
title: '活动名称八', title: '活动名称八',
readonly: '活动名称六', readonly: '活动名称六',
decs: '这个活动真好玩', decs: '这个活动真好玩',
@ -138,31 +135,44 @@
update_at: '2020-05-27T08:19:22Z', update_at: '2020-05-27T08:19:22Z',
}, },
] ]
export default {
components:{
EditTable
},
data(){
return{
dataSource:data,
column,
list:data,
radio:'bottom',
editableKeys:[]
}
},
created(){
let arrKeys = data.filter(item=>![624748504,624691229].includes(item.id)).map(item=>item.id)
this.editableKeys = arrKeys
},
methods:{
deleteAction(row){
console.log('删除',row)
this.$message.success('点击删除')
},
onChange(val){
this.dataSource = val
},
add(){
let arrKeys = data.map(item=>item.id) },
const radio = ref('bottom') reset(val){
const list = ref(data) this.$message.success('重置成功')
let editableKeys = ref(arrKeys) this.$refs.table.reset()
const dataSource = ref(data) },
const deleteAction = (row)=>{ config(){
console.log('删除',row) this.list = this.dataSource
ElMessage.success('点击删除') console.log('点击提交=========',this.dataSource)
} this.$message.success('点击提交数据')
const onChange = (val)=>{ }
dataSource.value = val }
}
const add = (row)=>{
}
const reset = (val)=>{
ElMessage.success('重置成功')
table.value.reset()
}
const config = ()=>{
list.value = dataSource.value
console.log('点击提交=========',dataSource.value)
ElMessage.success('点击提交数据')
} }
</script> </script>