push
This commit is contained in:
243
lib/component/table/edit/table-cell.vue
Normal file
243
lib/component/table/edit/table-cell.vue
Normal file
@@ -0,0 +1,243 @@
|
||||
<template>
|
||||
<div class="editable-cell">
|
||||
<!-- 显示模式 -->
|
||||
<div class="editable-cell-text-wrapper" v-if="!getRowValue && !editable">
|
||||
<div> {{ value }}</div>
|
||||
<div class="editable-cell-action">
|
||||
<edit-outlined class="editable-cell-icon" @click="editCell" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 编辑模式 -->
|
||||
<a-popover
|
||||
v-else
|
||||
:destroyTooltipOnHide="true"
|
||||
:visible="!isUndefined(getValidateInfo) && visible"
|
||||
:content="getValidateInfo?.message"
|
||||
:overlayClassName="'ns-cell-rule-popover'"
|
||||
:getPopupContainer="(triggerNode) => triggerNode.parentNode"
|
||||
>
|
||||
<div class="editable-cell-input-wrapper">
|
||||
<component :is="column.edit.component || 'NsInput'" v-bind="formProps" />
|
||||
<!--单元格编辑-->
|
||||
<div class="editable-cell-action" v-if="editable">
|
||||
<check-outlined class="editable-cell-icon" @click="saveCell" />
|
||||
<!-- <close-outlined class="editable-cell-icon" @click="cancelCell" /> -->
|
||||
</div>
|
||||
</div>
|
||||
</a-popover>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, inject, nextTick, PropType, ref, watch } from 'vue';
|
||||
import { PropTypes } from '/nerv-lib/util/type';
|
||||
import { CheckOutlined, CloseOutlined, EditOutlined } from '@ant-design/icons-vue';
|
||||
import { TableEdit } from '/nerv-lib/component/table/use-table-edit';
|
||||
import { isUndefined, upperFirst } from 'lodash-es';
|
||||
import Schema from 'async-validator';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NsTableCell',
|
||||
components: {
|
||||
EditOutlined,
|
||||
CheckOutlined,
|
||||
CloseOutlined,
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number, Boolean, Object] as PropType<string | number | boolean | Recordable>,
|
||||
default: '',
|
||||
required: true,
|
||||
},
|
||||
record: {
|
||||
type: Object as PropType<Recordable>,
|
||||
required: true,
|
||||
},
|
||||
column: {
|
||||
type: Object as PropType<Recordable>,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
index: PropTypes.number,
|
||||
},
|
||||
setup(props) {
|
||||
const {
|
||||
getValidate,
|
||||
setValidate,
|
||||
setValue,
|
||||
getValue,
|
||||
getKey,
|
||||
validate,
|
||||
tableEdit,
|
||||
tableSave,
|
||||
} = inject('tableEdit') as TableEdit;
|
||||
const visible = ref(true);
|
||||
|
||||
const getRowKey = computed(() => {
|
||||
return getKey({ ...props.record });
|
||||
});
|
||||
|
||||
const getField = computed(() => {
|
||||
return props.column.dataIndex;
|
||||
});
|
||||
|
||||
let editable = ref(false);
|
||||
|
||||
const getCellValue = computed({
|
||||
get: () => getValue(getRowKey.value, getField.value),
|
||||
set: (val) => setValue(getRowKey.value, val, getField.value),
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.index,
|
||||
() => {
|
||||
console.log('index', props.record, props.index);
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
const getRowValue = computed(() => {
|
||||
return getValue(getRowKey.value);
|
||||
});
|
||||
|
||||
const getValidateInfo = computed({
|
||||
get: () => getValidate(getRowKey.value, getField.value),
|
||||
set: (val) => setValidate(getRowKey.value, val, getField.value),
|
||||
});
|
||||
|
||||
// setTimeout(() => console.log('getCellValue', getCellValue.value), 1000);
|
||||
|
||||
watch(
|
||||
[() => getCellValue.value, () => getRowValue.value],
|
||||
() => {
|
||||
validate(getRowKey.value, getField.value);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 解决删除后验证遗留的问题
|
||||
*/
|
||||
watch(
|
||||
() => props.index,
|
||||
() => {
|
||||
if (getValidateInfo.value) {
|
||||
visible.value = false;
|
||||
// 延迟等待隐藏动画操作
|
||||
setTimeout(() => {
|
||||
visible.value = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const editCell = () => {
|
||||
tableEdit(getRowKey.value, getField.value);
|
||||
editable.value = true;
|
||||
};
|
||||
|
||||
const cancelCell = () => {
|
||||
getValidateInfo.value = undefined; //清空验证信息
|
||||
editable.value = false;
|
||||
};
|
||||
|
||||
const saveCell = () => {
|
||||
// console.log('getValidated.value', getValidated.value);
|
||||
if (!getValidateInfo.value) {
|
||||
editable.value = false;
|
||||
tableSave(getRowKey.value, getField.value);
|
||||
}
|
||||
};
|
||||
|
||||
const formProps = computed(() => {
|
||||
const {
|
||||
component,
|
||||
valueField,
|
||||
changeEvent = 'change',
|
||||
props: componentProps,
|
||||
} = props.column.edit;
|
||||
|
||||
const isCheck =
|
||||
component && ['NsSwitch', 'NsCheckbox', 'Switch', 'Checkbox'].includes(component);
|
||||
const bindValue: Recordable = {
|
||||
[valueField || (isCheck ? 'checked' : 'value')]: getCellValue.value,
|
||||
};
|
||||
const eventKey = `on${upperFirst(changeEvent)}`;
|
||||
|
||||
const on = {
|
||||
[eventKey]: (...args: Nullable<Recordable>[]) => {
|
||||
const [e] = args;
|
||||
const target = e ? e.target : null;
|
||||
getCellValue.value = target ? (isCheck ? target.checked : target.value) : e;
|
||||
},
|
||||
};
|
||||
return {
|
||||
...componentProps,
|
||||
...bindValue,
|
||||
...on,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
editCell,
|
||||
saveCell,
|
||||
cancelCell,
|
||||
editable,
|
||||
formProps,
|
||||
visible,
|
||||
getValidateInfo,
|
||||
getCellValue,
|
||||
getRowValue,
|
||||
isUndefined,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.ns-cell-rule-popover {
|
||||
color: @error-color;
|
||||
}
|
||||
|
||||
.editable-cell {
|
||||
position: relative;
|
||||
|
||||
.editable-cell-input-wrapper,
|
||||
.editable-cell-text-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.editable-cell-action {
|
||||
width: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.editable-cell-icon {
|
||||
width: 24px;
|
||||
line-height: 28px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:hover .editable-cell-icon {
|
||||
color: #108ee9;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.editable-add-btn {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.editable-cell:hover .editable-cell-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
:deep(.ant-popover) {
|
||||
z-index: 50;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user