Files
douyin/app/src/components/editable-cell/EditableCell.vue
T
2025-09-30 15:00:32 +08:00

143 lines
2.9 KiB
Vue

<script lang="ts" setup>
import { computed, nextTick, PropType, ref, toRefs } from 'vue';
export type AntInputType =
| 'input'
| 'textarea'
| 'radio'
| 'timePicker'
| 'datePicker'
| 'rangePicker'
| 'select'
| 'mention'
| 'rate'
| 'upload'
| 'treeSelect'
| 'transfer'
| 'checkbox'
| 'cascader'
| 'autoComplete'
| 'inputNumber'
| 'slider'
| 'switch';
const emit = defineEmits<{
(e: 'update:edit', edit: boolean): void;
(e: 'update:value', value: any): void;
(e: 'pressEnter', event: KeyboardEvent): void;
}>();
const props = defineProps({
value: [String, Number, Boolean, Object],
edit: {
type: Boolean,
default: null,
},
editOnClick: {
type: Boolean,
default: true,
},
type: {
type: String as PropType<AntInputType>,
default: 'input',
validator(val: string) {
return [
'input',
'radio',
'timePicker',
'datePicker',
'rangePicker',
'select',
'mention',
'rate',
'upload',
'treeSelect',
'transfer',
'checkbox',
'cascader',
'autoComplete',
'inputNumber',
'slider',
'switch',
'textarea',
].includes(val);
},
},
options: Object,
});
const { type } = toRefs(props);
const component = computed(() => {
const _type = type.value;
return 'A' + _type.substring(0, 1).toUpperCase() + _type.substring(1);
});
const cacheEdit = ref(false);
const _edit = computed({
get() {
if (props.edit !== null) {
cacheEdit.value = props.edit;
}
return props.edit ?? cacheEdit.value;
},
set(val) {
cacheEdit.value = val;
emit('update:edit', val);
},
});
const input = ref();
function editCell() {
if (props.editOnClick) {
_edit.value = true;
nextTick(() => input.value?.focus());
}
}
function complete() {
_edit.value = false;
}
const cacheVal: any = ref(null);
const _value = computed({
get() {
if (props.value !== undefined) {
cacheVal.value = props.value;
}
return props.value ?? cacheVal.value;
},
set(val) {
cacheVal.value = val;
emit('update:value', val);
},
});
</script>
<template>
<slot v-if="_edit" class="editable-cell-input" name="input">
<component
ref="input"
@keyup.enter="complete"
@blur="complete"
v-model:value="_value"
class="editable-cell-input-component"
v-bind="options"
:is="component"
/>
</slot>
<div v-else @click="editCell" class="editable-cell-show">
<slot>
{{ value }}
</slot>
</div>
</template>
<style lang="less" scoped>
.editable-cell {
&-input {
&-component {
}
}
}
</style>