Skip to content

Cascader 级联选择器 1.0.9

手机扫码预览
23:59

组件名:rice-cascader

级联选择 用于多层级数据的选择。注:1.0.9版本开始支持

平台兼容性

uni-app x

AndroidiOS鸿蒙Next微信小程序h5

基础用法

  • 通过 options 参数设置数据源, options 的数据格式为 CascaderOption;
  • 通过 v-model 绑定选中项的值;
  • 通过 v-model:show 控制 Cascader 的显示与否(仅在usePopuptrue的情况下生效);
html
<rice-cascader v-model="value" v-model:show="show" title="选择地区" :options="options"
 @change="onChange"
 @finish="onFinish"
 @clickDisabled="onClickDisabled"/>
ts
import { CascaderOption, CascaderEvent, CascaderClickDisabledEvent } from "@/uni_modules/rice-ui"
const show = ref(false)
const value = ref('')
const valueText = ref("")
const options = ref<CascaderOption[]>([
  {
    text: '浙江省',
    value: 'zhejiang',
    children: [
      { text: '杭州市', value: 'hangzhou', children: [{ text: '上城区', value: 'shangcheng' }, { text: '西湖区', value: 'xihua' }] },
      { text: '宁波市', value: 'ningbo', children: [{ text: '北仑', value: 'beilun' }] }
    ] as CascaderOption[],
  },
  {
    text: '江苏省',
    value: 'jiangsu',
    children: [{ text: '南京市', value: 'nanjing', children: [{ text: '玄武区', value: 'xuanwu' }, { text: '雨花台区', value: 'yuhuatai' }] }, { text: '苏州', value: 'sunzhou' }] as CascaderOption[],
  }, {
    text: '广西壮族自治区',
    value: 'guangxi',
    children: [{ text: '柳州市', value: 'liuzhou' }, { text: '桂林市', value: 'guiling', disabled: true }] as CascaderOption[],
  }])

const onChange = (e : CascaderEvent) => {
  console.log('onChange', e)
}

const onFinish = (e : CascaderEvent) => {
  console.log('onFinish', e)
  uni.showToast({
    title: `选择完成了-${e.value}`,
    icon: 'none'
  })
  valueText.value = e.selectedOptions.map(v => v.text).join('/')
}

const onClickDisabled = (e : CascaderClickDisabledEvent) => {
  console.log('onClickDisabled', e)
  uni.showToast({
    title: `点击了禁用项-${e.option.value}`,
    icon: 'none'
  })
}

默认选中

通过 v-model 双向绑定选中的value

html
<rice-cascader v-model="value2" v-model:show="show2" :options="options" title="默认选中"></rice-cascader>
<script setup>
  const value2=ref('xihua')
</script>

自定义颜色和大小

  • 通过 active-color 属性设置选中状态下的文字颜色
  • 通过 color 属性设置未选中状态下的文字颜色
  • 通过 font-size 属性设置文字的大小
html
<rice-cascader v-model:show="show3" :options="options"
 active-color="#07c160"
 :color="themeState.isDark?'#fff':'#000'"
 font-size="17px"
 title="自定义颜色" />

异步加载

可以监听 change 事件并动态设置 options数据源,实现异步加载选项。

注意

这种方式事先要把children设置为空数组才能实现,具体查看下方示例。
其实还有一种方式可以实现异步加载,就是把 close-on-finish 设为 false,再监听 finish 事件自行加载远程数据,这种方式children需要设置为null 或不传

html
<rice-cascader v-model:show="show4" :options="options2" title="异步加载"    
  @finish="onFinish4"
  @change="onChange4"></rice-cascader>
ts
const show4 = ref(false)
const options2 = ref<CascaderOption[]>([{
  text: '浙江省',
  value: 'zhejiang',
  children: [] as CascaderOption[], //如果需要异步加载下一项,children需要定义为空数组
},
{
  text: '江苏省',
  value: 'jiangsu',
  children: [] as CascaderOption[],
},
{
  text: '福建省',
  value: 'fujian',
  children: [] as CascaderOption[],
}, {
  text: '广西壮族自治区',
  value: 'guangxi',
}])
const onFinish4 = (e : CascaderEvent) => {
  uni.showToast({
    title: `选择完成了-${e.selectedOptions.map(v => v.text).join('/')}`,
    icon: 'none'
  })
}
const onChange4 = (e : CascaderEvent) => {
  uni.showLoading({
    title: '加载中…',
    mask: true,
  })
  setTimeout(() => {
    const value = e.selectedOptions[0].value
    if (value == 'zhejiang') {
      options2.value[0].children = [
        { text: '杭州市', value: 'hangzhou' },
      ] as CascaderOption[]
    } else if (value == 'jiangsu') {
      options2.value[1].children = [
        { text: '南京市', value: 'nanjing' }
      ] as CascaderOption[]
    } else if (value == 'fujian') {
      //假设请求完成后数据为空
      options2.value[2].children = null
      //使用nextTick是为了避免uni.hideLoading会导致onFinish4中的toast不显示,实际使用中不需要使用nextTick
      nextTick(() => {
        onFinish4(e)
      })
      show4.value = false
    }
    uni.hideLoading()
  }, 500)
}

中国省市区数据

很多时候我们拿到的数据格式不一定是CascaderOption 类型,那么就要手动转为 CascaderOption 类型了,因为uniappx是有严格的类型校验的。

html
<rice-cascader v-model="value" v-model:show="show5" title="省市区数据"
  :options="areaList"
  :placeholder="`请选择${getText(tabIndex5)}`"
  @change="onChange5"/>
ts
import { CascaderOption ,CascaderEvent} from "@/uni_modules/rice-ui"
let transformAreaData : ((list : AreaData[]) => CascaderOption[]) | null = null

transformAreaData = (list : AreaData[]) => {
  const result = list.map(item => {
    const children = item['children'] as AreaData[] | null
    return {
      value: item.code,
      text: item.name,
      extend: { code: item.code },
      children: (children != null && children.length > 0) ? transformAreaData!(children) : null
    } as CascaderOption
  })
  return result
}

// 假设area为后端返回的数据
areaList.value = [transformAreaData!(area!)] as CascaderOption[]

// 设置placeholder
const tabIndex5=ref(0)
const onChange5 = (e : CascaderEvent) => {
  tabIndex5.value = e.tabIndex + 1
}

const getText = (index : number) => {
  if (index == 0) return '省份'
  if (index == 1) return '城市'
  return '区县'
}

全部选择完成后不关闭

通过 close-on-finish 属性可以设置 选择完成后不关闭 popup,一般用于数据校验,可以通过optionsBottom 插槽自行控制关闭的时机,校验成功后再通过v-model:show绑定的值手动关闭。

html
<rice-cascader v-model:show="show6" :options="areaList" title="选择完成后不关闭" :close-on-finish="false"
  :close-on-click-overlay="false" close-icon="clear-fill" ref="cascaderRef">
  <template #optionsBottom="{tabIndex}">
    <view class="options-bottom">
      <rice-button type="primary" shape="round" :text="`选择完成-${getText(tabIndex)}`" @click="sure"></rice-button>
    </view>
  </template>
</rice-cascader>

<script setup>
const show6 = ref(false)
const valueText6 = ref("")
const cascaderRef = ref<RiceCascaderComponentPublicInstance | null>(null)
const sure = () => {
  const value = cascaderRef.value!.getSelectedOptions() as CascaderOption[]
  valueText6.value = value.map(v => v.text).join('/')
  show6.value = false
}
</script>

自定义选项上方内容

通过 optionsTop 插槽可以自定义选项上方内容

html
<rice-cascader v-model:show="show7" title="自定义选项上方内容" :options="areaList">
  <template #optionsTop="{tabIndex}">
    <text class="options-tip">请选择{{getText(tabIndex)}}</text>
  </template>
</rice-cascader>

不使用popup

use-popup 设置为 false 即可不依赖 popup,如果想要全页面展示,可以通过custom-style 设置 高度或者 flex:1

html
<rice-cascader v-model="value2" title="" :use-popup="false" :closeable="false" :options="options"/>

API

Props

属性名类型说明默认值
v-model:show/showboolean是否显示,usePopuptrue时生效false
v-model/model-valueString|Number绑定的数据-
optionsCascaderOption[]可选项的数据[]
titleString顶部栏标题-
title-alignString标题对齐方式,可选值:center、leftcenter
placeholderString未选中时的提示文字请选择
colorString选项文字颜色-
active-colorString选中状态下的文字颜色-
font-sizeString|Number选项文字大小16px
closeableBoolean是否显示关闭按钮true
close-iconString关闭按钮的图标cross
borderBoolean选项是否显示下边框false
use-popupBoolean是否使用popuptrue
close-on-finishBoolean全部选项选择完成后是否关闭popup,是否全部选择完成判断的条件是childrennulltrue
close-on-click-closeBoolean点击关闭按钮是否关闭popuptrue
close-on-click-overlayBoolean点击遮罩层是否关闭popuptrue
safe-area-inset-bottomBoolean是否开启底部安全区适配usePopuptrue 时默认开启
z-indexNumberzIndex 层级999
custom-styleObject自定义style-

CascaderOption 数据结构

键名说明类型
text选项文字(必填)String
value选项对应的值(必填,且不能重复)String|Number
disabled是否禁用Boolean
children子选择列表,为null或不传时表示没有下一级CascaderOption[]
extend自定义扩展字段,可以在 changefinish 事件回调中获取any

Events

事件名说明回调参数
change选中项变化时触发(value:CascaderEvent)
finish全部选项选择完成后触发,判断依据是childrennull 或不传(value:CascaderEvent)
clickDisabled点击禁用的选项时触发(value:CascaderClickDisabledEvent)
clickClose点击关闭图标时触发-
open打开时触发-
close关闭时触发-
opened打开动画结束时触发-
closed关闭动画结束时触发-

方法

通过 ref 可以获取到 Cascader 实例并且调用实例的方法

方法名说明返回值
getSelectedOptions获取当前选中项的集合CascaderOption[]

调用方法示例

ts
const cascaderRef = ref<RiceCascaderComponentPublicInstance | null>(null)
//需确保cascaderRef.value不为null的情况下才能使用 "!."
const value = cascaderRef.value!.getSelectedOptions() as CascaderOption[]

Slots 插槽

名称说明参数
optionsTop选项上方区域tabIndex : number
optionsBottom选项下方区域tabIndex : number

类型定义

组件导出如下类型

ts
//options的参数类型
type CascaderOption = {
	text : string,
	value : string | number,
	disabled ?: boolean,
	children ?: CascaderOption[], //子项,为null或不传时表示没有下一级
	extend ?: any | null,
}

//选中项变化/选择完成时的参数类型
type CascaderEvent = {
	value : string | number, //选项对应的值
	selectedOptions : CascaderOption[], //选中的选项集合
	tabIndex : number, // 当前tab的索引值
}

//点击禁用的选项时的参数类型 
type CascaderClickDisabledEvent = {
	option : CascaderOption, //当前点击的项
	tabIndex : number, //tab索引值
}

type CascaderTitleAlign = 'left' | 'center'

组件类型

ts
// 组件类型
const cascaderRef = ref<RiceCascaderComponentPublicInstance | null>(null)