codecamp

支付宝小程序 UI·级联选择(最大三级)

实现级联选择,可自动适配二级或者三级选择器, 一般用于省、市、区三级联动选择。

扫码体验

级联选择二维码.png

前提条件

使用级联选择的前提条件如下:

获取模板代码

下载 级联选择 Demo.zip 文件,并解压至本地。

字段说明

字段名 类型 说明 示例
selectShow boolen true 选择器是否显示。默认 false,支持 true / false .
selectValue String 浙江省杭州市西湖区 组件显示的value。
list Array [{"name":"北京",  "code":"110000",  "sub":[] }] 级联数据,需要有 namecodesub(有子级需要字段同name/code)

list 示例

[
  {
    "name": "北京市",
    "code": "110000",
    "sub": [
      {
        "name": "北京市",
        "code": "110100",
        "sub": [
          {
            "name": "东城区",
            "code": "110101"
          },
          {
            "name": "密云区",
            "code": "110118"
          },


          {
            "name": "延庆区",
            "code": "110119"
          }
        ]
      },
    ]
  },
  {
    "name": "天津市",
    "code": "120000",
    "sub": [
      {
        "name": "天津市",
        "code": "120100",
        "sub": [
          {
            "name": "河北区",
            "code": "120105"
          },


          {
            "name": "红桥区",
            "code": "120106"
          }
        ]
      }
    ]
  }
]

示例代码

index.json

// 注意: 使用前请在package.json中引入 mini-ali-ui
{
  "component": true,
  "usingComponents": {
    "popup": "mini-ali-ui/es/popup/index",
    "tabs": "mini-ali-ui/es/tabs/index",
    "tab-content": "mini-ali-ui/es/tabs/tab-content/index"
  }
}

index.axml

<view>
  <popup show="{{selectShow}}" position="bottom" onClose="onPopupClose" className="picker-popup" disableScroll="{{false}}">
    <view class="btn-action">
      <view class="cancel-btn" data-click="{{isConfirm}}" onTap="onCancel">取消                                                            
      </view>
      <view class="confirm-btn {{isConfirm?'active':'disable'}}" data-click="{{isConfirm}}" onTap="onConfirm">确定                                                            
      </view>
    </view>
    <tabs className="pipick-view-tab" tabBarCls="pick-view-tab-header" activeCls="activeTab" tabBarActiveTextColor="#333333" tabBarBackgroundColor="transparent" tabs="{{selectList}}" swipeable="{{false}}" onTabClick="handleTabClick" activeTab="{{activeTab}}">
      <block a:for="{{selectList}}" a:for-index="idx" a:for-item="itemName">
        <tab-content key="{{idx}}">
          <scroll-view class="pick-view-content" scroll-y="{{true}}" trap-scroll="{{true}}">
            <block a:for="{{itemName.sub}}">
              <view data-key="{{idx}}" data-name="{{item.name}}" data-code="{{item.code}}" data-sub="{{item.sub?item.sub:''}}" class="pick-view-content-item {{selectList[idx].title===item.name?'curret':''}}" onTap="itemSelect">{{item.name}}                                                        
              </view>
            </block>
          </scroll-view>
        </tab-content>
      </block>
    </tabs>
  </popup>
</view>

index.acss

.picker-popup {
  font-family: PingFangSC-Regular;
}
.btn-action{
  display: flex;
  align-items: center;
  padding: 30rpx;
  box-sizing: border-box;
  background: #FFFFFF
}
.pipick-view-tab .am-tabs-bar {
  height: 80rpx;
  box-sizing: border-box;
  border-bottom: 1rpx solid #DDDDDD;
  padding:0 10rpx;
}


.pipick-view-tab .am-tabs-bar-content {
  height: 79rpx;
  box-sizing: border-box;
}


.pipick-view-tab .am-tabs-scroll-right, .pipick-view-tab .am-tabs-scroll-left {
  width: 0;
  display: none;
}


.pick-view-tab-header {
  height: 79rpx;
  line-height: 79rpx;
  box-sizing: border-box;
  font-size: 26rpx;
  color: #333333;
}


.pick-view-tab-header .am-tabs-bar-title {
  max-width: 180rpx;
  height: 79rpx;
  line-height: 79rpx;
  border-bottom: 4rpx solid transparent;
  box-sizing: border-box;
  padding: 0 20rpx;
}


.pick-view-tab-header .am-tabs-bar-title text {
  max-width: 180rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block;
}


.pipick-view-tab .am-tabs-content-wrap {
  margin-top: 0;
}


.pick-view-content {
  height: 480rpx;
  padding: 20rpx 0;
  box-sizing: border-box;
}


.pick-view-content-item {
  height: 60rpx;
  line-height: 60rpx;
  padding: 0 30rpx;
  color: #333333;
  width: 100%;
  box-sizing: border-box;
  font-size: 26rpx;
}


.confirm-btn {
  text-align: right;
  flex: 1;
}
.cancel-btn{
  flex:1;
}


.disable {
  color: #CCCCCC;
}


.active {
  color: #108ee9;
}


.curret {
  color: #FFFFFF;
  background: #108ee9;
}

index.js

Component({
  data: {
    isConfirm: false, // 确认是否可点击
    selectList: [
      {
        title: '请选择',
        sub: []
      }
    ], // list数据
    activeTab: 0 // 当前tab项
  },
  props: {
    selectShow: false // 选择面板是否展示
  },
  didMount() {
    const { list } = this.props;
    this.setData({
      selectList: [
        {
          title: '请选择',
          sub: list
        }
      ]
    });
  },
  didUpdate(prevProps, prevData) {
    const { selectValue, list } = this.props;
    // 面板状态改变的时候数据的重新渲染
    if (!prevProps.selectShow && this.props.selectShow && selectValue) {
      const selectArray = selectValue.split(' ');
      let selectList = [];
      selectArray.map((item, k) => {
        if (k === 0) {
          const provinces = {
            title: item,
            sub: list
          };
          selectList.push(provinces);
        }
        if (k === 1) {
          list.map((data, index) => {
            if (data.name === selectArray[k - 1]) {
              const city = {
                title: item,
                sub: data.sub
              };
              selectList.push(city);
            }
          });
        }
        if (k === 2) {
          list.map((data, index) => {
            if (data.name === selectArray[k - 2]) {
              data.sub.map((areaData, i) => {
                if (areaData.name === selectArray[k - 1]) {
                  const area = {
                    title: item,
                    sub: areaData.sub
                  };
                  selectList.push(area);
                }
              });
            }
          });
        }
      });
      this.setData({
        selectList,
        activeTab: selectArray.length - 1
      });
    }
  },
  didUnmount() { },
  methods: {
    /**
     * 关闭popup
     * @method onPopupClose
     */
    onPopupClose() {
      const { selectValue, list } = this.props;
      if (!selectValue) {
        this.setData({
          isConfirm: false,
          selectList: [
            {
              title: '请选择',
              sub: list
            }
          ],
          activeTab: 0
        });
      }
      this.props.onClose();
    },
    /**
     * 确认
     * @method onConfirm
     * @param {*} e
     */
    onConfirm(e) {
      if (e.target.dataset.click) {
        // 点击确定
        const { selectList } = this.data;
        let result = [];
        selectList.map((item) => {
          const singleSelect = {
            name: item.title,
            code: item.code
          };
          result.push(singleSelect);
        });
        this.props.onSelectSuccess(result);
        this.props.onClose();
      }
    },
    /**
     * 取消
     * @method onCancel
     */
    onCancel() {
      this.props.onClose();
    },
    /**
     * tab切换
     * @method handleTabClick
     * @param {*} index
     */
    handleTabClick({ index }) {
      this.setData({
        activeTab: index
      });
    },
    /**
     * 省市区选择事件
     * @method itemSelect
     * @param {*} e
     */
    itemSelect(e) {
      const { key, name, code, sub } = e.target.dataset;
      const { list } = this.props;
      if (key === 0) { // 第一级数据处理
        if (sub) {
          this.setData({
            selectList: [
              {
                title: name,
                code,
                sub: list
              },
              {
                title: '城市',
                sub: sub
              }
            ],
            activeTab: 1,
            isConfirm: false
          });
        } else {
          this.setData({
            selectList: [
              {
                title: name,
                code,
                sub: list
              }
            ],
            isConfirm: true
          });
        }
      }
      if (key === 1) { // 第二级数据处理
        if (sub) {
          this.setData({
            selectList: [
              {
                title: this.data.selectList[0].title,
                code: this.data.selectList[0].code,
                sub: list
              },
              {
                title: name,
                code,
                sub: this.data.selectList[1].sub
              },
              {
                title: '区县',
                sub: sub
              }
            ],
            activeTab: 2,
            isConfirm: false
          });
        } else {
          this.setData({
            selectList: [
              {
                title: this.data.selectList[0].title,
                code: this.data.selectList[0].code,
                sub: list
              },
              {
                title: name,
                code,
                sub: this.data.selectList[1].sub
              }
            ],
            activeTab: 1,
            isConfirm: true
          });
        }
      }
      if (key === 2) { // 第三级数据处理
        this.setData({
          selectList: [
            {
              title: this.data.selectList[0].title,
              code: this.data.selectList[0].code,
              sub: list
            },
            {
              title: this.data.selectList[1].title,
              code: this.data.selectList[1].code,
              sub: this.data.selectList[1].sub
            },
            {
              title: name,
              code,
              sub: this.data.selectList[2].sub
            }
          ],
          activeTab: 2,
          isConfirm: true
        });
      }
    }
  }
});
支付宝小程序 快速示例·概览
支付宝小程序 UI·上滑加载更多
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

支付宝小程序开发文档

支付宝小程序 快速示例

支付宝小程序 小程序快速示例

支付宝小程序 框架

支付宝小程序 组件

支付宝小程序组件 基础组件

支付宝小程序组件 无障碍访问

支付宝小程序 扩展组件

支付宝小程序扩展组件 UI组件

支付宝小程序 API

支付宝小程序 开发工具

支付宝小程序 云服务

支付宝小程序 Serverless

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }