# tui-cascade-selection 级联选择 开源组件
介绍
Cascade Selection:支持一次性传入所有数据,支持分级请求返回数据,支持N级,直至没有下一级数据。
# 引入
# uni-app引入
第一种,手动引入(可全局引入)
import tuiCascadeSelection from "@/components/thorui/tui-cascade-selection/tui-cascade-selection.vue"
export default {
	components:{
		tuiCascadeSelection
	}
}
第二种,开启easycom组件模式,如果不了解如何配置,可先查看 官网文档 (opens new window)。
# uni-app版本平台差异说明
| App-Nvue | App-vue | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节小程序 | QQ小程序 | 
|---|---|---|---|---|---|---|---|
| 升级中 | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 
# 微信小程序引入(可在app.json中全局引入)
{
  "usingComponents": {
    "tui-cascade-selection": "/components/thorui/tui-cascade-selection/tui-cascade-selection"
  }
}
# 代码演示
部分功能演示,具体可参考示例程序以及文档API。
通过 itemList 属性传入所有数据。
<!--uni-app-->
<tui-cascade-selection height="200px" :itemList="itemList" @complete="complete"></tui-cascade-selection>
// data 数据 及 方法
// 请自行引入该js文件,数据格式见下方介绍 (text、value、children)【数组】
import cityData from '@/utils/picker.city.js';
export default {
  data() {
  	return {
  		itemList:cityData
  	}
  },
  methods: {
  	complete(e) {
  		console.log(e);
  		console.log('您选择的数据为:' + e.text)
  	}
  }
}
<!--微信小程序-->
<tui-cascade-selection height="200px" itemList="{{itemList}}" bindcomplete="complete"></tui-cascade-selection>
// data 数据 及 方法
// 请自行引入该js文件,数据格式见下方介绍 (text、value、children)【数组】
const cityData = require('../../../utils/picker.city.js');
Page({
  data: {
    itemList:cityData
  },
  complete(e) {
  	console.log(e.detail);
  	console.log('您选择的数据为:' + e.detail.text)
  }
})
// Make sure to add code blocks to your code group
通过 request 属性控制子集数据是否为请求返回。 请求返回子级数据时 itemList 属性传入第一级数据。 通过  receiveData 属性传入请求返回的子级数据。
change 为选择器item项中点击回传事件,用于请求下一级数据时使用。
<!--uni-app-->
<tui-cascade-selection request height="200px" :itemList="itemList" :receiveData="receiveData" @complete="complete" @change="change"></tui-cascade-selection>
// data 数据 及 方法
export default {
  data() {
  	return {
  		itemList: [],
  		receiveData: [],
  		webURL: 'https://thorui.cn'
  	}
  },
  onLoad() {
  	this.itemList = [
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(1)班',
  			subText: '30人',
  			value: 101
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(2)班',
  			subText: '30人',
  			value: 102
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(3)班',
  			subText: '30人',
  			value: 103
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(4)班',
  			subText: '28人',
  			value: 104
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(5)班',
  			subText: '28人',
  			value: 105
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(6)班',
  			subText: '28人',
  			value: 106
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(7)班',
  			subText: '28人',
  			value: 107
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(8)班',
  			subText: '38人',
  			value: 108
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(9)班',
  			subText: '38人',
  			value: 109
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(10)班',
  			subText: '38人',
  			value: 110
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(11)班',
  			subText: '38人',
  			value: 111
  		},
  		{
  			src: this.webURL + '/images/basic/color.png',
  			text: '高一(12)班',
  			subText: '38人',
  			value: 112
  		}
  	];
  },
  methods: {
  	change(e) {
  		console.log(e);
  		/**
  		 *   layer: 0  第几级 index
  			 src: '/static/images/basic/color.png'
  			 subIndex: 2   //当前层级下选中项index
  			 subText: '30人'  //选中项数据
  			 text: '高一(3)班'
  			 value: 103 //选中项value数据
  		 * */
  	
  		// 模拟请求
  		let value = e.value;
  		let layer = e.layer;
  		if (layer === 7) {
  			//实际中以请求数据为准,无下级数据则传空数组
  			this.receiveData = [];
  		} else {
  			uni.showLoading({
  				title: '请稍候...'
  			});
  			setTimeout(() => {
  				uni.hideLoading();
  				//请求完成后将数据处理成以下格式,传入,最后一级没有则传空数组
  				switch (layer) {
  					case 0:
  						this.receiveData = [
  							{
  								text: '张三',
  								subText: '男',
  								value: 11101
  							},
  							{
  								text: '王五',
  								subText: '男',
  								value: 11102
  							},
  							{
  								text: '周小小',
  								subText: '女',
  								value: 11103
  							},
  							{
  								text: '周小小',
  								subText: '女',
  								value: 11103
  							},
  							{
  								text: '周小小',
  								subText: '女',
  								value: 11103
  							}
  						];
  						break;
  					case 1:
  						this.receiveData = [
  							{
  								text: '他(她)说',
  								value: 11101
  							}
  						];
  						break;
  					case 2:
  						this.receiveData = [
  							{
  								text: '这是一个',
  								value: 11101
  							}
  						];
  						break;
  					case 3:
  						this.receiveData = [
  							{
  								text: '级联选择器',
  								value: 11101
  							}
  						];
  						break;
  					case 4:
  						this.receiveData = [
  							{
  								text: '测试例子',
  								value: 11101
  							}
  						];
  						break;
  					case 5:
  						this.receiveData = [
  							{
  								text: '总共',
  								value: 11101
  							}
  						];
  						break;
  					case 6:
  						this.receiveData = [
  							{
  								text: '8级数据',
  								value: 11101
  							}
  						];
  						break;
  					default:
  						break;
  				}
  			}, 800);
  		}
  	},
  	complete(e) {
  		console.log(e);
  		console.log('您选择的数据为:' + e.text);
  	}
  }
}
<!--微信小程序-->
<tui-cascade-selection request height="200px" itemList="{{itemList}}" receiveData="{{receiveData}}" bindcomplete="complete" bindchange="change"></tui-cascade-selection>
// data 数据 及 方法
Page({
  data: {
    itemList: [],
    receiveData: [],
    webURL: 'https://thorui.cn'
  },
  onLoad: function (options) {
      let itemList = [{
          src: '/static/images/basic/color.png',
          text: '高一(1)班',
          subText: '30人',
          value: 101
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(2)班',
          subText: '30人',
          value: 102
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(3)班',
          subText: '30人',
          value: 103
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(4)班',
          subText: '28人',
          value: 104
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(5)班',
          subText: '28人',
          value: 105
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(6)班',
          subText: '28人',
          value: 106
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(7)班',
          subText: '28人',
          value: 107
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(8)班',
          subText: '38人',
          value: 108
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(9)班',
          subText: '38人',
          value: 109
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(10)班',
          subText: '38人',
          value: 110
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(11)班',
          subText: '38人',
          value: 111
        },
        {
          src: '/static/images/basic/color.png',
          text: '高一(12)班',
          subText: '38人',
          value: 112
        }
      ];
      this.setData({
        itemList
      })
    },
   change(e) {
        console.log(e.detail);
        /**
         *   layer: 0  第几级 index
           src: '/static/images/basic/color.png'
           subIndex: 2   //当前层级下选中项index
           subText: '30人'  //选中项数据
           text: '高一(3)班'
           value: 103 //选中项value数据
         * */
    
        // 模拟请求
        let value = e.detail.value;
        let layer = e.detail.layer;
        if (layer === 7) {
          //实际中以请求数据为准,无下级数据则传空数组
          this.setData({
            receiveData: []
          })
        } else {
          wx.showLoading({
            title: '请稍候...'
          });
          setTimeout(() => {
            wx.hideLoading();
            //请求完成后将数据处理成以下格式,传入,最后一级没有则传空数组
            switch (layer) {
              case 0:
                let receiveData = [{
                    text: '张三',
                    subText: '男',
                    value: 11101
                  },
                  {
                    text: '王五',
                    subText: '男',
                    value: 11102
                  },
                  {
                    text: '周小小',
                    subText: '女',
                    value: 11103
                  },
                  {
                    text: '周小小',
                    subText: '女',
                    value: 11103
                  },
                  {
                    text: '周小小',
                    subText: '女',
                    value: 11103
                  }
                ];
                this.setData({
                  receiveData: receiveData
                })
                break;
              case 1:
                this.setData({
                  receiveData: [{
                    text: '他(她)说',
                    value: 11101
                  }]
                })
                break;
              case 2:
                this.setData({
                  receiveData: [{
                    text: '这是一个',
                    value: 11101
                  }]
                })
                break;
              case 3:
                this.setData({
                  receiveData: [{
                    text: '级联选择器',
                    value: 11101
                  }]
                })
                break;
              case 4:
                this.setData({
                  receiveData: [{
                    text: '测试例子',
                    value: 11101
                  }]
                })
                break;
              case 5:
                this.setData({
                  receiveData: [{
                    text: '总共',
                    value: 11101
                  }]
                })
                break;
              case 6:
                this.setData({
                  receiveData: [{
                    text: '8级数据',
                    value: 11101
                  }]
                })
                break;
              default:
                break;
            }
          }, 800);
        }
      },
      complete(e) {
        console.log(e.detail);
        console.log('您选择的数据为:' + e.detail.text);
      }
})
// Make sure to add code blocks to your code group
# Slots
| 插槽名称 | 插槽说明 | 
|---|---|
| - | - | 
# Props
| 属性名 | 类型 | 说明 | 默认值 | 
|---|---|---|---|
| itemList | Array | 级联数据, 如果下一级是请求返回,则为第一级数据,否则为所有数据 | [ ] | 
| srcField V3.0.0+ | String | 级联数据图标地址key | src | 
| textField V3.0.0+ | String | 级联数据主文本key | text | 
| subTextField V3.0.0+ | String | 级联数据副文本key | subText | 
| valueField V3.0.0+ | String | 级联数据value值 key | value | 
| childrenField V3.0.0+ | String | 级联数据子级数据 key | children | 
| defaultItemList | Array | 初始化默认选中数据,当一次性传入所有数据时,默认值可为字符串数组,如:['安徽省','阜阳市','颍上县'] | [ ] | 
| defaultKey V1.7.2+ | String | 默认值字段key,可传值:text,value,仅当一次性传入所有数据时有效 | text | 
| headerLine | Boolean | 是否显示header底部细线 | true | 
| headerBgColor | String | header背景颜色 | #FFFFFF | 
| tabsHeight | String | 顶部标签栏高度 | 88rpx | 
| text | String | 默认显示文字 | 请选择 | 
| size | Number | tabs 文字大小 | 28 | 
| color | String | tabs 文字颜色 | #555 | 
| activeColor | String | 选中颜色 | #5677fc | 
| bold | Boolean | 选中后文字加粗 | true | 
| showLine | Boolean | 选中后是否显示底部线条 | true | 
| lineColor | String | 线条颜色 | #5677fc | 
| checkMarkSize | Number | icon 大小 | 15 | 
| checkMarkColor | String | icon 颜色 | #5677fc | 
| imgWidth | String | item 图片宽度 | 40rpx | 
| imgHeight | String | item 图片高度 | 40rpx | 
| radius | String | 图片圆角 | 50% | 
| textColor | String | item text颜色 | #333 | 
| textActiveColor | String | item text选中后颜色 | #333 | 
| textBold | Boolean | 选中后字体是否加粗 | true | 
| textSize | Number | item text字体大小 | 28 | 
| nowrap | Boolean | text 是否不换行 | false | 
| subTextColor | String | item subText颜色 | #999 | 
| subTextSize | Number | item subText字体大小 | 24 | 
| padding | String | item padding | 20rpx 30rpx | 
| firstItemTop | String | 占位高度,第一条数据距离顶部距离 | 20rpx | 
| height | String | swiper 高度 | 300px | 
| backgroundColor | String | item swiper 内容部分背景颜色 | #FFFFFF | 
| request | Boolean | 子级数据是否请求返回(默认false,一次性返回所有数据) | false | 
| receiveData | Array | 子级数据(当有改变时,默认为当前选中项新增子级数据,request为true时生效) | [ ] | 
| reset | [Number, String] | 改变reset值则重置所有数据 | 0 | 
属性 receiveData 数据格式与 itemList中子集数据一致,数据为约定格式,尽量保持一致。
[{
    src: "", //图标地址,可使用属性 srcField 指定
    text: "",//主文本,可使用属性 textField 指定
    subText: "",//副文本,可使用属性 subTextField 指定
    value: 0, //value值,可使用属性 valueField 指定
    children:[{  //子级数据,可使用属性 childrenField 指定
  	  text: "",//主文本
  	  subText: "",//副文本
  	  value: 0,//value值
  	  children:[] //子级数据 如果数据长度为0则表示没有下一级数据了
     }] //子级数据
}]
数据为约定格式,尽量保持一致,当一次性传入所有数据时,默认值可为字符串数组。
[{
  	text: "", //选中的text,textField 指定的key
  	subText: '', //选中的subText,subTextField 指定的key
  	value: '', //选中的value,valueField 指定的key
  	src: '', //选中的src,没有则传空或不传,srcField 指定的key
  	index: 0, //选中数据在当前layer索引
  	list: [{
  		src: "",//图标地址,srcField 指定的key
  		text: "", //主文本,textField 指定的key
  		subText: "",//副文本,subTextField 指定的key
  		value: 101 //value值 ,valueField 指定的key
  	 }] //当前layer下所有数据集合
}]
# Events
注:uni-app端绑定事件使用@前缀,如@change;微信小程序原生使用bind前缀,如bindchange
| 事件名 | 说明 | 回调参数 | 
|---|---|---|
| change | 选择器中item项点击时触发 | 当前层级数据以及点击项的索引值 | 
| complete | 完成选择时触发 | 选择结果数据 | 
查看具体据结构可操作示例(请求返回子级),切换至控制台查看console打印信息。
layer 当前所属层级
subIndex 当前层级点击项索引值
subItem项 当前层级点击项所有数据,由父组件传入的数据
查看具体据结构可操作示例,切换至控制台查看console打印信息。
result 当前选择的结果
text 所有层级选择的text值拼接数据,text为 textField 指定的key,如:安徽省合肥市庐阳区
value 最后一级点击项的value值,value为 valueField 指定的 key
subText 最后一级点击项的text值,subText为 subTextField 指定的 key
src 最后一级点击项的src值,src为 srcField 指定的 key
# 预览
请以移动端效果为准,touch事件目前尚未在PC端做兼容。
# 特别说明
# 线上程序扫码预览
|  |  |  | 
|---|---|---|
| ThorUI组件库小程序码 | H5二维码 | ThorUI示例小程序码 | 
