Skip to content

Cascader ​

概述 ​

Cascader级联选择器,用于录入具有层级关系的数据,例如省市区、公司层级、事物分类等。数据支持树形嵌套与平铺索引两种结构,也支持在节点第一次展开时才加载子节点的懒加载模式,选中值按层级自动拼接。

示例 ​

声明一个级联字段只需要指定widget: 'cascader'并通过choices提供树形数据:

ts
const form = document.querySelector('#form');
form.state = {
    car: configurable('', {
        label: '车型',
        widget: 'cascader',
        placeholder: '选择车型',
        choices: {
            label: '汽车',
            id: '0',
            children: [
                {
                    label: '乘用车',
                    id: '1',
                    children: [
                        { label: '轿车', id: '1-1' },
                        { label: 'SUV', id: '1-2' },
                    ],
                },
            ],
        },
    }),
};
loading

指南 ​

数据格式 ​

choices为级联选择器提供数据,支持树形结构和扁平结构两种格式:

ts
// 每个节点至少包含 id、label、children? 三个属性,children 嵌套子节点
const cars = {
    id: '0',
    label: '汽车',
    children: [
        {
            id: '1',
            label: '乘用车',
            children: [
                {
                    id: '1-1',
                    label: '轿车',
                    children: [
                        { id: '1-1-1', label: '紧凑型轿车' },
                        { id: '1-1-2', label: '中型轿车' },
                        { id: '1-1-3', label: '豪华轿车' },
                    ],
                },
                {
                    id: '1-2',
                    label: 'SUV',
                    children: [
                        { id: '1-2-1', label: '小型SUV' },
                        { id: '1-2-2', label: '中型SUV' },
                    ],
                },
            ],
        },
    ],
};
form.state = {
    car: configurable('', {
        label: '车型',
        widget: 'cascader',
        choices: cars,
    }),
};
ts
// 以父节点 id 为键组织同级列表,配合 rootKey 指定第一级数据的来源
const cars = {
    0: [
        { id: '1', label: '乘用车' },
        { id: '2', label: '商用车' },
    ],
    1: [
        { id: '1-1', label: '轿车' },
        { id: '1-2', label: 'SUV' },
    ],
    2: [
        { id: '2-1', label: '客车' },
        { id: '2-2', label: '货车' },
    ],
    '1-1': [
        { id: '1-1-1', label: '紧凑型轿车' },
        { id: '1-1-2', label: '中型轿车' },
    ],
};
form.state = {
    car: configurable('', {
        label: '车型',
        widget: 'cascader',
        choices: cars,
        rootKey: '0', 
    }),
};
loading

choices也可以是一个返回数据的函数或异步函数(返回Promise),适合从远程接口获取选项的场景。

定制数据键名 ​

通过idKey、labelKey、valueKey、childrenKey可以定制数据键名,以适配任意后端数据结构:

参数 类型 默认值 说明
idKey string id 数据项的唯一标识
labelKey string label 数据项的显示文本
valueKey string <idKey> 数据项的取值,用于提交
childrenKey string children 数据项的子节点
rootKey string $root 根节点的标识,扁平结构时指定

例如行政区划数据使用name/code作为键名:

ts
form.state = {
    address: configurable('', {
        label: '地址',
        widget: 'cascader',
        choices: data,
        idKey: 'c', 
        labelKey: 'n', 
        valueKey: 'n', 
    }),
};

层级限制 ​

maxLevel用于限制最大级联层级,默认为3。数据实际深度浅于maxLevel的分支在选中叶子后即结束,后续列不再展开:

ts
form.state = {
    address: configurable('', {
        label: '乡镇',
        widget: 'cascader',
        maxLevel: 4, // 省/市/区/乡镇 四级
    }),
};

值与分隔符 ​

级联值的形态由字段初值决定:初值为字符串时,各级取值按delimiter连接成一个字符串;初值为数组时,输出各级取值组成的数组。

ts
form.state = {
    // 字符串值:选中后为 "乘用车/轿车/中型轿车"
    car: configurable('', {
        label: '车型',
        widget: 'cascader',
        choices: cars,
        valueKey: 'label',
        delimiter: '/', 
    }),
    // 数组值:选中后为 ['乘用车', '轿车']
    car2: configurable(['乘用车', '轿车'], {
        label: '车型',
        widget: 'cascader',
        choices: cars,
        valueKey: 'label',
    }),
};

delimiter默认为''。另外,dropdown用于指定是否显示为下拉框,默认为true;为false时多级列表内联平铺展示。

懒加载 ​

指定onLoad加载函数,并在choices数据中为节点声明lazy: true,即可在第一次展开该节点时才加载子节点:

ts
form.state = {
    car: configurable('', {
        label: '车型',
        widget: 'cascader',
        choices: {
            id: '0',
            label: '汽车',
            children: [
                { id: '1', label: '乘用车', lazy: true }, 
                { id: '2', label: '商用车', lazy: true }, 
            ],
        },
        onLoad: async (id) => { 
            // 入参为当前节点 id,返回其子节点数组
            await new Promise((resolve) => setTimeout(resolve, 1000)); 
            if (id === '1') { 
                return [ 
                    { id: '1-1', label: '轿车' }, 
                    { id: '1-2', label: 'SUV' }, 
                ]; 
            } 
            return []; 
        }, 
    }),
};

onLoad返回的子节点还可以携带children,一次返回多级子树;其叶子节点同样可以声明lazy: true供下一级按需加载。加载失败时节点回到待加载状态,可再次展开重试。

loading

行政区划联动 ​

级联选择器非常适合省市区联动场景,配合maxLevel与rootKey可以控制显示级别与起始范围:

  • 显示级别=3
loading
  • 显示级别=4
loading
  • 显示级别=4,指定根节点,仅显示福建省
loading

提示

行政区划数据:

属性 ​

属性 类型 默认值 说明
choices object / array / function {} 候选项数据:树形、平铺或其异步提供者
idKey string "id" 节点唯一标识字段名
rootKey string "$root" 根节点标识,扁平结构时指定第一级来源
labelKey string "label" 节点显示文本字段名
valueKey string <idKey> 节点取值字段名,默认跟随idKey
childrenKey string "children" 子节点字段名
maxLevel number 3 最大级联层级
delimiter string "" 字符串值中各级取值的连接符
onLoad function 懒加载函数:入参为节点id,返回子节点数组
dropdown boolean true 是否显示为下拉框

注意事项 ​

  • 候选项数据键名为choices,旧的select配置键已废弃。
  • 扁平结构必须通过rootKey指定第一级数据的来源键,否则无法渲染。
  • 懒加载需要同时满足两个条件:节点声明lazy: true且字段配置了onLoad。
  • 数据量较大时建议使用扁平结构或懒加载,避免一次性构造深层嵌套树。