p-pc-ui 1.3.12 → 1.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/p-button-rounded/p-button-rounded.vue +1 -1
- package/dist/components/p-form/p-form.vue +155 -78
- package/dist/components/p-modal/p-modal.vue +1 -1
- package/dist/components/p-modal-confirm/p-modal-confirm.vue +1 -3
- package/dist/components/p-modal-form/p-form-modal.vue +6 -2
- package/dist/components/p-table/p-table.vue +6 -9
- package/package.json +1 -2
|
@@ -60,7 +60,7 @@ const btnClick = useDebounceFn(async () => {
|
|
|
60
60
|
|
|
61
61
|
<a-tooltip color="var(--secondary-color-light)" :overlayInnerStyle="{ color: '#fff' }" :title="tooltip"
|
|
62
62
|
v-bind="$attrs">
|
|
63
|
-
<a-button @click="btnClick"
|
|
63
|
+
<a-button @click="btnClick" :loading="loading || builtInLoading" class="font-semibold"
|
|
64
64
|
:class="disabled ? 'cursor-not-allowed' : 'hover:opacity-80 active:opacity-100'" :style="{
|
|
65
65
|
background: disabled ? '#b5b5b5' : bgColor,
|
|
66
66
|
color: disabled ? '#fff' : color,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { ref, reactive, onMounted, render, onBeforeMount, useSlots, toRaw, shallowRef } from "vue";
|
|
2
|
+
import { ref, reactive, onMounted, render, onBeforeMount, useSlots, toRaw, shallowRef, isRef, isReactive } from "vue";
|
|
3
3
|
import type { FormDataItem } from "./index";
|
|
4
4
|
import {
|
|
5
5
|
Button as AButton,
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
Upload as AUpload,
|
|
17
17
|
Textarea as ATextarea,
|
|
18
18
|
Space as ASpace,
|
|
19
|
+
DatePicker as ADatePicker,
|
|
19
20
|
} from "ant-design-vue";
|
|
20
21
|
import type { FormInstance } from "ant-design-vue";
|
|
21
22
|
import * as _ from "../../utils/dataUtils";
|
|
@@ -137,14 +138,13 @@ const buildSelectLoadParams = (renderItem: FormDataItem & { [key: string]: any }
|
|
|
137
138
|
const normalizeSelectLoadResult = (res: SelectLoadResult, state: SelectLoadState) => {
|
|
138
139
|
const list = Array.isArray(res) ? res : res?.data || [];
|
|
139
140
|
|
|
140
|
-
const hasMore =
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
: typeof res?.pages?.total === "number" && typeof res?.pages?.now === "number"
|
|
141
|
+
const hasMore = Array.isArray(res)
|
|
142
|
+
? list.length >= state.pageSize
|
|
143
|
+
: typeof res?.pages?.total === "number" && typeof res?.pages?.now === "number"
|
|
144
144
|
? res.pages.now < res.pages.total
|
|
145
145
|
: typeof res?.count === "number"
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
? state.pageNum * state.pageSize < res.count
|
|
147
|
+
: list.length >= state.pageSize;
|
|
148
148
|
|
|
149
149
|
return {
|
|
150
150
|
list,
|
|
@@ -154,7 +154,7 @@ const normalizeSelectLoadResult = (res: SelectLoadResult, state: SelectLoadState
|
|
|
154
154
|
|
|
155
155
|
const fetchSelectOptions = async (
|
|
156
156
|
renderItem: FormDataItem & { [key: string]: any },
|
|
157
|
-
options: { reset?: boolean; keyword?: string } = {}
|
|
157
|
+
options: { reset?: boolean; keyword?: string } = {},
|
|
158
158
|
) => {
|
|
159
159
|
if (renderItem.type !== "select" || !renderItem.loadDataFunc) return;
|
|
160
160
|
const state = ensureSelectLoadState(renderItem);
|
|
@@ -258,7 +258,6 @@ const disposeRenderData = async (renderData: FormDataItem[]) => {
|
|
|
258
258
|
fieldType = "array";
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
|
|
262
261
|
if (required) {
|
|
263
262
|
rules.push({
|
|
264
263
|
type: renderItem.type == "uploadOss" || renderItem.type == "uploadTos" ? "array" : renderItem.fieldType,
|
|
@@ -294,8 +293,6 @@ const disposeRenderData = async (renderData: FormDataItem[]) => {
|
|
|
294
293
|
}
|
|
295
294
|
}
|
|
296
295
|
|
|
297
|
-
|
|
298
|
-
|
|
299
296
|
renderItem.rules = rules;
|
|
300
297
|
|
|
301
298
|
// 处理下拉选择
|
|
@@ -491,6 +488,10 @@ const getFormData = async (options: { no_check?: Boolean } = {}) => {
|
|
|
491
488
|
_.set(returnFormData, key.split("__"), formData[key]);
|
|
492
489
|
} else if (renderItem.type == "datePicker") {
|
|
493
490
|
returnFormData[key] = dayjs(formData[key]).format("YYYY-MM-DD HH:mm:ss");
|
|
491
|
+
}
|
|
492
|
+
else if ( isRef(formData[key]) || isReactive(formData[key]) ) {
|
|
493
|
+
|
|
494
|
+
returnFormData[key] = toRaw(formData[key]);
|
|
494
495
|
} else {
|
|
495
496
|
returnFormData[key] = formData[key];
|
|
496
497
|
}
|
|
@@ -510,9 +511,13 @@ const resetForm = () => {
|
|
|
510
511
|
* 确认按钮点击
|
|
511
512
|
*/
|
|
512
513
|
const confirmClick = async () => {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
514
|
+
try {
|
|
515
|
+
const formData = await getFormData();
|
|
516
|
+
if (Object.keys(formData).length == 0) return;
|
|
517
|
+
emits("confirm", formData, resetForm);
|
|
518
|
+
} catch (error) {
|
|
519
|
+
console.warn("Form validation failed:", error);
|
|
520
|
+
}
|
|
516
521
|
};
|
|
517
522
|
|
|
518
523
|
const uploadChange = (e, renderItem) => {
|
|
@@ -621,26 +626,46 @@ defineExpose({
|
|
|
621
626
|
</script>
|
|
622
627
|
|
|
623
628
|
<template>
|
|
624
|
-
<a-form
|
|
625
|
-
|
|
629
|
+
<a-form
|
|
630
|
+
ref="formRef"
|
|
631
|
+
:model="formState"
|
|
632
|
+
name="basic"
|
|
633
|
+
autocomplete="off"
|
|
634
|
+
:layout="layout"
|
|
635
|
+
:required-mark="requiredMark"
|
|
636
|
+
>
|
|
626
637
|
<div v-for="(renderItem, index) in renderData">
|
|
627
|
-
<a-form-item
|
|
638
|
+
<a-form-item
|
|
639
|
+
:label-col="{ span: renderItem.hideLabel ? 0 : renderItem.labelSpan || labelSpan }"
|
|
628
640
|
:wrapper-col="{ span: renderItem.hideLabel ? undefined : renderItem.valueSpan || valueSpan }"
|
|
629
641
|
v-show="!renderItem.visibleHook || (renderItem.visibleHook && renderItem.visibleHook(formState))"
|
|
630
|
-
:label="renderItem.label && !renderItem.hideLabel ? renderItem.label : ''"
|
|
631
|
-
:
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
}"
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
642
|
+
:label="renderItem.label && !renderItem.hideLabel ? renderItem.label : ''"
|
|
643
|
+
:name="renderItem.key"
|
|
644
|
+
:colon="renderItem.colon == undefined ? true : renderItem.colon"
|
|
645
|
+
:rules="
|
|
646
|
+
!renderItem.visibleHook || (renderItem.visibleHook && renderItem.visibleHook(formState))
|
|
647
|
+
? renderItem.rules
|
|
648
|
+
: undefined
|
|
649
|
+
"
|
|
650
|
+
:style="{
|
|
651
|
+
marginBottom: isSearchForm ? '20px' : '0px',
|
|
652
|
+
}"
|
|
653
|
+
:tooltip="renderItem.tooltip"
|
|
654
|
+
:label-align="renderItem.labelAlign || 'right'"
|
|
655
|
+
>
|
|
656
|
+
<div
|
|
657
|
+
:style="{
|
|
658
|
+
opacity: renderItem.disabled ? 0.6 : 1,
|
|
659
|
+
cursor: renderItem.disabled ? 'not-allowed' : 'auto',
|
|
660
|
+
}"
|
|
661
|
+
>
|
|
662
|
+
<a-input
|
|
663
|
+
v-model:value="formState[renderItem.key]"
|
|
664
|
+
v-if="renderItem.type == 'input' && [undefined, 'string'].includes(renderItem.fieldType)"
|
|
665
|
+
type="text"
|
|
666
|
+
:disabled="renderItem.disabled"
|
|
667
|
+
:placeholder="renderItem.placeholder || `请输入${renderItem.label}`"
|
|
668
|
+
>
|
|
644
669
|
<template v-if="renderItem.prefix" v-slot:prefix>
|
|
645
670
|
<component :is="renderItem.prefix" />
|
|
646
671
|
</template>
|
|
@@ -649,9 +674,13 @@ defineExpose({
|
|
|
649
674
|
</template>
|
|
650
675
|
</a-input>
|
|
651
676
|
|
|
652
|
-
<a-input
|
|
653
|
-
v-
|
|
654
|
-
|
|
677
|
+
<a-input
|
|
678
|
+
v-model:value.number="formState[renderItem.key]"
|
|
679
|
+
v-if="renderItem.type == 'input' && renderItem.fieldType == 'number'"
|
|
680
|
+
type="number"
|
|
681
|
+
:disabled="renderItem.disabled"
|
|
682
|
+
:placeholder="renderItem.placeholder || `请输入${renderItem.label}`"
|
|
683
|
+
>
|
|
655
684
|
<template v-if="renderItem.prefix" v-slot:prefix>
|
|
656
685
|
<component :is="renderItem.prefix" />
|
|
657
686
|
</template>
|
|
@@ -660,25 +689,37 @@ defineExpose({
|
|
|
660
689
|
</template>
|
|
661
690
|
</a-input>
|
|
662
691
|
|
|
663
|
-
<a-input-password
|
|
664
|
-
|
|
665
|
-
|
|
692
|
+
<a-input-password
|
|
693
|
+
v-model:value="formState[renderItem.key]"
|
|
694
|
+
v-if="renderItem.type == 'password'"
|
|
695
|
+
type="password"
|
|
696
|
+
:disabled="renderItem.disabled"
|
|
697
|
+
:placeholder="renderItem.placeholder || `请输入${renderItem.label}`"
|
|
698
|
+
>
|
|
666
699
|
<template v-if="renderItem.prefix" v-slot:prefix>
|
|
667
700
|
<component :is="renderItem.prefix" />
|
|
668
701
|
</template>
|
|
669
702
|
</a-input-password>
|
|
670
703
|
|
|
671
|
-
<a-input
|
|
672
|
-
v-
|
|
673
|
-
|
|
704
|
+
<a-input
|
|
705
|
+
v-model:value="formState[renderItem.key]"
|
|
706
|
+
v-if="renderItem.type == 'code' && [undefined, 'string'].includes(renderItem.fieldType)"
|
|
707
|
+
type="text"
|
|
708
|
+
:disabled="renderItem.disabled"
|
|
709
|
+
:placeholder="renderItem.placeholder || `请输入${renderItem.label}`"
|
|
710
|
+
>
|
|
674
711
|
<template v-if="renderItem.prefix" v-slot:prefix>
|
|
675
712
|
<component :is="renderItem.prefix" />
|
|
676
713
|
</template>
|
|
677
714
|
<template v-slot:suffix>
|
|
678
|
-
<span
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
715
|
+
<span
|
|
716
|
+
v-if="
|
|
717
|
+
(!renderItem.activityFunc || (renderItem.activityFunc && renderItem.activityFunc(formState))) &&
|
|
718
|
+
renderItem.sendStatus != 'sending'
|
|
719
|
+
"
|
|
720
|
+
class="send-notice send-notice-activity"
|
|
721
|
+
@click="sendNoticeClick(renderItem)"
|
|
722
|
+
>
|
|
682
723
|
{{ renderItem.codeName }}
|
|
683
724
|
</span>
|
|
684
725
|
<span v-else class="send-notice">
|
|
@@ -687,50 +728,83 @@ defineExpose({
|
|
|
687
728
|
</template>
|
|
688
729
|
</a-input>
|
|
689
730
|
|
|
690
|
-
<a-textarea
|
|
691
|
-
:
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
:
|
|
696
|
-
|
|
697
|
-
|
|
731
|
+
<a-textarea
|
|
732
|
+
v-model:value="formState[renderItem.key]"
|
|
733
|
+
v-if="renderItem.type == 'textarea'"
|
|
734
|
+
:disabled="renderItem.disabled"
|
|
735
|
+
:placeholder="renderItem.placeholder || `请输入${renderItem.label}`"
|
|
736
|
+
:auto-size="{ minRows: 2, maxRows: 10 }"
|
|
737
|
+
/>
|
|
738
|
+
|
|
739
|
+
<a-select
|
|
740
|
+
style="min-width: 170px; margin-right: 15px"
|
|
741
|
+
v-model:value="formState[renderItem.key]"
|
|
742
|
+
:placeholder="renderItem.placeholder || `请选择`"
|
|
743
|
+
v-if="renderItem.type == 'select'"
|
|
744
|
+
:disabled="renderItem.disabled"
|
|
745
|
+
:fieldNames="renderItem.fieldNames || { label: 'label', value: 'value' }"
|
|
746
|
+
:options="renderItem.optionList"
|
|
747
|
+
:mode="renderItem.isMultiple ? 'multiple' : undefined"
|
|
698
748
|
:show-search="renderItem.enableSearch || !!renderItem.loadDataFunc"
|
|
699
749
|
:filter-option="renderItem.loadDataFunc ? false : !!renderItem.enableSearch"
|
|
700
750
|
:option-filter-prop="renderItem.fieldNames?.label || 'label'"
|
|
701
751
|
:loading="(renderItem as any).__selectState?.loading"
|
|
702
752
|
@search="(keyword) => onSelectSearch(keyword, renderItem as any)"
|
|
703
|
-
@popupScroll="(e) => onSelectPopupScroll(e, renderItem as any)"
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
753
|
+
@popupScroll="(e) => onSelectPopupScroll(e, renderItem as any)"
|
|
754
|
+
></a-select>
|
|
755
|
+
|
|
756
|
+
<a-radio-group
|
|
757
|
+
v-if="renderItem.type == 'radio'"
|
|
758
|
+
v-model:value="formState[renderItem.key]"
|
|
759
|
+
:disabled="renderItem.disabled"
|
|
760
|
+
>
|
|
707
761
|
<a-radio v-for="item in renderItem.optionList" :value="item[renderItem.fieldNames?.value || 'value']">
|
|
708
762
|
{{ item[renderItem.fieldNames?.label || "label"] }}
|
|
709
763
|
</a-radio>
|
|
710
764
|
</a-radio-group>
|
|
711
765
|
|
|
712
|
-
<a-date-picker
|
|
713
|
-
:
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
:
|
|
766
|
+
<a-date-picker
|
|
767
|
+
v-model:value="formState[renderItem.key]"
|
|
768
|
+
v-if="renderItem.type === 'datePicker'"
|
|
769
|
+
show-time
|
|
770
|
+
:disabled="renderItem.disabled"
|
|
771
|
+
:placeholder="`请选择${renderItem.label}`"
|
|
772
|
+
class="ant-input"
|
|
773
|
+
format="YYYY-MM-DD HH:mm:ss"
|
|
774
|
+
value-format="YYYY-MM-DD HH:mm:ss"
|
|
775
|
+
/>
|
|
776
|
+
|
|
777
|
+
<a-tree-select
|
|
778
|
+
style="min-width: 170px; margin-right: 15px"
|
|
779
|
+
v-model:value="formState[renderItem.key]"
|
|
780
|
+
:tree-data="renderItem.optionList"
|
|
781
|
+
v-if="renderItem.type == 'treeSelect'"
|
|
782
|
+
:disabled="renderItem.disabled"
|
|
718
783
|
:fieldNames="renderItem.fieldNames || { children: 'children', label: 'name', value: 'id' }"
|
|
719
|
-
:placeholder="renderItem.placeholder || `请选择`"
|
|
784
|
+
:placeholder="renderItem.placeholder || `请选择`"
|
|
785
|
+
></a-tree-select>
|
|
720
786
|
|
|
721
787
|
<a-upload
|
|
722
788
|
v-if="renderItem.type == 'uploadOss' || renderItem.type == 'uploadTos' || renderItem.type == 'upload'"
|
|
723
|
-
:file-list="formState[renderItem.key]"
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
789
|
+
:file-list="formState[renderItem.key]"
|
|
790
|
+
:multiple="true"
|
|
791
|
+
:max-count="renderItem?.maxCount || 1"
|
|
792
|
+
@preview="handlePicPreview"
|
|
793
|
+
:customRequest="
|
|
794
|
+
(e) => {
|
|
795
|
+
uploadRequest(e, renderItem);
|
|
796
|
+
}
|
|
797
|
+
"
|
|
798
|
+
@change="
|
|
799
|
+
(e) => {
|
|
800
|
+
uploadChange(e, renderItem);
|
|
801
|
+
}
|
|
802
|
+
"
|
|
803
|
+
:headers="{
|
|
804
|
+
'Cache-Control': 'max-age=15552000',
|
|
805
|
+
}"
|
|
806
|
+
:list-type="renderItem.uploadType == 'pic' ? 'picture-card' : undefined"
|
|
807
|
+
>
|
|
734
808
|
<div v-if="renderItem.uploadType == 'pic'">
|
|
735
809
|
<plus-outlined />
|
|
736
810
|
<div style="margin-top: 8px">{{ renderItem.label }}</div>
|
|
@@ -744,8 +818,11 @@ defineExpose({
|
|
|
744
818
|
</div>
|
|
745
819
|
</a-upload>
|
|
746
820
|
|
|
747
|
-
<component
|
|
748
|
-
v-
|
|
821
|
+
<component
|
|
822
|
+
v-if="renderItem.type == 'component'"
|
|
823
|
+
:is="renderItem.component"
|
|
824
|
+
v-model:[renderItem.key]="formState[renderItem.key]"
|
|
825
|
+
></component>
|
|
749
826
|
</div>
|
|
750
827
|
</a-form-item>
|
|
751
828
|
</div>
|
|
@@ -753,10 +830,10 @@ defineExpose({
|
|
|
753
830
|
<div v-if="uSlots.button || showResetButton || showSubmitButton" style="display: flex; justify-content: center">
|
|
754
831
|
<slot name="button"></slot>
|
|
755
832
|
<a-space size="small">
|
|
756
|
-
<a-button v-if="showResetButton" @click="resetForm"
|
|
833
|
+
<a-button v-if="showResetButton" @click="resetForm" style="padding: 0 30px">
|
|
757
834
|
{{ resetButtonText || "取消" }}
|
|
758
835
|
</a-button>
|
|
759
|
-
<a-button type="primary" @click="confirmClick"
|
|
836
|
+
<a-button type="primary" @click="confirmClick" v-if="showSubmitButton" style="padding: 0 30px">
|
|
760
837
|
{{ submitButtonText || "确认" }}
|
|
761
838
|
</a-button>
|
|
762
839
|
</a-space>
|
|
@@ -44,7 +44,7 @@ const confirmClick = async () => {
|
|
|
44
44
|
</script>
|
|
45
45
|
|
|
46
46
|
<template>
|
|
47
|
-
<a-modal v-model:
|
|
47
|
+
<a-modal v-model:open="show" :width="width" centered wrapClassName="p-modal">
|
|
48
48
|
<template #title v-if="title">
|
|
49
49
|
<div class="modal-title">
|
|
50
50
|
{{ title }}
|
|
@@ -60,7 +60,6 @@ const confirmClick = async () => {
|
|
|
60
60
|
<a-button
|
|
61
61
|
class="modal-btn modal-cancel-btn"
|
|
62
62
|
@click="show = false"
|
|
63
|
-
@keydown.enter.prevent="show = false"
|
|
64
63
|
>
|
|
65
64
|
取消
|
|
66
65
|
</a-button>
|
|
@@ -72,7 +71,6 @@ const confirmClick = async () => {
|
|
|
72
71
|
backgroundColor: confrimBtnBgColor,
|
|
73
72
|
}"
|
|
74
73
|
@click="confirmClick"
|
|
75
|
-
@keydown.enter.prevent="confirmClick"
|
|
76
74
|
:loading="loading"
|
|
77
75
|
>
|
|
78
76
|
确定
|
|
@@ -65,8 +65,12 @@ onMounted(() => {
|
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
const ok = async () => {
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
try {
|
|
69
|
+
let formData = await PFormRef.value.getFormData();
|
|
70
|
+
emits('confirm', formData)
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.warn('Form validation failed:', error);
|
|
73
|
+
}
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
|
|
@@ -474,8 +474,8 @@ defineExpose({
|
|
|
474
474
|
layout="inline"
|
|
475
475
|
>
|
|
476
476
|
<template v-slot:button>
|
|
477
|
-
<a-button type="primary" @click="searchClick"
|
|
478
|
-
<a-button style="margin-left: 10px" @click="resetSearch"
|
|
477
|
+
<a-button type="primary" @click="searchClick" style="margin-left: 20px"> 搜索 </a-button>
|
|
478
|
+
<a-button style="margin-left: 10px" @click="resetSearch"> 重置 </a-button>
|
|
479
479
|
</template>
|
|
480
480
|
</PForm>
|
|
481
481
|
</div>
|
|
@@ -485,7 +485,7 @@ defineExpose({
|
|
|
485
485
|
style="display: flex; justify-content: flex-end; gap: 10px; margin-bottom: 10px; padding: 20px"
|
|
486
486
|
>
|
|
487
487
|
<slot name="button"></slot>
|
|
488
|
-
<a-button v-if="enableExport" type="primary" @click="openExportModal"
|
|
488
|
+
<a-button v-if="enableExport" type="primary" @click="openExportModal">导出Excel</a-button>
|
|
489
489
|
</div>
|
|
490
490
|
|
|
491
491
|
<a-table
|
|
@@ -532,16 +532,13 @@ defineExpose({
|
|
|
532
532
|
v-if="!item.visibleFunc || (item.visibleFunc && item.visibleFunc(record))"
|
|
533
533
|
class="operate-a"
|
|
534
534
|
@click="item.click(record)"
|
|
535
|
-
@keydown.enter.prevent="item.click(record)"
|
|
536
|
-
tabindex="0"
|
|
537
|
-
role="button"
|
|
538
535
|
>
|
|
539
536
|
{{ item.label }}</a
|
|
540
537
|
>
|
|
541
538
|
</span>
|
|
542
|
-
<a class="operate-a" v-if="editableData[record.index]" @click="save(record.index)"
|
|
543
|
-
<a class="operate-a" v-if="editableData[record.index]" @click="cancel(record.index)"
|
|
544
|
-
<a v-if="editColumns.length > 0" class="operate-a" @click="edit(record.index)"
|
|
539
|
+
<a class="operate-a" v-if="editableData[record.index]" @click="save(record.index)">保存</a>
|
|
540
|
+
<a class="operate-a" v-if="editableData[record.index]" @click="cancel(record.index)">退出</a>
|
|
541
|
+
<a v-if="editColumns.length > 0" class="operate-a" @click="edit(record.index)">编辑</a>
|
|
545
542
|
</div>
|
|
546
543
|
</template>
|
|
547
544
|
|