riku
2025-04-27 f46786f11c5c08ead7501a82e5a71430ad69b782
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { cascaderNote } from './form-util.js';
 
Component({
  options: {
    multipleSlots: true, // 在组件定义时的选项中启用多slot支持
  },
  properties: {
    /**
     * 表单输入框采用T-design框架下的Input组件
     * 表单属性数组,数组每项属性如下
     * required: 是否必填,
     * label: 条目标签名,
     * placeholder: 默认提示,
     * name: 对应字段名,
     * value: 真实值,
     * status: 输入框状态。可选项:success/warning/error,
     * tips: 输入框下方提示文本,会根据不同的 status 呈现不同的样式,
     * inputType: 输入类型 (text: 输入框; switch: 切换按钮; picker: 下拉框选项; cascader: 级联选择),
     * options: 当输入类型为picker或cascader时,提供可选项,
     * cascaderTitles: 当输入类型为cascader时,提供每个选项的标题,
     */
    formArr: {
      type: Array,
      value: [],
      observer(v) {
        this.setData({ formArray: v });
      },
    },
    // 确认文本
    submitText: {
      type: String,
      value: '保存',
    },
    // 取消文本
    cancelText: {
      type: String,
      value: '取消',
    },
    // 是否执行校验
    validated: {
      type: Boolean,
      value: false,
    },
    // 是否可编辑
    editable: {
      type: Boolean,
      value: true,
    },
  },
 
  data: {
    formArray: [],
  },
 
  methods: {
    // 输入框
    onInputChange(e) {
      const { index } = e.currentTarget.dataset;
      const { value } = e.detail;
      this.setData({
        [`formArray[${index}].value`]: value,
      });
    },
    // 开关
    onSwitchChange(e) {
      const { index } = e.currentTarget.dataset;
      const { value } = e.detail;
      this.setData({
        [`formArray[${index}].value`]: value,
      });
    },
    // 下拉框
    showPicker(e) {
      const { index } = e.currentTarget.dataset;
      this.setData({ [`formArray[${index}].visible`]: true });
    },
    onPickerChange(e) {
      const { index } = e.currentTarget.dataset;
      const { label, value } = e.detail;
      this.setData({
        [`formArray[${index}].visible`]: false,
        [`formArray[${index}]._value`]: value,
        [`formArray[${index}]._label`]: label[0],
        [`formArray[${index}].value`]: value[0],
      });
    },
    onPickerCancel(e) {
      const { index } = e.currentTarget.dataset;
      this.setData({
        [`formArray[${index}].visible`]: false,
      });
    },
    // 级联选择
    showCascader(e) {
      const { index } = e.currentTarget.dataset;
      this.setData({ [`formArray[${index}].visible`]: true });
    },
    onCascaderChange(e) {
      const { index } = e.currentTarget.dataset;
      const { selectedOptions, value } = e.detail;
      const note = cascaderNote(selectedOptions);
      const v = selectedOptions.map(v => {
        return v.value;
      });
      this.setData({
        [`formArray[${index}].visible`]: false,
        [`formArray[${index}]._value`]: value,
        [`formArray[${index}].note`]: note,
        [`formArray[${index}].value`]: v,
      });
    },
 
    // 保存
    onSubmit() {
      const formObj = {};
      let fail = false;
      this.data.formArray.forEach(e => {
        if (e.required && !e.value) {
          fail = true;
          this.setData({ validated: true });
          return;
        }
        if (e.inputType == 'picker') {
          formObj[e.name] = e.value;
        } else if (e.inputType == 'cascader') {
          e.referItems.forEach((r, i) => {
            formObj[r] = e.value[i];
          });
        } else {
          formObj[e.name] = e.value;
        }
      });
      if (!fail) {
        this.triggerEvent('submit', formObj);
      }
    },
    // 取消
    onCancel() {
      this.triggerEvent('cancel');
    },
 
    _note(v) {
      let note = '';
      v.forEach(o => {
        if (note != o.label) {
          if (note != '') {
            note += '/';
          }
          note += o.label;
        }
      });
      return note;
    },
  },
});