vue element 动态校验数据的必填项和非必填项

  1 <template>
  2   <!-- 人员资料--我的群组--添加群组 -->
  3   <section class="add-group">
  4     <div class="content">
  5       <el-form
  6         class="add-form"
  7         label-position="right"
  8         label-width="100px"
  9         :model="groupForm"
 10         :rules="formRules"
 11         ref="groupForm"
 12       >
 13         <el-form-item prop="groupName" label="群组名称:">
 14           <el-input
 15             v-model.trim="groupForm.groupName"
 16             placeholder="请输入群组名称"
 17           ></el-input>
 18         </el-form-item>
 19         <el-form-item prop="name">
 20           <span slot="label">
 21             <span>群组成员:</span>
 22             <el-button size="small" type="primary" @click.native="addMembers">
 23               添加
 24             </el-button>
 25           </span>
 26           <el-input
 27             type="textarea"
 28             :rows="4"
 29             v-model.trim="groupForm.members"
 30             placeholder="请添加群组成员"
 31           ></el-input>
 32         </el-form-item>
 33         <el-form-item class="operate">
 34           <el-button size="small" type="default" @click.native="cancel">
 35             取消
 36           </el-button>
 37           <el-button size="small" type="primary" @click.native="submit">
 38             保存
 39           </el-button>
 40         </el-form-item>
 41       </el-form>
 42     </div>
 43     <!-- 添加群组成员 -->
 44     <el-dialog
 45       title="添加成员"
 46       :modal-append-to-body="true"
 47       :append-to-body="true"
 48       :visible.sync="addFormVisible"
 49     >
 50       <el-form
 51         :model="membersForm"
 52         :rules="membersRule"
 53         ref="membersForm"
 54         label-width="100px"
 55         class="add-form"
 56       >
 57         <el-form-item label="成员类型:" prop="type">
 58           <el-radio-group v-model="membersForm.type">
 59             <el-radio
 60               v-for="item in memberType"
 61               :key="item.value"
 62               :label="item.value"
 63             >
 64               {{ item.label }}
 65             </el-radio>
 66           </el-radio-group>
 67         </el-form-item>
 68         <!-- 选择用户时如果选择的是门户人员则成员名称是必填项,否则为非必填项 -->
 69         <!-- 动态校验数据的必填项和非必填项 -->
 70         <el-form-item
 71           label="成员名称:"
 72           prop="name"
 73           :message="'请选择成员名称'"
 74           :required="membersForm.type === STAFF_TYPE.PORTAL_USER? true:false">
 75           <el-input
 76             v-if="membersForm.type === STAFF_TYPE.PORTAL_USER"
 77             type="textarea"
 78             autosize
 79             @focus="showSelectStaff"
 80             placeholder="请选择(可多选)"
 81             key="select-name"
 82           >
 83           </el-input>
 84           <el-input
 85             v-else
 86             v-model="membersForm.name"
 87             type="textarea"
 88             autosize
 89             auto-complete="off"
 90             key="input-name"
 91             placeholder="请输入成员姓名,多个以&quot; , &quot;隔开"
 92           ></el-input>
 93         </el-form-item>
 94         <!-- 输入成员昵称 -->
 95         <el-form-item label="成员昵称" prop="nicknames">
 96           <el-input
 97             v-model="membersForm.nicknames"
 98             type="textarea"
 99             autosize
100             auto-complete="off"
101             placeholder="请输入成员昵称,多个以&quot; , &quot;隔开"
102           ></el-input>
103         </el-form-item>
104          <!-- 输入成员手机号 -->
105         <el-form-item label="成员手机号" prop="phone" v-if="membersForm.type === STAFF_TYPE.DIRECT_INPUT">
106           <el-input
107             v-model="membersForm.phone"
108             maxlength="11"
109             auto-complete="off"
110             placeholder="请输入成员手机号,多个以&quot; , &quot;隔开"
111           ></el-input>
112         </el-form-item>
113       </el-form>
114       <div slot="footer" class="dialog-footer">
115         <el-button size="small" @click="addFormVisible = false"
116           >取 消</el-button
117         >
118         <el-button
119           size="small"
120           type="primary"
121           @click="addSubmit"
122           :loading="load.addLoading"
123           >确 定</el-button
124         >
125       </div>
126     </el-dialog>
127     <!-- 选择群组成员弹窗 -->
128     <select-staff :showDialog="selectDialogVisible" @closeModal="closeModal"></select-staff>
129   </section>
130 </template>
131 <script>
132 import DATA_TYPE from 'utils/enum';
133 import utilCheck from 'utils/check';
134 import selectStaff from 'components/selectStaff';
135 
136 export default {
137   components: {
138     'select-staff': selectStaff
139   },
140   data() {
141     return {
142       load: {
143         addLoading: false,
144         treeLoading: false
145       },
146       // 群组信息
147       groupForm: {
148         groupName: '',
149         members: ''
150       },
151       addFormVisible: false,
152       // 成员信息
153       membersForm: {
154         type: DATA_TYPE.STAFF_TYPE.PORTAL_USER, // 默认为门户用户
155         name: '',
156         members: [],
157         nicknames: '',
158         phone: ''
159       },
160       // 用户类型
161       STAFF_TYPE: DATA_TYPE.STAFF_TYPE,
162       memberType: [
163         { label: '门户用户', value: DATA_TYPE.STAFF_TYPE.PORTAL_USER },
164         { label: '直接输入', value: DATA_TYPE.STAFF_TYPE.DIRECT_INPUT }
165       ],
166       selectDialogVisible: false,
167       searchMember: '',
168       selectedMembers: [],
169       // 群组信息校验
170       formRules: {
171         name: [
172           {
173             required: true,
174             message: '请输入群组名称',
175             trigger: 'blur'
176           }
177         ],
178         members: [
179           {
180             required: true,
181             message: '请添加群组成员',
182             trigger: 'blur'
183           }
184         ]
185       },
186       /**
187        * 成员信息校验分为两种
188        * 1.门户选择
189        *    选择成员名称,成员昵称非必填,但是若填写,则数量上须保持一致
190        * 2.直接输入
191        *    成员手机号必填,成员名称和昵称非必填
192        *    但是如果填写了,则必须和手机号数量保持一致
193        *
194       */
195       membersRule: {
196         name: [
197           {
198             trigger: 'blur',
199             validator: (rule, value, callback) => {
200               let err;
201               // 门户成员时必须选择成员名称
202               if (this.membersForm.type === this.STAFF_TYPE.PORTAL_USER && !value) {
203                 err = new Error('请选择成员名称');
204               }
205               callback(err);
206             }
207           }
208         ],
209         phone: [
210           {
211             required: true,
212             message: '请输入成员手机号',
213             trigger: 'blur'
214           },
215           // 校验多个手机号的格式是否都正确
216           utilCheck.checkMultipleMobile
217         ]
218       },
219       searchStaff: ''
220     };
221   },
222   watch: {
223     /**
224      * 需要在监听这个属性 另外一定要加$nextTick()
225      * 不加的话切换必选属性的时候会触发框架自带的验证会出现 XX is required
226     */
227     'membersForm.type': function (val) {
228       this.$nextTick(() => {
229         if (val !== 1) {
230             this.$refs.membersForm.validateField('name');
231             this.membersForm.name = '';
232         }
233     });
234   }
235   },
236   methods: {
237     showSelectStaff() {
238       this.selectDialogVisible = true;
239     },
240     // 选择群组成员
241     addMembers() {
242       this.addFormVisible = true;
243     },
244     // 关闭选择群组成员弹窗
245     closeModal() {
246       this.selectDialogVisible = false;
247     },
248     // 提交添加群组成员
249     addSubmit() {},
250     submit() {
251       this.$refs.groupForm.validate((valid) => {
252         if (valid) {
253           // TODO test
254         }
255       });
256     },
257     cancel() {
258       this.$router.back();
259     }
260   },
261   mounted() {}
262 };
263 </script>
264 <style  scoped>
265 @import "~assets/css/vars.scss";
266 .add-group {
267   overflow: hidden;
268   .content {
269     width: 50%;
270     margin: 60px auto 0;
271   }
272   .operate {
273     text-align: center;
274     margin-top: 40px;
275   }
276 }
277 .search-content {
278   display: flex;
279   .el-button {
280     margin-left: 30px;
281   }
282 }
283 .dialog-content {
284   padding-bottom: 20px;
285 }
286 </style>