Skip to content

Cascader 级联选择

介绍

级联选择器,用于多层级数据的选择,典型场景为省市区选择。

基础用法

传入 options 列表。

html
<template>
  <nut-cascader
    v-model:visible="visible"
    v-model="value"
    :options="options"
    title="地址选择"
    @change="onChange"
    @pathChange="onPathChange"
  ></nut-cascader>
</template>
ts
import type { CascaderOption, CascaderValue } from "nutui-uniapp";

const visible = ref(false);

const value = ref(["湖南"]);

const options = ref([
  {
    value: "浙江",
    text: "浙江",
    children: [
      {
        value: "杭州",
        text: "杭州",
        disabled: true,
        children: [
          { value: "西湖区", text: "西湖区" },
          { value: "余杭区", text: "余杭区" }
        ]
      },
      {
        value: "温州",
        text: "温州",
        children: [
          { value: "鹿城区", text: "鹿城区" },
          { value: "瓯海区", text: "瓯海区" }
        ]
      }
    ]
  },
  {
    value: "湖南",
    text: "湖南",
    disabled: true
  },
  {
    value: "福建",
    text: "福建",
    children: [
      {
        value: "福州",
        text: "福州",
        leaf: false,
        children: []
      },
      {
        value: "厦门",
        text: "厦门"
      }
    ]
  }
]);

function onChange(value: CascaderValue, nodes: CascaderOption[]) {
  console.log("change", value, nodes);
}

function onPathChange(nodes: CascaderOption[]) {
  console.log("path-change", nodes);
}

自定义属性名称

可通过 text-keyvalue-keychildren-key 指定属性名。

html
<template>
  <nut-cascader
    v-model:visible="visible"
    v-model="value"
    :options="options"
    text-key="text"
    value-key="text"
    children-key="items"
  ></nut-cascader>
</template>
ts
const options = ref([
  {
    text: "浙江",
    items: [
      {
        text: "杭州",
        disabled: true,
        items: [
          { text: "西湖区" },
          { text: "余杭区" }
        ]
      },
      {
        text: "温州",
        items: [
          { text: "鹿城区" },
          { text: "瓯海区" }
        ]
      }
    ]
  },
  {
    text: "福建",
    items: [
      {
        text: "福州",
        items: [
          { text: "鼓楼区" },
          { text: "台江区" }
        ]
      }
    ]
  }
]);

动态加载

使用 lazy 标识是否需要动态获取数据,此时不传 options 代表所有数据都需要通过 lazy-load 加载, 首次加载通过 root 属性区分,当遇到非叶子节点时会调用 lazy-load 方法,参数为当前节点和 resolve 方法, 注意 resolve 方法必须调用,不传子节点时会被当做叶子节点处理。

html
<template>
  <nut-cascader
    v-model:visible="visible"
    v-model="value"
    lazy
    :lazy-load="request"
  ></nut-cascader>
</template>
ts
const value = ref(["A0", "A12", "A23", "A32"]);

function request(node: any, resolve: (children: any) => void) {
  setTimeout(() => {
    // root表示第一层数据
    if (node.root) {
      resolve([
        { value: "A0", text: "A0" },
        { value: "B0", text: "B0" },
        { value: "C0", text: "C0" }
      ]);
    } else {
      const { value, level } = node;

      const text = value.substring(0, 1);
      const value1 = `${text}${level + 1}1`;
      const value2 = `${text}${level + 1}2`;
      const value3 = `${text}${level + 1}3`;

      resolve([
        { value: value1, text: value1, leaf: level >= 6 },
        { value: value2, text: value2, leaf: level >= 6 },
        { value: value3, text: value3, leaf: level >= 6 }
      ]);
    }
  }, 2000);
}

部分数据动态加载

html
<template>
  <nut-cascader
    v-model:visible="visible"
    v-model="value"
    :options="options"
    lazy
    :lazyLoad="request"
  ></nut-cascader>
</template>
ts
const options = ref([
  { value: "A0", text: "A0" },
  {
    value: "B0",
    text: "B0",
    children: [
      { value: "B11", text: "B11", leaf: true },
      { value: "B12", text: "B12" }
    ]
  },
  { value: "C0", text: "C0" }
]);

function request(node: any, resolve: (children: any) => void) {
  setTimeout(() => {
    const { value, level } = node;

    const text = value.substring(0, 1);
    const value1 = `${text}${level + 1}1`;
    const value2 = `${text}${level + 1}2`;

    resolve([
      { value: value1, text: value1, leaf: level >= 2 },
      { value: value2, text: value2, leaf: level >= 1 }
    ]);
  }, 500);
}

自动转换

如果你的数据为可转换为树形结构的扁平结构时,可以通过 convert-config 告诉组件需要进行自动转换, convert-config 接受 4 个参数,topId 为顶层节点的父级id,idKey 为节点唯一 id,pidKey 为指向父节点 id 的属性名, 存在 sortKey 将根据指定字段调用 Array.prototype.sort() 进行同层排序。

html
<template>
  <nut-cascader
    v-model:visible="visible"
    v-model="value"
    :options="options"
    :convert-config="convertConfig"
  ></nut-cascader>
</template>
ts
const value = ref(["广东省", "广州市"]);

const options = ref([
  { value: "北京", text: "北京", id: 1, pid: null },
  { value: "朝阳区", text: "朝阳区", id: 11, pid: 1 },
  { value: "亦庄", text: "亦庄", id: 111, pid: 11 },
  { value: "广东省", text: "广东省", id: 2, pid: null },
  { value: "广州市", text: "广州市", id: 21, pid: 2 }
]);

const convertConfig = {
  topId: null,
  idKey: "id",
  pidKey: "pid",
  sortKey: ""
};

API

Props

参数说明类型可选值默认值
v-model选中值,双向绑定Array--
v-model:visible显示选择层boolean-false
options级联数据Array-[]
lazy是否开启动态加载boolean-false
lazy-load动态加载回调,开启动态加载时生效Function--
value-key自定义 options 结构中 value 的字段string-value
text-key自定义 options 结构中 text 的字段string-text
children-key自定义 options 结构中 children 的字段string-children
convert-configoptions 为可转换为树形结构的扁平结构时,配置转换规则object--
poppable是否需要弹层展示boolean-true
title标题string--
title-type 1.1.7选中底部展示样式stringline / card / smileline
title-size 1.1.7标签栏字体尺寸大小stringlarge / normal / smallnormal
title-gutter 1.1.7标签间隙number / string-0
title-ellipsis 1.1.7是否省略过长的标题文字boolean-true
pop-style 1.8.0自定义弹窗样式CSSProperties--
lock-scroll H5背景是否锁定boolean-true

options 数据结构

参数说明类型默认值
text显示名称(可以通过 text-key 更改)string-
value唯一标识(可以通过 value-key 更改)number / string-
children子级选项(可以通过 children-key 更改)Array-
disabled是否禁用booleanfalse
leaf是否叶子节点(默认以 children 是否为空判断)boolean-
loading加载状态booleanfalse

Events

事件名说明类型
change选中值改变时触发(value: CascaderValue, nodes: CascaderOption[]) => void
path-change选中项改变时触发(nodes: CascaderOption[]) => void
open 1.8.0打开弹窗时触发() => void
opened 1.8.0打开弹窗动画结束时触发() => void
close 1.8.0关闭弹窗时触发() => void
closed 1.8.0关闭弹窗动画结束时触发() => void

Slots

名称说明
title 1.5.4自定义顶部标题部分

主题定制

样式变量

组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 ConfigProvider 组件

名称默认值
--nut-cascader-font-sizevar(--nut-font-size-2)
--nut-cascader-line-height22px
--nut-cascader-tabs-item-padding0 10px
--nut-cascader-bar-padding24px 20px 17px
--nut-cascader-bar-font-sizevar(--nut-font-size-4)
--nut-cascader-bar-line-height20px
--nut-cascader-bar-colorvar(--nut-title-color)
--nut-cascader-item-padding10px 20px
--nut-cascader-item-colorvar(--nut-title-color)
--nut-cascader-item-font-sizevar(--nut-font-size-2)
--nut-cascader-item-active-colorvar(--nut-primary-color)

MIT Licensed