From 3959e507bfa99cc4ced2a6f48f9b4358334d34c4 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期二, 19 十二月 2023 17:34:45 +0800
Subject: [PATCH] 1. 调试表单选项组件的双向绑定逻辑

---
 src/components/search-option/FYOptionOnlineStatus.vue |   28 +---
 src/components/search-option/base/FYOptionText.vue    |   36 ++---
 src/components/search-option/FYOptionUserType.vue     |   28 +---
 src/components/search-option/FYOptionTime.vue         |   39 ++----
 src/components.d.ts                                   |    3 
 src/views/fytz/user/components/CompUserInfo.vue       |   25 ---
 src/composables/formConfirm.js                        |   16 +-
 src/components/form/FYForm.vue                        |   42 +++++-
 src/components/search-option/FYOptionLocation.vue     |  108 +++++++-----------
 src/components/search-option/FYOptionScene.vue        |   28 +---
 10 files changed, 138 insertions(+), 215 deletions(-)

diff --git a/src/components.d.ts b/src/components.d.ts
index 0f89be9..c7d77e1 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -10,6 +10,7 @@
     BaseContentLayout: typeof import('./components/core/BaseContentLayout.vue')['default']
     BasePanelLayout: typeof import('./components/core/BasePanelLayout.vue')['default']
     Content: typeof import('./components/core/Content.vue')['default']
+    copy: typeof import('./components/search-option/FYOptionLocation copy.vue')['default']
     ElAside: typeof import('element-plus/es')['ElAside']
     ElAvatar: typeof import('element-plus/es')['ElAvatar']
     ElBacktop: typeof import('element-plus/es')['ElBacktop']
@@ -55,9 +56,7 @@
     ElTabPane: typeof import('element-plus/es')['ElTabPane']
     ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTag: typeof import('element-plus/es')['ElTag']
-    ElText: typeof import('element-plus/es')['ElText']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
-    ElTransfer: typeof import('element-plus/es')['ElTransfer']
     ElTree: typeof import('element-plus/es')['ElTree']
     Footer: typeof import('./components/core/Footer.vue')['default']
     FormCol: typeof import('./components/layout/FormCol.vue')['default']
diff --git a/src/components/form/FYForm.vue b/src/components/form/FYForm.vue
index 42cf198..5bfa1b8 100644
--- a/src/components/form/FYForm.vue
+++ b/src/components/form/FYForm.vue
@@ -3,7 +3,7 @@
     :inline="false"
     :model="formObj"
     ref="formRef"
-    :rules="rules"
+    :rules="allRules"
     label-position="right"
     label-width="150px"
   >
@@ -26,7 +26,7 @@
  * 鍙紶鍏ュ垵濮嬭〃鍗曟暟鎹甪ormInfo锛岃〃鍗曟牎楠岃鍒檙ules
  * 瀹炵幇submit鍜宑ancel瑙﹀彂鍑芥暟
  */
-import { defineProps, defineEmits, reactive, ref, watch } from 'vue';
+import { defineProps, defineEmits, reactive, ref, watch, computed } from 'vue';
 import { useFormConfirm } from '@/composables/formConfirm';
 
 const props = defineProps({
@@ -43,7 +43,7 @@
   //閲嶇疆鎸夐挳鏄惁鍙敤
   useReset: Boolean,
   //瑙﹀彂閲嶇疆
-  reset: Boolean,
+  doClear: Boolean,
   //閫氱煡缂栬緫鐘舵��
   isEdit: Boolean
 });
@@ -51,8 +51,32 @@
 //瑙﹀彂鍑芥暟锛屾彁浜ゅ拰鍙栨秷
 const emit = defineEmits(['submit', 'cancel', 'update:isEdit']);
 
+const baseRules = reactive({
+  _usertype: [
+    {
+      required: true,
+      message: '鐢ㄦ埛绫诲瀷涓嶈兘涓虹┖',
+      trigger: 'change'
+    }
+  ],
+  _locations: [
+    {
+      required: true,
+      message: '鐪�/甯�/鍖�/闀囦笉鑳戒负绌�',
+      trigger: 'change',
+    }
+  ],
+  _scenetype: [
+    {
+      required: true,
+      message: '鍦烘櫙绫诲瀷涓嶈兘涓虹┖',
+      trigger: 'change'
+    }
+  ]
+});
+
 //琛ㄥ崟鎿嶄綔鍑芥暟
-const { formObj, formRef, edit, onSubmit, onCancel, onReset, formProps } = useFormConfirm({
+const { formObj, formRef, edit, onSubmit, onCancel, onReset, clear } = useFormConfirm({
   submit: {
     do: submit
   },
@@ -83,21 +107,25 @@
   emit('cancel');
 }
 
+const allRules = computed(()=>{
+  return {...baseRules.value, ...props.rules}
+})
+
 //鐩戝惉琛ㄥ崟鍒濆鏁版嵁浼犲叆
 watch(
   () => props.formInfo,
   (nValue) => {
     formObj.value = nValue;
   },
-  { deep: false, immediate: false }
+  { deep: false, immediate: true }
 );
 
 //鐩戝惉琛ㄥ崟閲嶇疆鍔熻兘瑙﹀彂
 watch(
-  () => props.reset,
+  () => props.doClear,
   (nValue) => {
     if (nValue) {
-      onReset();
+      clear();
     }
   }
 );
diff --git a/src/components/search-option/FYOptionLocation.vue b/src/components/search-option/FYOptionLocation.vue
index ea6c3d4..f4dc270 100644
--- a/src/components/search-option/FYOptionLocation.vue
+++ b/src/components/search-option/FYOptionLocation.vue
@@ -1,7 +1,8 @@
 <template>
   <el-form-item :label="placeholder" :prop="prop">
     <el-cascader
-      v-model="selectedOptions"
+      :model-value="formatedValue"
+      @change="handleChange"
       :options="locations"
       :placeholder="placeholder"
       :props="optionProps"
@@ -11,10 +12,7 @@
 </template>
 
 <script>
-import { enumLocation } from '@/enum/location'
-
-// 璁板綍閫夐」鏄惁鏄嚜瀹氫箟浼犲叆鐨�
-let customValue = true
+import { enumLocation } from '@/enum/location';
 
 export default {
   props: {
@@ -46,50 +44,28 @@
   data() {
     return {
       locations: enumLocation(this.allOption, this.level),
-      selectedOptions: [],
       optionProps: {
         checkStrictly: this.checkStrictly
       }
-    }
+    };
   },
   computed: {
     placeholder() {
-      const list = '鐪�/甯�/鍖�/闀�'.split('/')
-      const p = []
+      const list = '鐪�/甯�/鍖�/闀�'.split('/');
+      const p = [];
       for (let i = 0; i < this.level; i++) {
-        p.push(list[i])
+        p.push(list[i]);
       }
-      return p.join('/')
-    }
-  },
-  watch: {
-    selectedOptions: {
-      handler(nVal, oVal) {
-        if (nVal != oVal) {
-          const res = this.optionFormat(nVal)
-          // 鏍囨槑姝ゆ椂鐨剉alue鏇存柊鏄粍浠跺唴閮ㄨЕ鍙�
-          customValue = false
-          this.$emit('update:value', res)
-        }
-      },
-      deep: true
+      return p.join('/');
     },
-    value: {
-      handler(nVal, oVal) {
-        // 鍙湁褰撳�兼槸澶栭儴浼犲叆鏃讹紝鎵嶈Е鍙戞洿鏂�
-        if (!customValue) {
-          customValue = true
-          return
-        }
-        if (nVal != oVal) {
-          this.selectedOptions = this.optionFormatReverse(nVal)
-        }
-      },
-      deep: true,
-      immediate: true
+    formatedValue() {
+      return this.optionFormatReverse(this.value);
     }
   },
   methods: {
+    handleChange(value) {
+      this.$emit('update:value', this.optionFormat(value));
+    },
     /**
      * 鍦板尯閫夐」缁撴灉鏍煎紡鍖�
      */
@@ -103,61 +79,61 @@
         dName: null,
         tCode: null,
         tName: null
-      }
+      };
       if (val.length > 0) {
-        res.pCode = val[0][0]
-        res.pName = val[0][1]
+        res.pCode = val[0][0];
+        res.pName = val[0][1];
       }
       if (val.length > 1) {
-        res.cCode = val[1][0]
-        res.cName = val[1][1]
+        res.cCode = val[1][0];
+        res.cName = val[1][1];
       }
       if (val.length > 2) {
-        res.dCode = val[2][0]
-        res.dName = val[2][1]
+        res.dCode = val[2][0];
+        res.dName = val[2][1];
       }
       if (val.length > 3) {
-        res.tCode = val[3][0]
-        res.tName = val[3][1]
+        res.tCode = val[3][0];
+        res.tName = val[3][1];
       }
-      return res
+      return res;
     },
     optionFormatReverse(val) {
-      const res = []
+      const res = [];
       if (val) {
-        if (val.pCode) {
-          res.push([val.pCode, val.pName])
+        if (val.pName) {
+          res.push([val.pCode, val.pName]);
         }
-        if (val.cCode) {
-          res.push([val.cCode, val.cName])
+        if (val.cName) {
+          res.push([val.cCode, val.cName]);
         }
-        if (val.dCode) {
-          res.push([val.dCode, val.dName])
+        if (val.dName) {
+          res.push([val.dCode, val.dName]);
         }
-        if (val.tCode) {
-          res.push([val.tCode, val.tName])
-        } 
+        if (val.tName) {
+          res.push([val.tCode, val.tName]);
+        }
       }
-      return res
+      return res;
     }
   },
   mounted() {
     if (this.initValue) {
       if (this.checkStrictly) {
-        this.selectedOptions = [this.locations[0].value]
+        this.handleChange([this.locations[0].value]);
       } else {
         const f = (location) => {
           if (location.children && location.children.length > 0) {
-            const r = f(location.children[0])
-            r.unshift(location.value)
-            return r
+            const r = f(location.children[0]);
+            r.unshift(location.value);
+            return r;
           } else {
-            return [location.value]
+            return [location.value];
           }
-        }
-        this.selectedOptions = f(this.locations[0])
+        };
+        this.handleChange(f(this.locations[0]));
       }
     }
   }
-}
+};
 </script>
diff --git a/src/components/search-option/FYOptionOnlineStatus.vue b/src/components/search-option/FYOptionOnlineStatus.vue
index 3d245b1..a68b463 100644
--- a/src/components/search-option/FYOptionOnlineStatus.vue
+++ b/src/components/search-option/FYOptionOnlineStatus.vue
@@ -1,7 +1,8 @@
 <template>
   <el-form-item label="涓婄嚎鐘舵��">
     <el-select
-      v-model="selectedOptions"
+      :model-value="value"
+      @change="handleChange"
       placeholder="涓婄嚎鐘舵��"
       style="width: 75px"
     >
@@ -37,31 +38,16 @@
   data() {
     return {
       onlineStatus: enumOnlineStatus(),
-      selectedOptions: {},
     };
   },
-  watch: {
-    selectedOptions: {
-      handler(nVal, oVal) {
-        if (nVal != oVal) {
-          this.$emit('update:value', nVal);
-        }
-      },
-      deep: true,
-    },
-    value: {
-      handler(nVal, oVal) {
-        if (nVal != oVal) {
-          this.selectedOptions = nVal;
-        }
-      },
-      deep: true,
-      immediate: true
-    },
+  methods: {
+    handleChange(value) {
+      this.$emit('update:value', value);
+    }
   },
   mounted() {
     if (this.initValue) {
-      this.selectedOptions = this.onlineStatus[0];
+      this.handleChange(this.onlineStatus[0]);
     }
   },
 };
diff --git a/src/components/search-option/FYOptionScene.vue b/src/components/search-option/FYOptionScene.vue
index b02aff2..441b57d 100644
--- a/src/components/search-option/FYOptionScene.vue
+++ b/src/components/search-option/FYOptionScene.vue
@@ -1,7 +1,8 @@
 <template>
   <el-form-item label="鍦烘櫙绫诲瀷" :prop="prop">
     <el-select
-      v-model="selectedOptions"
+      :model-value="value"
+      @change="handleChange"
       placeholder="鍦烘櫙绫诲瀷"
       style="width: 150px"
     >
@@ -43,31 +44,16 @@
   data() {
     return {
       sceneTypes: enumScene(this.type, this.allOption),
-      selectedOptions: {},
     };
   },
-  watch: {
-    selectedOptions: {
-      handler(nVal, oVal) {
-        if (nVal != oVal) {
-          this.$emit('update:value', nVal);
-        }
-      },
-      deep: true,
-    },
-    value: {
-      handler(nVal, oVal) {
-        if (nVal != oVal) {
-          this.selectedOptions = nVal;
-        }
-      },
-      deep: true,
-      immediate: true
-    },
+  methods: {
+    handleChange(value) {
+      this.$emit('update:value', value);
+    }
   },
   mounted() {
     if (this.initValue) {
-      this.selectedOptions = this.sceneTypes[0];
+      this.handleChange(this.sceneTypes[0]);
     }
   },
 };
diff --git a/src/components/search-option/FYOptionTime.vue b/src/components/search-option/FYOptionTime.vue
index 9a6ba6f..b55bb6b 100644
--- a/src/components/search-option/FYOptionTime.vue
+++ b/src/components/search-option/FYOptionTime.vue
@@ -1,7 +1,8 @@
 <template>
   <el-form-item label="鏃堕棿">
     <el-date-picker
-      v-model="selectedOptions"
+      :model-value="value"
+      @change="handleChange"
       type="month"
       placeholder="閫夋嫨鏃堕棿"
       style="width: 150px"
@@ -10,9 +11,9 @@
 </template>
 
 <script>
-import dayjs from 'dayjs'
+import dayjs from 'dayjs';
 
-const MONTH = 'month'
+const MONTH = 'month';
 
 export default {
   props: {
@@ -30,41 +31,25 @@
   },
   emits: ['update:value'],
   data() {
-    return {
-      selectedOptions: ''
-    }
-  },
-  watch: {
-    selectedOptions: {
-      handler(nVal, oVal) {
-        if (nVal != oVal) {
-          this.$emit('update:value', nVal)
-        }
-      }
-    },
-    value: {
-      handler(nVal, oVal) {
-        if (nVal != oVal) {
-          this.selectedOptions = nVal
-        }
-      },
-      immediate: true
-    }
+    return {};
   },
   methods: {
+    handleChange(value) {
+      this.$emit('update:value', value);
+    },
     timeFormat() {
       switch (this.type) {
         case MONTH:
-          return 'YYYY-MM'
+          return 'YYYY-MM';
         default:
-          return 'YYYY-MM'
+          return 'YYYY-MM';
       }
     }
   },
   mounted() {
     if (this.initValue) {
-      this.selectedOptions = new Date()
+      this.handleChange(new Date());
     }
   }
-}
+};
 </script>
diff --git a/src/components/search-option/FYOptionUserType.vue b/src/components/search-option/FYOptionUserType.vue
index f127187..e274241 100644
--- a/src/components/search-option/FYOptionUserType.vue
+++ b/src/components/search-option/FYOptionUserType.vue
@@ -1,7 +1,8 @@
 <template>
   <el-form-item label="鐢ㄦ埛绫诲瀷" :prop="prop">
     <el-select
-      v-model="selectedOptions"
+      :model-value="value"
+      @change="handleChange"
       placeholder="鐢ㄦ埛绫诲瀷"
       style="width: 150px"
     >
@@ -38,31 +39,16 @@
   data() {
     return {
       userTypes: enumUser(this.allOption),
-      selectedOptions: {},
     };
   },
-  watch: {
-    selectedOptions: {
-      handler(nVal, oVal) {
-        if (nVal != oVal) {
-          this.$emit('update:value', nVal);
-        }
-      },
-      deep: true,
-    },
-    value: {
-      handler(nVal, oVal) {
-        if (nVal != oVal) {
-          this.selectedOptions = nVal;
-        }
-      },
-      deep: true,
-      immediate: true
-    },
+  methods: {
+    handleChange(value) {
+      this.$emit('update:value', value);
+    }
   },
   mounted() {
     if (this.initValue) {
-      this.selectedOptions = this.userTypes[0];
+      this.handleChange(this.userTypes[0]);
     }
   },
 };
diff --git a/src/components/search-option/base/FYOptionText.vue b/src/components/search-option/base/FYOptionText.vue
index 47bc779..980feb5 100644
--- a/src/components/search-option/base/FYOptionText.vue
+++ b/src/components/search-option/base/FYOptionText.vue
@@ -1,6 +1,12 @@
 <template>
-  <el-form-item :label="label">
-    <el-input clearable v-model="searchText" :placeholder="placeholder" />
+  <el-form-item :label="label" :prop="prop">
+    <el-input
+      clearable
+      :model-value="value"
+      :placeholder="placeholder"
+      @input="handleInput"
+      style="width: 150px"
+    />
   </el-form-item>
 </template>
 
@@ -9,32 +15,24 @@
   props: {
     label: {
       type: String,
-      default: '鏌ヨ椤�',
+      default: '鏌ヨ椤�'
     },
     placeholder: {
       type: String,
-      default: '杈撳叆鎼滅储鍐呭',
+      default: '杈撳叆鎼滅储鍐呭'
     },
     // 杩斿洖缁撴灉
     value: String,
+    prop: String
   },
   emits: ['update:value'],
   data() {
-    return {
-      searchText: '',
-    };
+    return {};
   },
-  watch: {
-    searchText(nVal, oVal) {
-      if (nVal != oVal) {
-        this.$emit('update:value', nVal);
-      }
-    },
-    value(nVal, oVal) {
-      if (nVal != oVal) {
-        this.searchText = nVal;
-      }
-    },
-  },
+  methods: {
+    handleInput(value) {
+      this.$emit('update:value', value);
+    }
+  }
 };
 </script>
diff --git a/src/composables/formConfirm.js b/src/composables/formConfirm.js
index d568fe0..dc295d5 100644
--- a/src/composables/formConfirm.js
+++ b/src/composables/formConfirm.js
@@ -20,10 +20,10 @@
   if (!cancel.title) cancel.title = '鍙栨秷';
   if (!cancel.msg) cancel.msg = '鏄惁鏀惧純宸茬紪杈戠殑鍐呭锛�';
 
-  const formProps = defineProps({
-    // 鏄惁鍦ㄦ彁浜ゆ垚鍔熷悗娓呯┖琛ㄥ崟
-    clearAftSubmit: Boolean
-  });
+  // const formProps = defineProps({
+  //   // 鏄惁鍦ㄦ彁浜ゆ垚鍔熷悗娓呯┖琛ㄥ崟
+  //   clearAftSubmit: Boolean
+  // });
 
   //琛ㄥ崟鍐呭
   const formObj = ref(defaultForm ? defaultForm : {});
@@ -69,24 +69,24 @@
 
   // 閲嶇疆琛ㄥ崟
   const _reset = function () {
+    formRef.value.clearValidate();
     edit.value = false;
     isReset = true;
     formObj.value = useCloned(formObjClone.cloned, {
       manual: true
     }).cloned.value;
-    formRef.value.clearValidate();
   };
 
   // 娓呯┖琛ㄥ崟
   const clear = function () {
     isReset = true;
-    // formRef.value.resetFields();
+    formRef.value.resetFields();
     edit.value = false;
   };
 
   // 鎻愪氦鎴愬姛鍚�
   const submited = function () {
-    if (formProps.clearAftSubmit) clear();
+    // if (formProps.clearAftSubmit) clear();
     edit.value = false;
     formObjClone = useCloned(formObj, { manual: true });
   };
@@ -147,5 +147,5 @@
     }
   };
 
-  return { formProps, formObj, formRef, edit, onSubmit, onCancel, onReset };
+  return { formObj, formRef, edit, onSubmit, onCancel, onReset, clear };
 }
diff --git a/src/views/fytz/user/components/CompUserInfo.vue b/src/views/fytz/user/components/CompUserInfo.vue
index 1194b4a..9ee0edf 100644
--- a/src/views/fytz/user/components/CompUserInfo.vue
+++ b/src/views/fytz/user/components/CompUserInfo.vue
@@ -2,7 +2,7 @@
   <FYForm
     :form-info="_formInfo"
     :rules="rules"
-    :reset="active"
+    :doClear="active"
     :useCancel="create"
     :useReset="!create"
     :clearAftSubmit="create"
@@ -130,27 +130,6 @@
   //     trigger: 'blur',
   //   },
   // ],
-  _usertype: [
-    {
-      required: true,
-      message: '鐢ㄦ埛绫诲瀷涓嶈兘涓虹┖',
-      trigger: 'change'
-    }
-  ],
-  _locations: [
-    {
-      required: props.create,
-      message: '鐪�/甯�/鍖�/闀囦笉鑳戒负绌�',
-      trigger: 'change'
-    }
-  ],
-  _scenetype: [
-    {
-      required: true,
-      message: '鍦烘櫙绫诲瀷涓嶈兘涓虹┖',
-      trigger: 'change'
-    }
-  ]
 });
 
 // 鐢ㄦ埛鍩烘湰淇℃伅鏍煎紡鍖�
@@ -162,7 +141,7 @@
 
   s._scenetype = getSceneName(s.extension2, 1);
 
-  s._locations = [];
+  s._locations = {};
 
   return s;
 }

--
Gitblit v1.9.3