浏览代码

fix: Address 组件体积优化 (#1885)

* fix: 修复 ImagePreview 在Taro编译成H5后报错的问题

* fix: 地址关闭时, Close 事件触发两次问题解决

* feat: 组件DatePicker 添加双向绑定

* docs: 组件Picker文档修改

* feat: 组件Picker与DatePicker新增属性safe-area-inset-bottom

* feat: imagepreview

* fix: 组件imagepreview点击视频遮罩关闭(#1729)

* fix: 解决 Picker 在微信小程序中无法使用问题 (#1774)

* fix: 修改 Picker 组件 v-model 失效问题

* fix: 组件NoticeBar修改height之后,垂直轮播会卡顿

* fix: 删除Datepicker Demo演示多余内容

* fix: 组件Picker在JD小程序上适配

* fix: 组件Address京东小程序适配

* feat: 京东小程序适配

* fix: 删除空格

* feat: 删除console

* fix: 京东小程序imagepreview适配

* fix: 修复 imagepreview 动态设置 initNo 显示不正确问题

* fix: 组件 InfiniteLoading 某些情况下会错误触发下拉刷新#1819

* fix: 删除pullrefresh

* feat: 组件 imagepreview瘦身

* feat: 组件Picker 瘦身

* fix: address线上问题修改

* fix: 完善imagepreview

* feat: 公共函数提取

* feat: 函数式改用 createComponent

* fix: 文件回撤

* fix: 组件 popup 组件修改 watcheffect 为 watch

* fix: 地址问题修改

* feat: address组件删除冗余逻辑

* feat: 地址组件Taro适配
yangxiaolu1993 3 年之前
父节点
当前提交
d8cac09c72
共有 3 个文件被更改,包括 255 次插入415 次删除
  1. 5 0
      src/packages/__VUE/address/index.scss
  2. 107 195
      src/packages/__VUE/address/index.taro.vue
  3. 143 220
      src/packages/__VUE/address/index.vue

+ 5 - 0
src/packages/__VUE/address/index.scss

@@ -235,4 +235,9 @@
       color: $white;
     }
   }
+
+  &-select-icon {
+    margin-right: $address-item-margin-right;
+    color: $address-icon-color !important;
+  }
 }

+ 107 - 195
src/packages/__VUE/address/index.taro.vue

@@ -32,26 +32,29 @@
       </view>
 
       <!-- 请选择 -->
-      <view class="custom-address" v-if="privateType == 'custom'">
+      <view class="custom-address" v-if="['custom', 'custom2'].includes(privateType)">
         <view class="nut-address-region-tab" ref="tabRegion">
           <view
-            :class="{ 'tab-item': true, active: index == tabIndex, [tabName[index]]: true }"
-            v-for="(item, key, index) in selectedRegion"
+            :class="['tab-item', index == tabIndex ? 'active' : '']"
+            v-for="(item, index) in selectedRegion"
             :key="index"
-            @click="changeRegionTab(item, key, index)"
+            @click="changeRegionTab(item, index)"
           >
             <view>{{ getTabName(item, index) }} </view>
-
-            <view :class="{ 'region-tab-line-mini': true, active: index == tabIndex }" ref="regionLine"></view>
+            <view :class="{ 'region-tab-line-mini': true, active: index == tabIndex }"></view>
+          </view>
+          <view class="active tab-item" v-if="tabIndex == selectedRegion.length">
+            <view>{{ getTabName(null, selectedRegion.length) }} </view>
+            <view class="region-tab-line-mini active"></view>
           </view>
         </view>
 
-        <view class="region-con">
+        <view class="region-con" v-if="privateType == 'custom'">
           <ul class="region-group">
             <li
-              v-for="(item, index) in regionList[tabName[tabIndex]]"
+              v-for="(item, index) in regionList"
               :key="index"
-              :class="['region-item', selectedRegion[tabName[tabIndex]].id == item.id ? 'active' : '']"
+              :class="['region-item', selectedRegion[tabIndex]?.id == item.id ? 'active' : '']"
               @click="nextAreaList(item)"
             >
               <div>
@@ -61,32 +64,18 @@
                   v-bind="$attrs"
                   :name="selectedIcon"
                   size="13px"
-                  v-if="selectedRegion[tabName[tabIndex]].id == item.id"
+                  v-if="selectedRegion[tabIndex]?.id == item.id"
                 ></nut-icon
                 >{{ item.name }}
               </div>
             </li>
           </ul>
         </view>
-      </view>
 
-      <!-- 请选择 -->
-      <view class="custom-address" v-else-if="privateType == 'custom2'">
-        <view class="nut-address-region-tab" ref="tabRegion">
-          <view
-            :class="{ 'tab-item': true, active: index == tabIndex, [tabName[index]]: true }"
-            v-for="(item, key, index) in selectedRegion"
-            :key="index"
-            @click="changeRegionTab(item, key, index)"
-          >
-            <view>{{ getTabName(item, index) }}</view>
-            <view :class="{ 'region-tab-line-mini': true, active: index == tabIndex }"></view>
-          </view>
-        </view>
-        <view class="elevator-group">
+        <view class="elevator-group" v-else>
           <nut-elevator
             :height="height"
-            :index-list="regionList[tabName[tabIndex]]"
+            :index-list="transformData(regionList)"
             @click-item="handleElevatorItem"
           ></nut-elevator>
         </view>
@@ -135,7 +124,7 @@
   </nut-popup>
 </template>
 <script lang="ts">
-import { reactive, ref, toRefs, watch, computed, onMounted } from 'vue';
+import { reactive, ref, toRefs, watch, computed } from 'vue';
 import { popupProps } from '../popup/props';
 import { createComponent } from '@/packages/utils/create';
 
@@ -251,8 +240,6 @@ export default create({
       };
     });
 
-    const regionLine = ref<null | HTMLElement>(null);
-
     const tabItemRef = reactive({
       province: ref<null | HTMLElement>(null),
       city: ref<null | HTMLElement>(null),
@@ -267,6 +254,19 @@ export default create({
 
     const isCustom2 = computed(() => props.type === 'custom2');
 
+    const regionList = computed(() => {
+      switch (tabIndex.value) {
+        case 0:
+          return props.province;
+        case 1:
+          return props.city;
+        case 2:
+          return props.country;
+        default:
+          return props.town;
+      }
+    });
+
     const transformData = (data: RegionData[]) => {
       if (!Array.isArray(data)) throw new TypeError('params muse be array.');
 
@@ -293,29 +293,14 @@ export default create({
             list: [].concat(item)
           });
         } else {
-          newData[index] = {
-            title: item.title,
-            list: newData[index].list.concat(item)
-          };
+          newData[index].list.push(item);
         }
       });
 
       return newData;
     };
 
-    const regionList = reactive({
-      province: isCustom2.value ? transformData(props.province) : props.province,
-      city: isCustom2.value ? transformData(props.city) : props.city,
-      country: isCustom2.value ? transformData(props.country) : props.country,
-      town: isCustom2.value ? transformData(props.town) : props.town
-    });
-
-    const selectedRegion = reactive({
-      province: {} as RegionData,
-      city: {} as RegionData,
-      country: {} as RegionData,
-      town: {} as RegionData
-    }); //已选择的 省、市、县、镇
+    let selectedRegion = ref<RegionData[]>([]);
 
     let selectedExistAddress = reactive({}); // 当前选择的地址
 
@@ -323,64 +308,45 @@ export default create({
 
     const lineDistance = ref(20);
 
-    onMounted(() => {
-      customPlaceholder();
-    });
-
     // 设置选中省市县
     const initCustomSelected = () => {
-      // console.log(props.modelValue);
-      if (props.modelValue.length > 0) {
-        tabIndex.value = props.modelValue.length - 1;
-        for (let index = 0; index < props.modelValue.length; index++) {
-          if ((regionList as any)[tabName.value[index]].length == 0) {
-            tabIndex.value = index - 1;
-            break;
-          } else {
-            const val = props.modelValue[index];
-            const arr: [] = (regionList as any)[tabName.value[index]];
-            if (privateType.value == 'custom') {
-              (selectedRegion as any)[tabName.value[index]] = arr.filter((item: RegionData) => item.id == val)[0];
-            } else if (privateType.value == 'custom2') {
-              let sumArr: any = [];
-              arr.map((item) => {
-                sumArr.push(...(item as any).list);
-              });
-              (selectedRegion as any)[tabName.value[index]] = sumArr.filter((item: RegionData) => item.id == val)[0];
-            }
-          }
+      const defaultValue = props.modelValue;
+      const num = defaultValue.length;
+      if (num > 0) {
+        tabIndex.value = num - 1;
+        if (regionList.value.length == 0) {
+          tabIndex.value = 0;
+          return;
         }
-      }
-    };
-
-    // 自定义‘请选择’文案
-    const customPlaceholder = () => {
-      let selectStr = translate('select');
-      let typeD = Object.prototype.toString.call(props.columnsPlaceholder || selectStr);
-      if (typeD == '[object String]') {
-        tabNameDefault.value = new Array(4).fill(props.columnsPlaceholder || selectStr);
-      } else if (typeD == '[object Array]') {
-        tabNameDefault.value = new Array(4).fill('');
-        tabNameDefault.value.forEach((val, index) => {
-          if (props.columnsPlaceholder[index]) {
-            tabNameDefault.value[index] = props.columnsPlaceholder[index];
-          } else {
-            tabNameDefault.value[index] = selectStr;
+        for (let index = 0; index < num; index++) {
+          let arr: [] = [];
+          switch (index) {
+            case 0:
+              arr = props.province;
+              break;
+            case 1:
+              arr = props.city;
+              break;
+            case 2:
+              arr = props.country;
+              break;
+            default:
+              arr = props.town;
           }
-        });
+          selectedRegion.value[index] = arr.filter((item: RegionData) => item.id == defaultValue[index])[0];
+        }
       }
     };
 
-    //获取已选地区列表名称
-    const getTabName = (item: RegionData, index: number) => {
-      if (item.name) return item.name;
-
-      if (tabIndex.value < index) {
+    const getTabName = (item: RegionData | null, index: number) => {
+      if (item && item.name) return item.name;
+      if (tabIndex.value < index && item) {
         return item.name;
       } else {
-        return tabNameDefault.value[index];
+        return props.columnsPlaceholder[index] || translate('select');
       }
     };
+
     // 手动关闭 点击叉号(cross),或者蒙层(mask)
     const handClose = (type = 'self') => {
       if (!props.closeBtnIcon) return;
@@ -389,6 +355,7 @@ export default create({
 
       showPopup.value = false;
     };
+
     // 点击遮罩层关闭
     const clickOverlay = () => {
       closeWay.value = 'mask';
@@ -396,36 +363,35 @@ export default create({
 
     // 切换下一级列表
     const nextAreaList = (item: RegionData | string) => {
-      // onchange 接收的参数
-      const calBack = {
-        next: '',
-        value: '',
-        custom: tabName.value[tabIndex.value]
+      const tab = tabIndex.value;
+
+      const callBackParams: {
+        next?: string;
+        value?: RegionData;
+        custom: string;
+      } = {
+        custom: tabName.value[tab]
       };
 
-      (selectedRegion as any)[tabName.value[tabIndex.value]] = item;
+      selectedRegion.value[tab] = item;
 
-      // for (let i = tabIndex.value; i < tabIndex.value - 1; i++) {
-      //   (selectedRegion as any)[tabName.value[i + 1]] = {};
-      // }
-      for (let i = tabIndex.value; i < 4; i++) {
-        (selectedRegion as any)[tabName.value[i + 1]] = {};
+      for (let i = tab + 2; i < 4; i++) {
+        selectedRegion.value.splice(i, 1);
       }
+      if (tab < 3) {
+        tabIndex.value = tab + 1;
 
-      if (tabIndex.value < 3) {
-        tabIndex.value = tabIndex.value + 1;
+        callBackParams.next = tabName.value[tabIndex.value];
+        callBackParams.value = item;
 
-        // 切换下一个
-        calBack.next = tabName.value[tabIndex.value];
-        calBack.value = item as string;
-        emit('change', calBack);
+        emit('change', callBackParams);
       } else {
         handClose();
         emit('update:modelValue');
       }
     };
     //切换地区Tab
-    const changeRegionTab = (item: RegionData, key: number, index: number) => {
+    const changeRegionTab = (item: RegionData, index: number) => {
       if (getTabName(item, index)) {
         tabIndex.value = index;
       }
@@ -436,11 +402,9 @@ export default create({
       const copyExistAdd = props.existAddress as AddressList[];
       let prevExistAdd = {};
 
-      copyExistAdd.forEach((list, index) => {
-        if (list && (list as AddressList).selectedAddress) {
-          prevExistAdd = list;
-        }
-        (list as AddressList).selectedAddress = false;
+      copyExistAdd.forEach((list: AddressList) => {
+        if (list && list.selectedAddress) prevExistAdd = list;
+        list.selectedAddress = false;
       });
 
       item.selectedAddress = true;
@@ -453,67 +417,54 @@ export default create({
     };
     // 初始化
     const initAddress = () => {
-      for (let i = 0; i < tabName.value.length; i++) {
-        (selectedRegion as any)[tabName.value[i]] = {};
-      }
+      selectedRegion.value = [];
       tabIndex.value = 0;
     };
 
     // 关闭
     const close = () => {
-      const resCopy = Object.assign(
-        {
-          addressIdStr: '',
-          addressStr: ''
-        },
-        selectedRegion
-      );
-
-      const res = {
+      const data = {
+        addressIdStr: '',
+        addressStr: '',
+        province: selectedRegion.value[0],
+        city: selectedRegion.value[1],
+        country: selectedRegion.value[2],
+        town: selectedRegion.value[3]
+      };
+
+      const callBackParams = {
         data: {},
         type: privateType.value
       };
 
-      if (privateType.value == 'custom' || privateType.value == 'custom2') {
-        const { province, city, country, town } = resCopy;
-
-        resCopy.addressIdStr = [
-          (province as RegionData).id || 0,
-          (city as RegionData).id || 0,
-          (country as RegionData).id || 0,
-          (town as RegionData).id || 0
-        ].join('_');
-        resCopy.addressStr = [
-          (province as RegionData).name,
-          (city as RegionData).name,
-          (country as RegionData).name,
-          (town as RegionData).name
-        ].join('');
-        res.data = resCopy;
+      if (['custom', 'custom2'].includes(privateType.value)) {
+        [0, 1, 2, 3].forEach((i) => {
+          const item = selectedRegion.value[i];
+          data.addressIdStr += `${i ? '_' : ''}${(item && item.id) || 0}`;
+          data.addressStr += (item && item.name) || '';
+        });
+
+        callBackParams.data = data;
       } else {
-        res.data = selectedExistAddress;
+        callBackParams.data = selectedExistAddress;
       }
 
       initAddress();
 
       if (closeWay.value == 'self') {
-        emit('close', res);
+        emit('close', callBackParams);
       } else {
         emit('close-mask', { closeWay: closeWay });
       }
+
       emit('update:visible', false);
     };
 
     // 选择其他地址
     const switchModule = () => {
-      if (privateType.value == 'exist') {
-        privateType.value = 'custom';
-      } else {
-        privateType.value = 'exist';
-      }
-
+      const type = privateType.value;
+      privateType.value = type == 'exist' ? 'custom' : 'exist';
       initAddress();
-
       emit('switch-module', { type: privateType.value });
     };
 
@@ -531,51 +482,12 @@ export default create({
     watch(
       () => showPopup.value,
       (value) => {
-        if (value == false) {
-          close();
-        } else {
+        if (value) {
           initCustomSelected();
         }
       }
     );
 
-    watch(
-      () => props.province,
-      (value) => {
-        regionList.province = isCustom2.value ? transformData(value) : value;
-      }
-    );
-    watch(
-      () => props.city,
-      (value) => {
-        regionList.city = isCustom2.value ? transformData(value) : value;
-      }
-    );
-    watch(
-      () => props.country,
-      (value) => {
-        regionList.country = isCustom2.value ? transformData(value) : value;
-      }
-    );
-    watch(
-      () => props.town,
-      (value) => {
-        regionList.town = isCustom2.value ? transformData(value) : value;
-      }
-    );
-
-    watch(
-      () => props.existAddress,
-      (value) => {
-        //  existAddress.value = value;
-        value.forEach((item, index) => {
-          if ((item as AddressList).selectedAddress) {
-            selectedExistAddress = item as {};
-          }
-        });
-      }
-    );
-
     return {
       classes,
       showPopup,
@@ -590,7 +502,6 @@ export default create({
       close,
       getTabName,
       nextAreaList,
-      regionLine,
       lineDistance,
       changeRegionTab,
       selectedExist,
@@ -599,7 +510,8 @@ export default create({
       handleElevatorItem,
       ...toRefs(props),
       ...toRefs(tabItemRef),
-      translate
+      translate,
+      transformData
     };
   }
 });

+ 143 - 220
src/packages/__VUE/address/index.vue

@@ -38,12 +38,15 @@
         <view class="nut-address-region-tab" ref="tabRegion">
           <view
             :class="['tab-item', index == tabIndex ? 'active' : '']"
-            v-for="(item, key, index) in selectedRegion"
+            v-for="(item, index) in selectedRegion"
             :key="index"
-            @click="changeRegionTab(item, key, index)"
+            @click="changeRegionTab(item, index)"
           >
             <view>{{ getTabName(item, index) }} </view>
           </view>
+          <view class="active tab-item" v-if="tabIndex == selectedRegion.length">
+            <view>{{ getTabName(null, selectedRegion.length) }} </view>
+          </view>
 
           <view class="region-tab-line" ref="regionLine" :style="{ left: lineDistance + 'px' }"></view>
         </view>
@@ -51,22 +54,18 @@
         <view class="region-con" v-if="privateType == 'custom'">
           <ul class="region-group">
             <li
-              v-for="(item, index) in regionList[tabName[tabIndex]]"
+              v-for="(item, index) in regionList"
               :key="index"
-              class="region-item"
-              :class="[selectedRegion[tabName[tabIndex]].id == item.id ? 'active' : '']"
+              :class="['region-item', selectedRegion[tabIndex]?.id == item.id ? 'active' : '']"
               @click="nextAreaList(item)"
             >
               <div>
-                <nut-icon
-                  class="region-item-icon"
-                  type="self"
+                <component
+                  :is="renderIcon(selectedIcon)"
                   v-bind="$attrs"
-                  :name="selectedIcon"
-                  size="13px"
-                  v-if="selectedRegion[tabName[tabIndex]].id == item.id"
-                ></nut-icon
-                >{{ item.name }}
+                  v-if="selectedRegion[tabIndex]?.id == item.id"
+                ></component>
+                {{ item.name }}
               </div>
             </li>
           </ul>
@@ -75,35 +74,29 @@
         <view class="elevator-group" v-else>
           <nut-elevator
             :height="height"
-            :index-list="regionList[tabName[tabIndex]]"
+            :index-list="transformData(regionList)"
             @click-item="handleElevatorItem"
           ></nut-elevator>
         </view>
       </view>
 
       <!-- 配送至 -->
-      <view class="exist-address" v-else-if="privateType == 'exist'">
+      <view class="exist-address" v-else>
         <div class="exist-address-group">
           <ul class="exist-ul">
             <li
-              class="exist-item"
-              :class="[item.selectedAddress ? 'active' : '']"
+              :class="['exist-item', item.selectedAddress ? 'active' : '']"
               v-for="(item, index) in existAddress"
               :key="index"
               @click="selectedExist(item)"
             >
-              <nut-icon
-                class="exist-item-icon"
-                type="self"
+              <component
+                :is="renderIcon(item.selectedAddress ? selectedIcon : defaultIcon)"
                 v-bind="$attrs"
-                :name="item.selectedAddress ? selectedIcon : defaultIcon"
-                size="13px"
-              ></nut-icon>
+              ></component>
               <div class="exist-item-info">
-                <div class="exist-item-info-top" v-if="item.name && item.phone">
-                  <div class="exist-item-info-name">{{ item.name }}</div>
-                  <div class="exist-item-info-phone">{{ item.phone }}</div>
-                </div>
+                <div class="exist-item-info-name" v-if="item.name">{{ item.name }}</div>
+                <div class="exist-item-info-phone" v-if="item.phone">{{ item.phone }}</div>
                 <div class="exist-item-info-bottom">
                   <view>
                     {{ item.provinceName + item.cityName + item.countyName + item.townName + item.addressDetail }}
@@ -124,13 +117,14 @@
   </nut-popup>
 </template>
 <script lang="ts">
-import { reactive, ref, toRefs, watch, nextTick, computed, Ref, onMounted } from 'vue';
+import { reactive, ref, toRefs, watch, nextTick, computed, Ref, h } from 'vue';
 import { createComponent } from '@/packages/utils/create';
-import { isArray, isString, TypeOfFun } from '@/packages/utils/util';
 import { popupProps } from '../popup/props';
+import Icon from '../icon/index.vue';
 const { componentName, create, translate } = createComponent('address');
 interface RegionData {
   name: string;
+  id: number | string;
   [key: string]: any;
 }
 interface CustomRegionData {
@@ -182,11 +176,11 @@ export default create({
     isShowCustomAddress: {
       type: Boolean,
       default: true
-    }, // 是否显示‘选择其他地区’按钮 type=‘exist’ 生效
+    },
     existAddress: {
       type: Array,
       default: () => []
-    }, // 现存地址列表
+    },
     existAddressTitle: {
       type: String,
       default: ''
@@ -196,22 +190,18 @@ export default create({
       default: ''
     },
     defaultIcon: {
-      // 地址选择列表前 - 默认的图标
       type: String,
       default: 'location2'
     },
     selectedIcon: {
-      // 地址选择列表前 - 选中的图标
       type: String,
       default: 'Check'
     },
     closeBtnIcon: {
-      // 关闭弹框按钮 icon
       type: String,
       default: 'circle-close'
     },
     backBtnIcon: {
-      // 选择其他地址左上角返回 icon
       type: String,
       default: 'left'
     },
@@ -228,19 +218,36 @@ export default create({
 
   setup(props: any, { emit }) {
     const regionLine = ref<null | HTMLElement>(null);
-
     const tabRegion: Ref<any> = ref(null);
-
     const showPopup = ref(props.visible);
     const privateType = ref(props.type);
     const tabIndex = ref(0);
     const tabName = ref(['province', 'city', 'country', 'town']);
-    const tabNameDefault = ref(new Array(4).fill(translate('select')));
 
-    const isCustom2 = computed(() => props.type === 'custom2');
+    const regionList = computed(() => {
+      switch (tabIndex.value) {
+        case 0:
+          return props.province;
+        case 1:
+          return props.city;
+        case 2:
+          return props.country;
+        default:
+          return props.town;
+      }
+    });
+
+    const renderIcon = (n: string) => {
+      return h(Icon, {
+        class: `${componentName}-select-icon`,
+        type: 'self',
+        size: '13px',
+        name: n
+      });
+    };
 
     const transformData = (data: RegionData[]) => {
-      if (!isArray(data)) throw new TypeError('params muse be array.');
+      if (!Array.isArray(data)) throw new TypeError('params muse be array.');
 
       if (!data.length) return [];
 
@@ -253,9 +260,7 @@ export default create({
 
       const newData: CustomRegionData[] = [];
 
-      data = data.sort((a: RegionData, b: RegionData) => {
-        return a.title.localeCompare(b.title);
-      });
+      data = data.sort((a: RegionData, b: RegionData) => a.title.localeCompare(b.title));
 
       data.forEach((item: RegionData) => {
         const index = newData.findIndex((value: CustomRegionData) => value.title === item.title);
@@ -265,29 +270,15 @@ export default create({
             list: [].concat(item)
           });
         } else {
-          newData[index] = {
-            title: item.title,
-            list: newData[index].list.concat(item)
-          };
+          newData[index].list.push(item);
         }
       });
 
       return newData;
     };
 
-    const regionList = reactive({
-      province: isCustom2.value ? transformData(props.province) : props.province,
-      city: isCustom2.value ? transformData(props.city) : props.city,
-      country: isCustom2.value ? transformData(props.country) : props.country,
-      town: isCustom2.value ? transformData(props.town) : props.town
-    });
-
-    const selectedRegion = reactive({
-      province: {} as RegionData,
-      city: {} as RegionData,
-      country: {} as RegionData,
-      town: {} as RegionData
-    }); //已选择的 省、市、县、镇
+    //已选择的 省、市、县、镇
+    let selectedRegion = ref<RegionData[]>([]);
 
     let selectedExistAddress = reactive({}); // 当前选择的地址
 
@@ -297,123 +288,98 @@ export default create({
 
     // 设置选中省市县
     const initCustomSelected = () => {
-      if (props.modelValue.length > 0) {
-        tabIndex.value = props.modelValue.length - 1;
-        for (let index = 0; index < props.modelValue.length; index++) {
-          if ((regionList as any)[tabName.value[index]].length == 0) {
-            tabIndex.value = index - 1;
-            break;
-          } else {
-            const val = props.modelValue[index];
-            const arr: [] = (regionList as any)[tabName.value[index]];
-            if (privateType.value == 'custom') {
-              (selectedRegion as any)[tabName.value[index]] = arr.filter((item: RegionData) => item.id == val)[0];
-            } else if (privateType.value == 'custom2') {
-              let sumArr: any = [];
-              arr.map((item) => {
-                sumArr.push(...(item as any).list);
-              });
-              (selectedRegion as any)[tabName.value[index]] = sumArr.filter((item: RegionData) => item.id == val)[0];
-            }
+      const defaultValue = props.modelValue;
+      const num = defaultValue.length;
+      if (num > 0) {
+        tabIndex.value = num - 1;
+        if (regionList.value.length == 0) {
+          tabIndex.value = 0;
+          return;
+        }
+        for (let index = 0; index < num; index++) {
+          let arr: [] = [];
+          switch (index) {
+            case 0:
+              arr = props.province;
+              break;
+            case 1:
+              arr = props.city;
+              break;
+            case 2:
+              arr = props.country;
+              break;
+            default:
+              arr = props.town;
           }
+          selectedRegion.value[index] = arr.filter((item: RegionData) => item.id == defaultValue[index])[0];
         }
         lineAnimation();
       }
     };
-    // 自定义‘请选择’文案
-    const customPlaceholder = () => {
-      const { columnsPlaceholder } = props;
-      if (!columnsPlaceholder) return;
-      if (isString(columnsPlaceholder)) {
-        tabNameDefault.value = new Array(4).fill(columnsPlaceholder);
-      } else if (isArray(columnsPlaceholder) && columnsPlaceholder.length < 5) {
-        columnsPlaceholder.forEach((val, index) => {
-          tabNameDefault.value[index] = val;
-        });
-      }
-    };
-
-    //获取已选地区列表名称
-    const getTabName = (item: RegionData, index: number) => {
-      if (item.name) return item.name;
-
-      if (tabIndex.value < index) {
+    const getTabName = (item: RegionData | null, index: number) => {
+      if (item && item.name) return item.name;
+      if (tabIndex.value < index && item) {
         return item.name;
       } else {
-        return tabNameDefault.value[index];
+        return props.columnsPlaceholder[index] || translate('select');
       }
     };
-    // 手动关闭 点击叉号(cross),或者蒙层(mask)
-    const handClose = (type = 'self') => {
-      if (!props.closeBtnIcon) return;
-
-      closeWay.value = type == 'cross' ? 'cross' : 'self';
 
-      showPopup.value = false;
-    };
-    // 点击遮罩层关闭
-    const clickOverlay = () => {
-      closeWay.value = 'mask';
-    };
-    // 移动下面的红线
     const lineAnimation = () => {
       nextTick(() => {
         const name = tabRegion.value && tabRegion.value.getElementsByClassName('active')[0];
-
         if (name) {
           const distance = name.offsetLeft;
-
           lineDistance.value = distance ? distance : 20;
         }
       });
     };
-    // 切换下一级列表
-    const nextAreaList = (item: RegionData | string) => {
-      // onchange 接收的参数
-      const calBack = {
-        next: '',
-        value: '',
-        custom: tabName.value[tabIndex.value]
+
+    const nextAreaList = (item: RegionData) => {
+      const tab = tabIndex.value;
+
+      const callBackParams: {
+        next?: string;
+        value?: RegionData;
+        custom: string;
+      } = {
+        custom: tabName.value[tab]
       };
 
-      (selectedRegion as any)[tabName.value[tabIndex.value]] = item;
+      selectedRegion.value[tab] = item;
 
-      for (let i = tabIndex.value; i < 4; i++) {
-        (selectedRegion as any)[tabName.value[i + 1]] = {};
+      for (let i = tab + 2; i < 4; i++) {
+        selectedRegion.value.splice(i, 1);
       }
-
-      if (tabIndex.value < 3) {
-        tabIndex.value = tabIndex.value + 1;
+      if (tab < 3) {
+        tabIndex.value = tab + 1;
 
         lineAnimation();
 
-        // 切换下一个
-        calBack.next = tabName.value[tabIndex.value];
-        calBack.value = item as string;
-        emit('change', calBack);
+        callBackParams.next = tabName.value[tabIndex.value];
+        callBackParams.value = item;
+
+        emit('change', callBackParams);
       } else {
         handClose();
         emit('update:modelValue');
       }
     };
-    //切换地区Tab
-    const changeRegionTab = (item: RegionData, key: number, index: number) => {
+
+    const changeRegionTab = (item: RegionData, index: number) => {
       if (getTabName(item, index)) {
         tabIndex.value = index;
         lineAnimation();
       }
     };
 
-    // 选择现有地址
     const selectedExist = (item: RegionData) => {
       const copyExistAdd = props.existAddress as AddressList[];
       let prevExistAdd = {};
 
-      copyExistAdd.forEach((list, index) => {
-        if (list && (list as AddressList).selectedAddress) {
-          prevExistAdd = list;
-        }
-        (list as AddressList).selectedAddress = false;
+      copyExistAdd.forEach((list: AddressList) => {
+        if (list && list.selectedAddress) prevExistAdd = list;
+        list.selectedAddress = false;
       });
 
       item.selectedAddress = true;
@@ -424,81 +390,74 @@ export default create({
 
       handClose();
     };
-    // 初始化
+
     const initAddress = () => {
-      for (let i = 0; i < tabName.value.length; i++) {
-        (selectedRegion as any)[tabName.value[i]] = {};
-      }
+      selectedRegion.value = [];
       tabIndex.value = 0;
       lineAnimation();
     };
 
-    // 关闭
+    // 手动关闭 点击叉号(cross),或者蒙层(mask)
+    const handClose = (type = 'self') => {
+      if (!props.closeBtnIcon) return;
+      closeWay.value = type == 'cross' ? 'cross' : 'self';
+      showPopup.value = false;
+    };
+
+    const clickOverlay = () => {
+      closeWay.value = 'mask';
+    };
+
     const close = () => {
-      const resCopy = Object.assign(
-        {
-          addressIdStr: '',
-          addressStr: ''
-        },
-        selectedRegion
-      );
-
-      const res = {
+      const data = {
+        addressIdStr: '',
+        addressStr: '',
+        province: selectedRegion.value[0],
+        city: selectedRegion.value[1],
+        country: selectedRegion.value[2],
+        town: selectedRegion.value[3]
+      };
+
+      const callBackParams = {
         data: {},
         type: privateType.value
       };
 
-      if (privateType.value == 'custom' || privateType.value == 'custom2') {
-        const { province, city, country, town } = resCopy;
-
-        resCopy.addressIdStr = [
-          (province as RegionData).id || 0,
-          (city as RegionData).id || 0,
-          (country as RegionData).id || 0,
-          (town as RegionData).id || 0
-        ].join('_');
-        resCopy.addressStr = [
-          (province as RegionData).name,
-          (city as RegionData).name,
-          (country as RegionData).name,
-          (town as RegionData).name
-        ].join('');
-        res.data = resCopy;
+      if (['custom', 'custom2'].includes(privateType.value)) {
+        [0, 1, 2, 3].forEach((i) => {
+          const item = selectedRegion.value[i];
+          data.addressIdStr += `${i ? '_' : ''}${(item && item.id) || 0}`;
+          data.addressStr += (item && item.name) || '';
+        });
+
+        callBackParams.data = data;
       } else {
-        res.data = selectedExistAddress;
+        callBackParams.data = selectedExistAddress;
       }
 
       initAddress();
 
       if (closeWay.value == 'self') {
-        emit('close', res);
+        emit('close', callBackParams);
       } else {
         emit('close-mask', { closeWay: closeWay });
       }
+
       emit('update:visible', false);
     };
 
     // 选择其他地址
     const switchModule = () => {
-      if (privateType.value == 'exist') {
-        privateType.value = 'custom';
-      } else {
-        privateType.value = 'exist';
-      }
-
+      const type = privateType.value;
+      privateType.value = type == 'exist' ? 'custom' : 'exist';
       initAddress();
-
       emit('switch-module', { type: privateType.value });
     };
 
-    const handleElevatorItem = (key: string, item: RegionData | string) => {
+    const handleElevatorItem = (key: string, item: RegionData) => {
       nextAreaList(item);
     };
 
-    const updateRegion = (type: string, value: any) => {
-      regionList[type] = isCustom2.value ? transformData(value) : value;
-    };
-
     watch(
       () => props.visible,
       (value) => {
@@ -510,56 +469,17 @@ export default create({
       () => showPopup.value,
       (value) => {
         if (value) {
-          customPlaceholder();
           initCustomSelected();
         }
       }
     );
 
-    watch(
-      () => props.province,
-      (value) => {
-        updateRegion('province', value);
-      }
-    );
-    watch(
-      () => props.city,
-      (value) => {
-        updateRegion('city', value);
-      }
-    );
-    watch(
-      () => props.country,
-      (value) => {
-        updateRegion('country', value);
-      }
-    );
-    watch(
-      () => props.town,
-      (value) => {
-        updateRegion('town', value);
-      }
-    );
-
-    watch(
-      () => props.existAddress,
-      (value) => {
-        value.forEach((item) => {
-          if ((item as AddressList).selectedAddress) {
-            selectedExistAddress = item as {};
-          }
-        });
-      }
-    );
-
     return {
       showPopup,
       privateType,
       tabIndex,
       tabName,
-      regionList,
       selectedRegion,
-      selectedExistAddress,
       switchModule,
       closeWay,
       close,
@@ -575,7 +495,10 @@ export default create({
       handleElevatorItem,
       initCustomSelected,
       ...toRefs(props),
-      translate
+      translate,
+      regionList,
+      transformData,
+      renderIcon
     };
   }
 });