暗黑模式
Cascader 级联选择器 1.0.9
手机扫码预览
23:59
组件名:rice-cascader
级联选择 用于多层级数据的选择。注:1.0.9版本开始支持
平台兼容性
uni-app x
Android | iOS | 鸿蒙Next | 微信小程序 | h5 |
---|---|---|---|---|
√ | √ | √ | √ | √ |
基础用法
- 通过
options
参数设置数据源,options
的数据格式为 CascaderOption; - 通过
v-model
绑定选中项的值; - 通过
v-model:show
控制Cascader
的显示与否(仅在usePopup
为true
的情况下生效);
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/show | boolean | 是否显示,usePopup 为 true 时生效 | false |
v-model/model-value | String|Number | 绑定的数据 | - |
options | CascaderOption[] | 可选项的数据 | [] |
title | String | 顶部栏标题 | - |
title-align | String | 标题对齐方式,可选值:center、left | center |
placeholder | String | 未选中时的提示文字 | 请选择 |
color | String | 选项文字颜色 | - |
active-color | String | 选中状态下的文字颜色 | - |
font-size | String|Number | 选项文字大小 | 16px |
closeable | Boolean | 是否显示关闭按钮 | true |
close-icon | String | 关闭按钮的图标 | cross |
border | Boolean | 选项是否显示下边框 | false |
use-popup | Boolean | 是否使用popup | true |
close-on-finish | Boolean | 全部选项选择完成后是否关闭popup,是否全部选择完成判断的条件是children 为null | true |
close-on-click-close | Boolean | 点击关闭按钮是否关闭popup | true |
close-on-click-overlay | Boolean | 点击遮罩层是否关闭popup | true |
safe-area-inset-bottom | Boolean | 是否开启底部安全区适配 | usePopup 为 true 时默认开启 |
z-index | Number | zIndex 层级 | 999 |
custom-style | Object | 自定义style | - |
CascaderOption 数据结构
键名 | 说明 | 类型 |
---|---|---|
text | 选项文字(必填) | String |
value | 选项对应的值(必填,且不能重复) | String|Number |
disabled | 是否禁用 | Boolean |
children | 子选择列表,为null或不传时表示没有下一级 | CascaderOption[] |
extend | 自定义扩展字段,可以在 change 和 finish 事件回调中获取 | any |
Events
事件名 | 说明 | 回调参数 |
---|---|---|
change | 选中项变化时触发 | (value:CascaderEvent) |
finish | 全部选项选择完成后触发,判断依据是children 为null 或不传 | (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)