介绍
用于在多层级数据中进行选择,常用于省市区、组织架构选择。
代码演示
基础使用
通过 v-model 绑定当前值,通过 options 配置选项数据。
vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:" :value="JSON.stringify(value) ?? 'undefined'" />
<s-list-item
title="设置为:440111 (广东省/广州市/白云区)"
arrow
hover
@click="value = 440111"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import { type CascaderOption } from 'sard'
const regionData = getRegionData()
const value = ref<number | undefined>(150102)
const onChange = (value: any, selectedOptions: CascaderOption[]) => {
console.log('change', value, selectedOptions)
}
</script>vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:" :value="JSON.stringify(value) ?? 'undefined'" />
<s-list-item
title="设置为:440111 (广东省/广州市/白云区)"
arrow
hover
@click="value = 440111"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import 'sard'
const regionData = getRegionData()
const value = ref(150102)
const onChange = (value, selectedOptions) => {
console.log('change', value, selectedOptions)
}
</script>选择即改变
设置 change-on-select 属性,允许只选中父级选项。
vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
change-on-select
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:" :value="JSON.stringify(value) ?? 'undefined'" />
<s-list-item
title="设置为:440111 (广东省/广州市/白云区)"
arrow
hover
@click="value = 440111"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import { type CascaderOption } from 'sard'
const regionData = getRegionData()
const value = ref<number | undefined>(150102)
const onChange = (value: any, selectedOptions: CascaderOption[]) => {
console.log('change', value, selectedOptions)
}
</script>vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
change-on-select
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:" :value="JSON.stringify(value) ?? 'undefined'" />
<s-list-item
title="设置为:440111 (广东省/广州市/白云区)"
arrow
hover
@click="value = 440111"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import 'sard'
const regionData = getRegionData()
const value = ref(150102)
const onChange = (value, selectedOptions) => {
console.log('change', value, selectedOptions)
}
</script>懒加载
设置 lazy 属性标识为懒加载,设置 load 属性用于获取数据,会在点击节点时调用,当获取的数据为空时,会将点击的节点标识为叶子节点。当然,你也可以提前设置节点是否为叶子节点,以避免为叶子节点时还要请求一次接口。
首次加载失败可点击提示重新加载,“无数据”状态也可点击重新加载;点击节点加载失败回退到 idle 状态,可再次点击进行加载。
vue
<template>
<s-list card>
<s-list-item>
<s-cascader
lazy
:load="loadNode"
:field-keys="{ label: 'name', value: 'code', isLeaf: 'isLeaf' }"
@change="onChange"
/>
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { mapProvinces, mapCities, mapCounties } from 'region-data'
import { type CascaderOption, type CascaderStateNode } from 'sard'
let requestTime = 0
const doGetTreeData = (parentId?: number) => {
requestTime++
if (requestTime === 1) throw new Error()
if (requestTime === 2) return []
if (!parentId) {
return Object.entries(mapProvinces).map(([code, name]) => ({
code: +code,
name,
isLeaf: false,
}))
} else {
const isProvince = /^\d{2}0{4}/.test(String(parentId))
const isCity = !isProvince && /^\d{4}0{2}/.test(String(parentId))
const prefixCode = isProvince
? String(parentId).slice(0, 2)
: isCity
? String(parentId).slice(0, 4)
: ''
const map = isProvince ? mapCities : isCity ? mapCounties : {}
return Object.entries(map)
.filter(([code]) => String(code).startsWith(prefixCode))
.map(([code, name]) => ({
code: +code,
name,
isLeaf: isCity,
}))
}
}
const getTreeData = (parentId?: number) => {
return new Promise<ReturnType<typeof doGetTreeData>>((resolve, reject) => {
setTimeout(() => {
try {
const treeData = doGetTreeData(parentId)
resolve(treeData)
} catch {
reject()
}
}, 500)
})
}
const loadNode = async (node?: CascaderStateNode) => {
return await getTreeData(node?.key as number)
}
const onChange = (value: any, selectedOptions: CascaderOption[]) => {
console.log('change', value, selectedOptions)
}
</script>vue
<template>
<s-list card>
<s-list-item>
<s-cascader
lazy
:load="loadNode"
:field-keys="{ label: 'name', value: 'code', isLeaf: 'isLeaf' }"
@change="onChange"
/>
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { mapProvinces, mapCities, mapCounties } from 'region-data'
import 'sard'
let requestTime = 0
const doGetTreeData = (parentId) => {
requestTime++
if (requestTime === 1) throw new Error()
if (requestTime === 2) return []
if (!parentId) {
return Object.entries(mapProvinces).map(([code, name]) => ({
code: +code,
name,
isLeaf: false,
}))
} else {
const isProvince = /^\d{2}0{4}/.test(String(parentId))
const isCity = !isProvince && /^\d{4}0{2}/.test(String(parentId))
const prefixCode = isProvince
? String(parentId).slice(0, 2)
: isCity
? String(parentId).slice(0, 4)
: ''
const map = isProvince ? mapCities : isCity ? mapCounties : {}
return Object.entries(map)
.filter(([code]) => String(code).startsWith(prefixCode))
.map(([code, name]) => ({
code: +code,
name,
isLeaf: isCity,
}))
}
}
const getTreeData = (parentId) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
try {
const treeData = doGetTreeData(parentId)
resolve(treeData)
} catch {
reject()
}
}, 500)
})
}
const loadNode = async (node) => {
return await getTreeData(node?.key)
}
const onChange = (value, selectedOptions) => {
console.log('change', value, selectedOptions)
}
</script>自定义面板上方内容
使用 top 插槽可以在面板顶部展示当前面板的一些信息。
vue
<template>
<s-list card>
<s-list-item>
<s-cascader
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
@update:modelValue="onChange"
>
<template #top="{ tabIndex }">
<div
:style="{
padding: '8px 16px',
backgroundColor: 'rgba(var(--s-color-primary-rgb), 0.1)',
color: 'var(--s-color-primary)',
}"
>
当前为第{{ tabIndex + 1 }}级
</div>
</template>
</s-cascader>
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { getRegionData, type Node } from 'region-data'
import { toast } from 'sard'
const regionData = getRegionData()
const onChange = (_: any, selectedOptions: Node[]) => {
toast(selectedOptions.map((option) => option.name).join('/'))
}
</script>vue
<template>
<s-list card>
<s-list-item>
<s-cascader
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
@update:modelValue="onChange"
>
<template #top="{ tabIndex }">
<div
:style="{
padding: '8px 16px',
backgroundColor: 'rgba(var(--s-color-primary-rgb), 0.1)',
color: 'var(--s-color-primary)',
}"
>
当前为第{{ tabIndex + 1 }}级
</div>
</template>
</s-cascader>
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { getRegionData } from 'region-data'
import { toast } from 'sard'
const regionData = getRegionData()
const onChange = (_, selectedOptions) => {
toast(selectedOptions.map((option) => option.name).join('/'))
}
</script>禁选选项
禁用的选项不可点击。
vue
<template>
<s-list card>
<s-list-item>
<s-cascader :options="options" @update:modelValue="onChange" />
</s-list-item>
</s-list>
</template>
<script setup lang="ts">
import { toast } from 'sard'
interface Option {
label: string
value: string
disabled: boolean
children?: Option[]
}
const options: Option[] = Array(10)
.fill(0)
.map((_, i) => {
return {
label: `label${i}`,
value: `${i}`,
disabled: i < 3,
children: Array(10)
.fill(0)
.map((_, j) => {
return {
label: `label${i}-label${j}`,
value: `${i}-${j}`,
disabled: j < 3,
}
}),
}
})
const onChange = (_: any, selectedOptions: Option[]) => {
toast(selectedOptions.map((option) => option.label).join('/'))
}
</script>vue
<template>
<s-list card>
<s-list-item>
<s-cascader :options="options" @update:modelValue="onChange" />
</s-list-item>
</s-list>
</template>
<script setup lang="js">
import { toast } from 'sard'
const options = Array(10)
.fill(0)
.map((_, i) => {
return {
label: `label${i}`,
value: `${i}`,
disabled: i < 3,
children: Array(10)
.fill(0)
.map((_, j) => {
return {
label: `label${i}-label${j}`,
value: `${i}-${j}`,
disabled: j < 3,
}
}),
}
})
const onChange = (_, selectedOptions) => {
toast(selectedOptions.map((option) => option.label).join('/'))
}
</script>绑定所有级别的值
如果要绑定所有级别的值,即绑定数组值,而不单单是最后一级,可以使用 all-levels 属性。
vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
all-levels
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:" :value="JSON.stringify(value) ?? 'undefined'" />
<s-list-item
title="设置为:440111 (广东省/广州市/白云区)"
arrow
hover
@click="value = [440000, 440100, 440111]"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import { type CascaderOption } from 'sard'
const regionData = getRegionData()
const value = ref<number[] | undefined>([440000, 440100, 440111])
const onChange = (value: any, selectedOptions: CascaderOption[]) => {
console.log('change', value, selectedOptions)
}
</script>vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
all-levels
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:" :value="JSON.stringify(value) ?? 'undefined'" />
<s-list-item
title="设置为:440111 (广东省/广州市/白云区)"
arrow
hover
@click="value = [440000, 440100, 440111]"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import 'sard'
const regionData = getRegionData()
const value = ref([44e4, 440100, 440111])
const onChange = (value, selectedOptions) => {
console.log('change', value, selectedOptions)
}
</script>多选
设置 multiple 属性可在每个选项前面显示复选框,点击复选框可选择多个;如果是最后一级,点击选项也可以选中复选框。
vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
multiple
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:">
<template #value>
<div class="line-clamp-3">
{{ JSON.stringify(value) ?? 'undefined' }}
</div>
</template>
</s-list-item>
<s-list-item
title="设置为:[440106, 440111] ([天河区, 白云区])"
arrow
hover
@click="value = [440106, 440111]"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import { type CascaderOption, type CascaderValue } from 'sard'
const regionData = getRegionData()
const value = ref<CascaderValue | undefined>([440106, 440111])
const onChange = (value: any, selectedOptions: CascaderOption[]) => {
console.log('change', value, selectedOptions)
}
</script>vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
multiple
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:">
<template #value>
<div class="line-clamp-3">
{{ JSON.stringify(value) ?? 'undefined' }}
</div>
</template>
</s-list-item>
<s-list-item
title="设置为:[440106, 440111] ([天河区, 白云区])"
arrow
hover
@click="value = [440106, 440111]"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import 'sard'
const regionData = getRegionData()
const value = ref([440106, 440111])
const onChange = (value, selectedOptions) => {
console.log('change', value, selectedOptions)
}
</script>多选-绑定所有级别的值
all-levels 属性也可以作用于多选,当设置此属性,绑定的值会是一个二维数组。
vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
multiple
all-levels
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:">
<template #value>
<div class="line-clamp-3">
{{ JSON.stringify(value) ?? 'undefined' }}
</div>
</template>
</s-list-item>
<s-list-item
title="设置为:[[440000, 440100, 440106], [440000, 440100, 440111]] ([天河区, 白云区])"
arrow
hover
@click="
value = [
[440000, 440100, 440106],
[440000, 440100, 440111],
]
"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import { type CascaderOption, type CascaderValue } from 'sard'
const regionData = getRegionData()
const value = ref<CascaderValue | undefined>([
[440000, 440100, 440106],
[440000, 440100, 440111],
])
const onChange = (value: any, selectedOptions: CascaderOption[]) => {
console.log('change', value, selectedOptions)
}
</script>vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
multiple
all-levels
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:">
<template #value>
<div class="line-clamp-3">
{{ JSON.stringify(value) ?? 'undefined' }}
</div>
</template>
</s-list-item>
<s-list-item
title="设置为:[[440000, 440100, 440106], [440000, 440100, 440111]] ([天河区, 白云区])"
arrow
hover
@click="
value = [
[440000, 440100, 440106],
[440000, 440100, 440111],
]
"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import 'sard'
const regionData = getRegionData()
const value = ref([
[44e4, 440100, 440106],
[44e4, 440100, 440111],
])
const onChange = (value, selectedOptions) => {
console.log('change', value, selectedOptions)
}
</script>多选-选择任意级别
在单选模式下,你只能选择叶子节点;而在多选模式下,勾选父节点真正选中的都是叶子节点。 启用该功能后,可让父子节点取消关联,选择任意一级选项。
可通过设置 check-strictly 来取消父子节点选中关联,从而达到选择任意一级选项的目的。
vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
multiple
check-strictly
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:">
<template #value>
<div class="line-clamp-3">
{{ JSON.stringify(value) ?? 'undefined' }}
</div>
</template>
</s-list-item>
<s-list-item
title="设置为:[440106, 440111] ([天河区, 白云区])"
arrow
hover
@click="value = [440106, 440111]"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import { type CascaderOption, type CascaderValue } from 'sard'
const regionData = getRegionData()
const value = ref<CascaderValue | undefined>([440106, 440111])
const onChange = (value: any, selectedOptions: CascaderOption[]) => {
console.log('change', value, selectedOptions)
}
</script>vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
multiple
check-strictly
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:">
<template #value>
<div class="line-clamp-3">
{{ JSON.stringify(value) ?? 'undefined' }}
</div>
</template>
</s-list-item>
<s-list-item
title="设置为:[440106, 440111] ([天河区, 白云区])"
arrow
hover
@click="value = [440106, 440111]"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import 'sard'
const regionData = getRegionData()
const value = ref([440106, 440111])
const onChange = (value, selectedOptions) => {
console.log('change', value, selectedOptions)
}
</script>多选-选择任意级别-绑定所有级别
下面综合演示多选的使用。
vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
multiple
all-levels
check-strictly
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:">
<template #value>
<div class="line-clamp-3">
{{ JSON.stringify(value) ?? 'undefined' }}
</div>
</template>
</s-list-item>
<s-list-item
title="设置为:[[440000, 440100, 440106], [440000, 440100, 440111]] ([天河区, 白云区])"
arrow
hover
@click="
value = [
[440000, 440100, 440106],
[440000, 440100, 440111],
]
"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import { type CascaderOption, type CascaderValue } from 'sard'
const regionData = getRegionData()
const value = ref<CascaderValue | undefined>([
[440000, 440100, 440106],
[440000, 440100, 440111],
])
const onChange = (value: any, selectedOptions: CascaderOption[]) => {
console.log('change', value, selectedOptions)
}
</script>vue
<template>
<s-list card>
<s-list-item>
<s-cascader
v-model="value"
:options="regionData"
:field-keys="{ label: 'name', value: 'code' }"
multiple
all-levels
check-strictly
@change="onChange"
/>
</s-list-item>
<s-list-item title="当前值:">
<template #value>
<div class="line-clamp-3">
{{ JSON.stringify(value) ?? 'undefined' }}
</div>
</template>
</s-list-item>
<s-list-item
title="设置为:[[440000, 440100, 440106], [440000, 440100, 440111]] ([天河区, 白云区])"
arrow
hover
@click="
value = [
[440000, 440100, 440106],
[440000, 440100, 440111],
]
"
/>
<s-list-item title="清空" arrow hover @click="value = undefined" />
</s-list>
</template>
<script setup lang="js">
import { ref } from 'vue'
import { getRegionData } from 'region-data'
import 'sard'
const regionData = getRegionData()
const value = ref([
[44e4, 440100, 440106],
[44e4, 440100, 440111],
])
const onChange = (value, selectedOptions) => {
console.log('change', value, selectedOptions)
}
</script>API
CascaderProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| model-value | 选中项的值 | CascaderValue | - |
| options | 可选项数据源 | CascaderOption[] | [] |
| field-keys | 自定义 options 中的字段 | OptionKeys | defaultOptionKeys |
| option-keys | 自定义 options 中的字段,同 field-keys | OptionKeys | defaultOptionKeys |
| hint-text | 未选中时的提示文案 | string | '请选择' |
| label-render | 自定义可选项渲染 | (option: CascaderOption) => string | - |
| change-on-select | 点击每级选项都会触发变化 | boolean | false |
| all-levels | 是否绑定所有级别的值,而不单单是最后一级 | boolean | false |
| multiple | 是否多选 | boolean | false |
| check-strictly | 是否严格的遵守父子节点不互相关联(用于多选) | boolean | false |
| lazy | 是否懒加载子节点,需与 load 方法结合使用 | boolean | false |
| load | 加载子节点的方法,仅当 lazy 属性为true 时生效 | (node?: CascaderStateNode) => Promise<CascaderOption[]> | CascaderOption[] | - |
CascaderSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| top | 自定义面板上方内容 | { tabIndex: number } |
CascaderEmits
| 事件 | 描述 | 类型 |
|---|---|---|
| update:modelValue | 全部选项选择完成后触发 | (value: CascaderValue, selectedOptions: CascaderOption[]) => void |
| change | 全部选项选择完成后触发 | (value: CascaderValue, selectedOptions: CascaderOption[]) => void |
| select | 选中某一项时触发 | (option: CascaderOption, tabIndex: number) => void |
CascaderValue
ts
type CascaderValue = string | number | (string | number)[] | (string | number)[][]CascaderOption
ts
interface CascaderOption {
label?: string
value?: string | number
disabled?: boolean
children?: CascaderOption[]
isLeaf?: boolean
[key: PropertyKey]: any
}OptionKeys
ts
interface OptionKeys {
label?: string
value?: string
disabled?: string
children?: string
isLeaf?: string
}defaultOptionKeys
ts
const defaultOptionKeys: OptionKeys = {
label: 'label',
value: 'value',
disabled: 'disabled',
children: 'children',
isLeaf: 'isLeaf',
}js
const defaultOptionKeys = {
label: 'label',
value: 'value',
disabled: 'disabled',
children: 'children',
isLeaf: 'isLeaf',
}CascaderStateNode
ts
interface CascaderStateNode {
label: string
value: string | number
key: string | number
disabled: boolean
children?: CascaderStateNode[]
parent: CascaderStateNode | null
isLeaf: boolean
loadStatus: 'idle' | 'loading' | 'loaded'
depth: number
indeterminate: boolean
checked: boolean
selected: boolean
option: CascaderOption
}主题定制
样式变量
| CSS 变量 | 值 |
|---|---|
--s-cascader-wrapper-duration | var(--s-duration) |
--s-cascader-options-height | 320px |
--s-cascader-option-min-height | var(--s-content-height-sm) |
--s-cascader-option-padding-y | var(--s-content-padding-y) |
--s-cascader-option-padding-x | var(--s-content-padding-x) |
--s-cascader-option-color-selected | var(--s-color-primary) |
--s-cascader-option-font-weight-selected | var(--s-font-weight-bold) |
--s-cascader-option-bg-active | var(--s-bg-color-active) |
--s-cascader-option-loading-margin-end | var(--s-size-xs) |
--s-cascader-option-loading-font-size | var(--s-font-size) |
--s-cascader-option-loading-color | var(--s-text-color-fourth) |
--s-cascader-option-label-font-size | var(--s-font-size) |
--s-cascader-option-label-line-height | var(--s-line-height-relaxed) |
--s-cascader-status-font-size | var(--s-font-size) |
--s-cascader-status-color | var(--s-text-color-fourth) |
--s-cascader-loading-font-size | var(--s-font-size-xl) |