Przeglądaj źródła

[Fix 0000] 修复了矿码级联组件在重置后无法正确传递信息的问题

houzekong 3 miesięcy temu
rodzic
commit
09f8c90128

+ 117 - 100
src/components/Form/src/jeecg/components/MineCascader/MineCascader.vue

@@ -1,9 +1,18 @@
 <template>
-  <Cascader :value="innerValue" :options="options" placeholder="全部" :field-names="{
-    label: 'departName',
-    value: 'id',
-    children: 'childDepart',
-  }" :show-search="showSearch" :allow-clear="allowClear" :change-on-select="changeOnSelect" @change="handleChange">
+  <Cascader
+    :value="innerValue"
+    :options="options"
+    placeholder="全部"
+    :field-names="{
+      label: 'departName',
+      value: 'id',
+      children: 'childDepart',
+    }"
+    :show-search="showSearch"
+    :allow-clear="allowClear"
+    :change-on-select="changeOnSelect"
+    @change="handleChange"
+  >
     <template #displayRender="{ labels }">
       {{ labels[labels.length - 1] }}
     </template>
@@ -12,111 +21,119 @@
 </template>
 
 <script lang="ts">
-import { last } from 'lodash';
-import { defineComponent, ref, watch } from 'vue';
-// import { useMessage } from '/@/hooks/web/useMessage';
-import { propTypes } from '/@/utils/propTypes';
-import { useMineDepartmentStore } from '/@/store/modules/mine';
-import { Cascader } from 'ant-design-vue';
+  import { last } from 'lodash';
+  import { defineComponent, ref, watch } from 'vue';
+  // import { useMessage } from '/@/hooks/web/useMessage';
+  import { propTypes } from '/@/utils/propTypes';
+  import { useMineDepartmentStore } from '/@/store/modules/mine';
+  import { Cascader } from 'ant-design-vue';
 
-/**
- * 矿区级联选择器,该组件会根据配置从store中获取初始数据
- *
- * 组件数据流梳理:初始化数据及选项 -> 更新数据 -> 同步STORE -> 计算组件内依赖
- *
- * 本组件在初始化后不再监听STORE中的数据变化,因为这样可能导致用户通过Tabs切换时出现数据混乱
- */
-export default defineComponent({
-  name: 'MineCascader',
-  components: { Cascader },
-  props: {
-    value: propTypes.string.def(''),
-    placeholder: propTypes.string.def('全部'),
-    /** 根节点ID,如果传入,组件将过滤该节点下的节点 */
-    rootId: propTypes.string,
-    /** 是否从已存储的信息中初始化组件值 */
-    initFromStore: propTypes.bool.def(true),
-    /** 是否从将值同步至STORE */
-    syncToStore: propTypes.bool.def(true),
-    showSearch: propTypes.bool.def(true),
-    allowClear: propTypes.bool.def(true),
-    changeOnSelect: propTypes.bool.def(true),
-    // clearOnDestroy: propTypes.bool.def(false),
-  },
-  emits: ['change', 'update:value'],
-  setup(props, { emit }) {
-    // const { createMessage } = useMessage();
-    const mineStore = useMineDepartmentStore();
-    const innerValue = ref<string[]>([]);
-    const options = ref(mineStore.getDepartTree);
+  /**
+   * 矿区级联选择器,该组件会根据配置从store中获取初始数据
+   *
+   * 组件数据流梳理:初始化数据及选项 -> 更新数据 -> 同步STORE -> 计算组件内依赖
+   *
+   * 本组件在初始化后不再监听STORE中的数据变化,因为这样可能导致用户通过Tabs切换时出现数据混乱
+   */
+  export default defineComponent({
+    name: 'MineCascader',
+    components: { Cascader },
+    props: {
+      value: propTypes.string.def(''),
+      placeholder: propTypes.string.def('全部'),
+      /** 根节点ID,如果传入,组件将过滤该节点下的节点 */
+      rootId: propTypes.string,
+      /** 是否从已存储的信息中初始化组件值 */
+      initFromStore: propTypes.bool.def(true),
+      /** 是否从将值同步至STORE */
+      syncToStore: propTypes.bool.def(true),
+      showSearch: propTypes.bool.def(true),
+      allowClear: propTypes.bool.def(true),
+      changeOnSelect: propTypes.bool.def(true),
+      // clearOnDestroy: propTypes.bool.def(false),
+    },
+    emits: ['change', 'update:value'],
+    setup(props, { emit }) {
+      // const { createMessage } = useMessage();
+      const mineStore = useMineDepartmentStore();
+      const innerValue = ref<string[]>([]);
+      const options = ref(mineStore.getDepartTree);
 
-    // if (props.clearOnDestroy) {
-    //   const raw = getDepartId.value;
-    //   onUnmounted(() => {
-    //     mineStore.setDepartById(raw);
-    //   });
-    // }
+      // if (props.clearOnDestroy) {
+      //   const raw = getDepartId.value;
+      //   onUnmounted(() => {
+      //     mineStore.setDepartById(raw);
+      //   });
+      // }
 
-    if (props.rootId) {
-      options.value = mineStore.filterDepartTree((e) => e.parentId === props.rootId);
-    }
-
-    // 如果从STORE里初始化数据需要触发一次watcher以初始化组件状态
-    if (props.initFromStore) {
-      handleWatch(mineStore.getDepartId);
-      // 为了让使用该组件的各个页面能够第一时间使用到该组件传递的值,手动触发一次emit
-      handleChange([mineStore.getDepartId]);
-    } else {
-      handleWatch(props.value);
-      // 为了让使用该组件的各个页面能够第一时间使用到该组件传递的值,手动触发一次emit
-      handleChange([props.value]);
-    }
-
-    /**
-     * change事件
-     * @param e
-     */
-    function handleChange(value: any[] = []) {
-      console.log(value, 'value===')
-      if (!value.length) {
-        emit('update:value', null);
-        emit('change', null);
-      } else if (!mineStore.findDepartById(last(value), options.value)) {
-        console.warn('[Change] The value provided is not included in MineOptions');
-        const val = mineStore.calcMineCodeByDepart(options.value);
-        emit('update:value', val);
-        emit('change', val);
-      } else {
-        emit('update:value', last(value));
-        emit('change', last(value));
+      if (props.rootId) {
+        options.value = mineStore.filterDepartTree((e) => e.parentId === props.rootId);
       }
-    }
 
-    function handleWatch(id: string = '') {
-      // rootId提供了选项过滤功能,任何传入的值都应该检查
-      if (!mineStore.findDepartById(id, options.value)) {
-        console.warn('[Watch] The id provided is not included in MineOptions');
-        innerValue.value = [];
+      // 如果从STORE里初始化数据需要触发一次watcher以初始化组件状态
+      if (props.initFromStore) {
+        // handleWatch(mineStore.getDepartId);
+        // 为了让使用该组件的各个页面能够第一时间使用到该组件传递的值,手动触发一次emit
+        handleChange([mineStore.getDepartId]);
       } else {
-        const path = mineStore.calcDepartPathById(id, options.value, (e) => e.id);
-        innerValue.value = path;
+        // handleWatch(props.value);
+        // 为了让使用该组件的各个页面能够第一时间使用到该组件传递的值,手动触发一次emit
+        handleChange([props.value]);
       }
 
-      if (props.syncToStore) {
-        mineStore.setDepartById(id);
+      /**
+       * change事件
+       * @param e
+       */
+      function handleChange(value: any[] = []) {
+        if (!mineStore.findDepartById(last(value), options.value)) {
+          console.warn('[Change] The value provided is not included in MineOptions');
+          const val = mineStore.calcMineCodeByDepart(options.value);
+          emit('update:value', val);
+          emit('change', val);
+        } else {
+          emit('update:value', last(value));
+          emit('change', last(value));
+        }
       }
 
-      const path = mineStore.calcDepartPathById(id, options.value, (e) => e.id);
-      innerValue.value = path;
-    }
+      function handleWatch(id: string = '') {
+        // rootId提供了选项过滤功能,任何传入的值都应该检查
+        if (!mineStore.findDepartById(id, options.value)) {
+          console.warn('[Watch] The id provided is not included in MineOptions');
+          innerValue.value = [];
+        } else {
+          const path = mineStore.calcDepartPathById(id, options.value, (e) => e.id);
+          innerValue.value = path;
+        }
+
+        if (props.syncToStore) {
+          mineStore.setDepartById(id);
+        }
+
+        const path = mineStore.calcDepartPathById(id, options.value, (e) => e.id);
+        innerValue.value = path;
+      }
 
-    watch(() => props.value, handleWatch);
+      watch(
+        () => props.value,
+        (nv) => {
+          // 触发事件的顺序应该是 change -> watch
+          if (nv === '') {
+            // 因此当监听到的数据为空时,99%的情况是外部操作导致,因此触发一次 change -> watch
+            handleChange([nv]);
+          } else {
+            // 反之则为内部正常数据触发 change 后来到这里走 watch 的逻辑
+            handleWatch(nv);
+          }
+        }
+      );
 
-    return {
-      innerValue,
-      options,
-      handleChange,
-    };
-  },
-});
+      return {
+        innerValue,
+        options,
+        handleChange,
+      };
+    },
+  });
 </script>