使用场景 ​
从静态层级 options 选择节点。规范化节点保留 raw 和 children,以逐级菜单展示路径。ASAM 值模式返回节点值而非整条路径;需要原始模型时显式 native。
层级选择与自定义节点 ​
value/object 模式的 default 插槽收到 data、node 和对应规范化 option;native 模式原样传递原生 data、node。filterable 提供本地筛选。高级模式清空单选回到 null,native 模式保留原生清空值。
层级选择与自定义节点
<template>
<div class="example">
<AsamCascader
ref="control"
v-bind="{ filterable: true, clearable: true, 'aria-label': '选择团队' }"
v-model="value"
:options="options"
@change="event = JSON.stringify($event)"
>
<template #default="{ data }"> {{ data.label }}节点 </template>
<template #empty> 没有可选节点 </template>
</AsamCascader>
<AsamButton type="default" @click="control?.focus()"> 聚焦 </AsamButton>
<output>值:{{ value }};事件:{{ event }}</output>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamCascaderBasicExample' });
import { ref } from 'vue';
import { AsamCascader, AsamButton } from '@asam-ui/ui';
import type { AsamCascaderExpose } from '@asam-ui/ui';
const control = ref<AsamCascaderExpose>();
const options = [
{
label: '团队',
value: 'team',
raw: {},
children: [
{ label: '设计', value: 'design', raw: {} },
{ label: '开发', value: 'dev', raw: {} }
]
}
];
const value = ref<string | null>('design');
const event = ref('尚未更改');
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
<template>
<div class="example">
<AsamCascader
ref="control"
v-bind="{ filterable: true, clearable: true, 'aria-label': '选择团队' }"
v-model="value"
:options="options"
@change="event = JSON.stringify($event)"
>
<template #default="{ data }"> {{ data.label }}节点 </template>
<template #empty> 没有可选节点 </template>
</AsamCascader>
<AsamButton type="default" @click="control?.focus()"> 聚焦 </AsamButton>
<output>值:{{ value }};事件:{{ event }}</output>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamCascaderBasicExample' });
import { ref } from 'vue';
import { AsamCascader, AsamButton } from '@asam-ui/ui';
const control = ref();
const options = [
{
label: '团队',
value: 'team',
raw: {},
children: [
{ label: '设计', value: 'design', raw: {} },
{ label: '开发', value: 'dev', raw: {} }
]
}
];
const value = ref('design');
const event = ref('尚未更改');
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
多选与对象值 ​
multiple + valueMode=object 返回规范化节点数组。字符串存储只用于 value 模式,separator 不得与节点值冲突;所有节点值保持唯一。
多选与对象值
<template>
<div class="example">
<AsamCascader
v-model="objectValue"
:options="options"
v-bind="{ multiple: true, 'value-mode': 'object' }"
/>
<AsamCascader
v-model="stringValue"
:options="options"
v-bind="{ multiple: true, 'multiple-value-mode': 'string', separator: '|' }"
/>
<output>对象:{{ objectValue }};字符串:{{ stringValue }}</output>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamCascaderPoliciesExample' });
import { ref } from 'vue';
import { AsamCascader } from '@asam-ui/ui';
import type { AsamHierarchyOption } from '@asam-ui/ui';
const options = [
{
label: '团队',
value: 'team',
raw: {},
children: [
{ label: '设计', value: 'design', raw: {} },
{ label: '开发', value: 'dev', raw: {} }
]
}
];
const objectValue = ref<AsamHierarchyOption[]>([]);
const stringValue = ref('design');
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
<template>
<div class="example">
<AsamCascader
v-model="objectValue"
:options="options"
v-bind="{ multiple: true, 'value-mode': 'object' }"
/>
<AsamCascader
v-model="stringValue"
:options="options"
v-bind="{ multiple: true, 'multiple-value-mode': 'string', separator: '|' }"
/>
<output>对象:{{ objectValue }};字符串:{{ stringValue }}</output>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamCascaderPoliciesExample' });
import { ref } from 'vue';
import { AsamCascader } from '@asam-ui/ui';
const options = [
{
label: '团队',
value: 'team',
raw: {},
children: [
{ label: '设计', value: 'design', raw: {} },
{ label: '开发', value: 'dev', raw: {} }
]
}
];
const objectValue = ref([]);
const stringValue = ref('design');
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
原始节点字段与实例 ​
native 使用原始 options;props.emitPath=true 保存路径数组。getCheckedNodes 可读取已选节点;CascaderPanel 是独立常驻面板。
原始节点字段与实例
<template>
<div class="example">
<AsamCascader
ref="control"
v-bind="{
...{ 'value-mode': 'native' },
...{
options: nodes,
props: { value: 'id', label: 'name', children: 'nodes', emitPath: true }
}
}"
v-model="value"
/>
<AsamButton type="default" @click="inspect"> 读取节点 </AsamButton>
<output>原始模型:{{ value }};{{ inspected }}</output>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamCascaderNativeExample' });
import { ref } from 'vue';
import { AsamCascader, AsamButton } from '@asam-ui/ui';
import type { AsamCascaderExpose, AsamCascaderNativeProps } from '@asam-ui/ui';
const control = ref<AsamCascaderExpose>();
const value = ref<AsamCascaderNativeProps['modelValue']>([]);
const nodes = [
{
id: 'team',
name: '团队',
nodes: [
{ id: 'design', name: '设计' },
{ id: 'dev', name: '开发' }
]
}
];
const inspected = ref('');
function inspect() {
inspected.value = JSON.stringify(
control.value?.getCheckedNodes(true)?.map((node) => node.value)
);
}
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
<template>
<div class="example">
<AsamCascader
ref="control"
v-bind="{
...{ 'value-mode': 'native' },
...{
options: nodes,
props: { value: 'id', label: 'name', children: 'nodes', emitPath: true }
}
}"
v-model="value"
/>
<AsamButton type="default" @click="inspect"> 读取节点 </AsamButton>
<output>原始模型:{{ value }};{{ inspected }}</output>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamCascaderNativeExample' });
import { ref } from 'vue';
import { AsamCascader, AsamButton } from '@asam-ui/ui';
const control = ref();
const value = ref([]);
const nodes = [
{
id: 'team',
name: '团队',
nodes: [
{ id: 'design', name: '设计' },
{ id: 'dev', name: '开发' }
]
}
];
const inspected = ref('');
function inspect() {
inspected.value = JSON.stringify(
control.value?.getCheckedNodes(true)?.map((node) => node.value)
);
}
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
四档尺寸与上下文继承 ​
四个实例分别显式使用 large、big、default、small。下面省略 size 的实例随 ConfigProvider 响应切换;显式 size 覆盖祖先。面板本身没有 size 契约的入口不附加虚构尺寸属性。
四档尺寸与上下文继承
<template>
<div class="example">
<div class="density-grid">
<section data-density="large">
<strong> large </strong>
<AsamCascader size="large" :options="options" model-value="design" />
</section>
<section data-density="big">
<strong> big </strong>
<AsamCascader size="big" :options="options" model-value="design" />
</section>
<section data-density="default">
<strong> default </strong>
<AsamCascader size="default" :options="options" model-value="design" />
</section>
<section data-density="small">
<strong> small </strong>
<AsamCascader size="small" :options="options" model-value="design" />
</section>
</div>
<AsamConfigProvider :size="density">
<section data-density="inherited">
<AsamCascader :options="options" model-value="design" />
</section>
</AsamConfigProvider>
<div class="row">
<AsamButton type="default" @click="density = 'small'"> 继承 small </AsamButton>
<AsamButton type="default" @click="density = 'big'"> 继承 big </AsamButton>
</div>
<output>配置提供器:{{ density }}</output>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamCascaderSizesExample' });
import { ref } from 'vue';
import { AsamCascader, AsamConfigProvider, AsamButton } from '@asam-ui/ui';
import type { AsamControlSize } from '@asam-ui/ui';
const density = ref<AsamControlSize>('big');
const options = [
{
label: '团队',
value: 'team',
raw: {},
children: [
{ label: '设计', value: 'design', raw: {} },
{ label: '开发', value: 'dev', raw: {} }
]
}
];
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
<template>
<div class="example">
<div class="density-grid">
<section data-density="large">
<strong> large </strong>
<AsamCascader size="large" :options="options" model-value="design" />
</section>
<section data-density="big">
<strong> big </strong>
<AsamCascader size="big" :options="options" model-value="design" />
</section>
<section data-density="default">
<strong> default </strong>
<AsamCascader size="default" :options="options" model-value="design" />
</section>
<section data-density="small">
<strong> small </strong>
<AsamCascader size="small" :options="options" model-value="design" />
</section>
</div>
<AsamConfigProvider :size="density">
<section data-density="inherited">
<AsamCascader :options="options" model-value="design" />
</section>
</AsamConfigProvider>
<div class="row">
<AsamButton type="default" @click="density = 'small'"> 继承 small </AsamButton>
<AsamButton type="default" @click="density = 'big'"> 继承 big </AsamButton>
</div>
<output>配置提供器:{{ density }}</output>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamCascaderSizesExample' });
import { ref } from 'vue';
import { AsamCascader, AsamConfigProvider, AsamButton } from '@asam-ui/ui';
const density = ref('big');
const options = [
{
label: '团队',
value: 'team',
raw: {},
children: [
{ label: '设计', value: 'design', raw: {} },
{ label: '开发', value: 'dev', raw: {} }
]
}
];
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
ASAM 扩展与迁移 ​
ASAM 扩展包括四档密度及 value/object、array/string 模型策略。 完整说明。
模型与 change 载荷由值模式和单多选策略共同决定。 完整说明。
迁移旧挂载属性:popper-append-to-body 已淘汰,当前组件没有此属性。 完整说明。
native 模式的 TS 父模型使用 ref<AsamCascaderNativeProps['modelValue']>,保留原生标量、路径、多选和空值声明;初始 [] 不应推断成 never[] 或仅路径数组。辅助 Checkbox 的模型使用其公开事件参数类型,Switch 输出传给布尔属性前作明确转换。
受控回写边界 ​
打开面板后,点击节点会产生候选值并发出 update:modelValue 和 change。 完整说明。
父级随后传入实际变化的 modelValue 时由原生组件重新同步显示和节点。 完整说明。
SSR 使用限制 ​
高级 lazy 的未知标量预填也受原生同步能力限制:叶节点在加载前尚不可解析时,加载后原生实例可能仍无标签和已选节点。ASAM 保留宿主值与未解析值装饰,不短暂重绑定 modelValue 来修补上游;需要显示已选叶节点时,应提供可解析的初始 options,或在节点加载后由宿主传入实际变化的模型。
注意:固定版本连续 SSR 渲染常驻级联弹层时,可能出现 DOM ID 水合不一致。 完整说明。
API 阅读方式 ​
下方 Props、Events、Slots、Exposes 按当前实际公开类型与运行默认值生成。组合属性按分支生效,不能任意混搭值模式。标为“未知 / 未声明”的默认值不代表 false 或空值。源码区域提供对应语言的独立 Demo.vue,可直接复制或下载;本地辅助组件、数据和素材已内联到当前文件。
原生协议完整用法与 API ​
以下用法对应固定 2.14.7。Cascader 与 TreeSelect 的示例显式使用 value-mode="native";其原生值、路径、字段映射和回调不能直接套到标准化模式。API 表保留原生默认值,ASAM 覆盖值与四档尺寸以下列约定为准。
当一个数据集合有清晰的层级结构时,可通过级联选择器逐级查看并选择。
基础用法 ​
有两种触发子菜单的方式
只需为 Cascader 的options属性指定选项数组即可渲染出一个级联选择器。通过 props.expandTrigger 属性控制子节点的展开方式
基础用法
<template>
<div class="m-4">
<p class="example-paragraph">点击展开子选项(默认)</p>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
@change="handleChange"
/>
</div>
<div class="m-4">
<p class="example-paragraph">悬停展开子选项</p>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
:props="props"
@change="handleChange"
/>
</div>
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
import type { AsamCascaderNativeProps } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/basic.vue
import { ref } from 'vue';
const value = ref<AsamCascaderNativeProps['modelValue']>([]);
const props = {
expandTrigger: 'hover' as const
};
const handleChange = (value: unknown) => {
console.log(value);
};
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4 {
margin: var(--asam-space-lg);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
<template>
<div class="m-4">
<p class="example-paragraph">点击展开子选项(默认)</p>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
@change="handleChange"
/>
</div>
<div class="m-4">
<p class="example-paragraph">悬停展开子选项</p>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
:props="props"
@change="handleChange"
/>
</div>
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/basic.vue
import { ref } from 'vue';
const value = ref([]);
const props = {
expandTrigger: 'hover'
};
const handleChange = (value) => {
console.log(value);
};
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4 {
margin: var(--asam-space-lg);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
有禁用选项 ​
通过在数据源中设置 disabled 字段来声明该选项是禁用的
本例中,options指定的数组中的第一个元素含有disabled: true键值对,因此是禁用的。 完整说明。
有禁用选项
<template>
<AsamCascader value-mode="native" :options="options" />
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/option-disabling.vue
const options = [
{
value: 'guide',
label: '指南',
disabled: true,
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<template>
<AsamCascader value-mode="native" :options="options" />
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/option-disabling.vue
const options = [
{
value: 'guide',
label: '指南',
disabled: true,
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
可清空 ​
为 AsamCascader 设置 clearable 后,已选择内容且鼠标悬停时会显示清除图标。
可清空
<template>
<AsamCascader value-mode="native" :options="options" clearable />
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/clearable.vue
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<template>
<AsamCascader value-mode="native" :options="options" clearable />
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/clearable.vue
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
自定义清除图标 ​
你可以通过clear-icon属性自定义清除图标
自定义清除图标
<!-- 此演示还使用 @asam-ui/icons-vue,请按官网对应指南配置这些公开依赖。 -->
<template>
<AsamCascader
value-mode="native"
:options="options"
clearable
:clear-icon="CloseBold"
placeholder="自定义清除图标"
/>
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/clear-icon.vue
import { CloseBold } from '@asam-ui/icons-vue';
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines'
}
]
}
];
</script>
<!-- 此演示还使用 @asam-ui/icons-vue,请按官网对应指南配置这些公开依赖。 -->
<template>
<AsamCascader
value-mode="native"
:options="options"
clearable
:clear-icon="CloseBold"
placeholder="自定义清除图标"
/>
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/clear-icon.vue
import { CloseBold } from '@asam-ui/icons-vue';
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines'
}
]
}
];
</script>
仅显示最后一级 ​
可以仅在输入框中显示选中项最后一级的标签,而不是选中项所在的完整路径。
属性show-all-levels定义了是否显示完整的路径,将其赋值为 false 则仅显示最后一级。
仅显示最后一级
<template>
<AsamCascader value-mode="native" :options="options" :show-all-levels="false" />
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/last-level.vue
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<template>
<AsamCascader value-mode="native" :options="options" :show-all-levels="false" />
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/last-level.vue
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
多选 ​
使用 value-mode="native" 配合 props.multiple=true 开启原生多选模式。将配置保存为具名对象,便于复用:
<template>
<AsamCascader value-mode="native" :props="props" />
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
const props = { multiple: true };
</script>
使用多选时,所有选中的标签将默认显示。您可以设置 collapse = true 将选中的标签折叠。您可以设置 max-collapse-tags 来显示最大tag数量,默认1。您可以使用 collapse-tags-tooltip 属性来启用鼠标悬停折叠文字以显示具体所选值的行为。
多选
<template>
<div class="m-4">
<p class="example-paragraph">显示全部标签(默认)</p>
<AsamCascader value-mode="native" :options="options" :props="props" clearable />
</div>
<div class="m-4">
<p class="example-paragraph">折叠标签</p>
<AsamCascader
value-mode="native"
:options="options"
:props="props"
collapse-tags
clearable
/>
</div>
<div class="m-4">
<p class="example-paragraph">折叠标签提示</p>
<AsamCascader
value-mode="native"
:options="options"
:props="props"
collapse-tags
collapse-tags-tooltip
clearable
/>
</div>
<div class="m-4">
<p class="example-paragraph">最多显示的折叠标签数</p>
<AsamCascader
value-mode="native"
:options="options"
:props="props"
collapse-tags
collapse-tags-tooltip
:max-collapse-tags="3"
clearable
/>
</div>
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/multiple-selection.vue
const props = { multiple: true };
const options = [
{
value: 1,
label: 'Asia',
children: [
{
value: 2,
label: 'China',
children: [
{ value: 3, label: 'Beijing' },
{ value: 4, label: 'Shanghai' },
{ value: 5, label: 'Hangzhou' }
]
},
{
value: 6,
label: 'Japan',
children: [
{ value: 7, label: 'Tokyo' },
{ value: 8, label: 'Osaka' },
{ value: 9, label: 'Kyoto' }
]
},
{
value: 10,
label: 'Korea',
children: [
{ value: 11, label: 'Seoul' },
{ value: 12, label: 'Busan' },
{ value: 13, label: 'Taegu' }
]
}
]
},
{
value: 14,
label: 'Europe',
children: [
{
value: 15,
label: 'France',
children: [
{ value: 16, label: 'Paris' },
{ value: 17, label: 'Marseille' },
{ value: 18, label: 'Lyon' }
]
},
{
value: 19,
label: 'UK',
children: [
{ value: 20, label: 'London' },
{ value: 21, label: 'Birmingham' },
{ value: 22, label: 'Manchester' }
]
}
]
},
{
value: 23,
label: 'North America',
children: [
{
value: 24,
label: 'US',
children: [
{ value: 25, label: 'New York' },
{ value: 26, label: '洛杉矶' },
{ value: 27, label: 'Washington' }
]
},
{
value: 28,
label: 'Canada',
children: [
{ value: 29, label: 'Toronto' },
{ value: 30, label: 'Montreal' },
{ value: 31, label: 'Ottawa' }
]
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4 {
margin: var(--asam-space-lg);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
<template>
<div class="m-4">
<p class="example-paragraph">显示全部标签(默认)</p>
<AsamCascader value-mode="native" :options="options" :props="props" clearable />
</div>
<div class="m-4">
<p class="example-paragraph">折叠标签</p>
<AsamCascader
value-mode="native"
:options="options"
:props="props"
collapse-tags
clearable
/>
</div>
<div class="m-4">
<p class="example-paragraph">折叠标签提示</p>
<AsamCascader
value-mode="native"
:options="options"
:props="props"
collapse-tags
collapse-tags-tooltip
clearable
/>
</div>
<div class="m-4">
<p class="example-paragraph">最多显示的折叠标签数</p>
<AsamCascader
value-mode="native"
:options="options"
:props="props"
collapse-tags
collapse-tags-tooltip
:max-collapse-tags="3"
clearable
/>
</div>
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/multiple-selection.vue
const props = { multiple: true };
const options = [
{
value: 1,
label: 'Asia',
children: [
{
value: 2,
label: 'China',
children: [
{ value: 3, label: 'Beijing' },
{ value: 4, label: 'Shanghai' },
{ value: 5, label: 'Hangzhou' }
]
},
{
value: 6,
label: 'Japan',
children: [
{ value: 7, label: 'Tokyo' },
{ value: 8, label: 'Osaka' },
{ value: 9, label: 'Kyoto' }
]
},
{
value: 10,
label: 'Korea',
children: [
{ value: 11, label: 'Seoul' },
{ value: 12, label: 'Busan' },
{ value: 13, label: 'Taegu' }
]
}
]
},
{
value: 14,
label: 'Europe',
children: [
{
value: 15,
label: 'France',
children: [
{ value: 16, label: 'Paris' },
{ value: 17, label: 'Marseille' },
{ value: 18, label: 'Lyon' }
]
},
{
value: 19,
label: 'UK',
children: [
{ value: 20, label: 'London' },
{ value: 21, label: 'Birmingham' },
{ value: 22, label: 'Manchester' }
]
}
]
},
{
value: 23,
label: 'North America',
children: [
{
value: 24,
label: 'US',
children: [
{ value: 25, label: 'New York' },
{ value: 26, label: '洛杉矶' },
{ value: 27, label: 'Washington' }
]
},
{
value: 28,
label: 'Canada',
children: [
{ value: 29, label: 'Toronto' },
{ value: 30, label: 'Montreal' },
{ value: 31, label: 'Ottawa' }
]
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4 {
margin: var(--asam-space-lg);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
选择任意一级选项 ​
在单选模式下,你只能选择叶子节点;而在多选模式下,勾选父节点真正选中的都是叶子节点。启用该功能后,可让父子节点取消关联,选择任意一级选项。
可通过 props.checkStrictly = true 来设置父子节点取消选中关联,从而达到选择任意一级选项的目的。
选择任意一级选项
<template>
<div class="m-4">
<p class="example-paragraph">选择任意层级(单选)</p>
<AsamCascader value-mode="native" :options="options" :props="props1" clearable />
</div>
<div class="m-4">
<p class="example-paragraph">选择任意层级(多选)</p>
<AsamCascader value-mode="native" :options="options" :props="props2" clearable />
</div>
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/any-level.vue
const props1 = {
checkStrictly: true
};
const props2 = {
multiple: true,
checkStrictly: true
};
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4 {
margin: var(--asam-space-lg);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
<template>
<div class="m-4">
<p class="example-paragraph">选择任意层级(单选)</p>
<AsamCascader value-mode="native" :options="options" :props="props1" clearable />
</div>
<div class="m-4">
<p class="example-paragraph">选择任意层级(多选)</p>
<AsamCascader value-mode="native" :options="options" :props="props2" clearable />
</div>
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/any-level.vue
const props1 = {
checkStrictly: true
};
const props2 = {
multiple: true,
checkStrictly: true
};
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4 {
margin: var(--asam-space-lg);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
动态加载 ​
当选中某一级时,动态加载该级下的选项。
通过lazy开启动态加载,并通过lazyload来设置加载数据源的方法。 完整说明。
动态加载
<template>
<AsamCascader value-mode="native" :props="props" />
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/dynamic-loading.vue
import type { AsamCascaderNativeConfig } from '@asam-ui/ui';
let id = 0;
const props: AsamCascaderNativeConfig = {
lazy: true,
lazyLoad(node, resolve) {
const { level } = node;
setTimeout(() => {
const nodes = Array.from({ length: level + 1 }).map(() => ({
value: ++id,
label: `Option - ${id}`,
leaf: level >= 2
}));
// Invoke `resolve` callback to return the child nodes data and indicate the loading is finished.
resolve(nodes);
}, 1000);
}
};
</script>
<template>
<AsamCascader value-mode="native" :props="props" />
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
let id = 0;
const props = {
lazy: true,
lazyLoad(node, resolve) {
const { level } = node;
setTimeout(() => {
const nodes = Array.from({ length: level + 1 }).map(() => ({
value: ++id,
label: `Option - ${id}`,
leaf: level >= 2
}));
// Invoke `resolve` callback to return the child nodes data and indicate the loading is finished.
resolve(nodes);
}, 1000);
}
};
</script>
可筛选 ​
可以快捷地搜索选项并选择。
为 AsamCascader 设置 filterable 可开启筛选。在原生模式下,会按 show-all-levels 匹配节点或父节点标签中包含输入关键字的项。可通过 filter-method 自定义搜索:接收 node 与 keyword,返回布尔值表示节点是否匹配。
可筛选
<template>
<div class="m-4">
<p class="example-paragraph">可筛选(单选)</p>
<AsamCascader
value-mode="native"
placeholder="尝试搜索:Guide"
:options="options"
filterable
/>
</div>
<div class="m-4">
<p class="example-paragraph">可筛选(多选)</p>
<AsamCascader
value-mode="native"
placeholder="尝试搜索:Guide"
:options="options"
:props="props"
filterable
/>
</div>
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/filterable.vue
const props = {
multiple: true
};
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4 {
margin: var(--asam-space-lg);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
<template>
<div class="m-4">
<p class="example-paragraph">可筛选(单选)</p>
<AsamCascader
value-mode="native"
placeholder="尝试搜索:Guide"
:options="options"
filterable
/>
</div>
<div class="m-4">
<p class="example-paragraph">可筛选(多选)</p>
<AsamCascader
value-mode="native"
placeholder="尝试搜索:Guide"
:options="options"
:props="props"
filterable
/>
</div>
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/filterable.vue
const props = {
multiple: true
};
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4 {
margin: var(--asam-space-lg);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
自定义节点内容 ​
可以自定义备选项的节点内容
你可以通过 scoped slot 自定义节点的内容。您可以访问 scope 中的 node 和 data 属性,分别表示当前节点的 Node 对象和当前节点的数据。
自定义节点内容
<template>
<AsamCascader value-mode="native" :options="options">
<template #default="{ node, data }">
<span>{{ data.label }}</span>
<span v-if="!node.isLeaf"> ({{ data.children?.length ?? 0 }}) </span>
</template>
</AsamCascader>
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/custom-content.vue
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<template>
<AsamCascader value-mode="native" :options="options">
<template #default="{ node, data }">
<span>{{ data.label }}</span>
<span v-if="!node.isLeaf"> ({{ data.children?.length ?? 0 }}) </span>
</template>
</AsamCascader>
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/custom-content.vue
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
自定义建议项 ​
你可以通过 suggestion-item 插槽自定义建议项。你可以在作用域中访问 item,它代表建议项。
自定义建议项
<template>
<AsamCascader value-mode="native" :options="options" filterable placeholder="尝试搜索:Guide">
<template #suggestion-item="{ item }">
<span>🔍 {{ item.pathLabels.join(' > ') }}</span>
</template>
</AsamCascader>
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/custom-suggestion-item.vue
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
<template>
<AsamCascader value-mode="native" :options="options" filterable placeholder="尝试搜索:Guide">
<template #suggestion-item="{ item }">
<span>🔍 {{ item.pathLabels.join(' > ') }}</span>
</template>
</AsamCascader>
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/custom-suggestion-item.vue
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
},
{
value: 'color',
label: '颜色'
},
{
value: 'typography',
label: 'Typography'
},
{
value: 'icon',
label: 'Icon'
},
{
value: 'button',
label: '按钮'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
},
{
value: 'checkbox',
label: 'Checkbox'
},
{
value: 'input',
label: 'Input'
},
{
value: 'input-number',
label: 'InputNumber'
},
{
value: 'select',
label: '选择'
},
{
value: 'cascader',
label: 'Cascader'
},
{
value: 'switch',
label: 'Switch'
},
{
value: 'slider',
label: 'Slider'
},
{
value: 'time-picker',
label: 'TimePicker'
},
{
value: 'date-picker',
label: 'DatePicker'
},
{
value: 'datetime-picker',
label: 'DateTimePicker'
},
{
value: 'upload',
label: '上传'
},
{
value: 'rate',
label: '评分'
},
{
value: 'form',
label: 'Form'
}
]
},
{
value: 'data',
label: 'Data',
children: [
{
value: 'table',
label: 'Table'
},
{
value: 'tag',
label: '标签'
},
{
value: 'progress',
label: 'Progress'
},
{
value: 'tree',
label: 'Tree'
},
{
value: 'pagination',
label: 'Pagination'
},
{
value: 'badge',
label: 'Badge'
}
]
},
{
value: 'notice',
label: '注意',
children: [
{
value: 'alert',
label: 'Alert'
},
{
value: 'loading',
label: '加载中'
},
{
value: 'message',
label: 'Message'
},
{
value: 'message-box',
label: 'MessageBox'
},
{
value: 'notification',
label: 'Notification'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'menu',
label: 'Menu'
},
{
value: 'tabs',
label: 'Tabs'
},
{
value: 'breadcrumb',
label: 'Breadcrumb'
},
{
value: 'dropdown',
label: 'Dropdown'
},
{
value: 'steps',
label: 'Steps'
}
]
},
{
value: 'others',
label: 'Others',
children: [
{
value: 'dialog',
label: 'Dialog'
},
{
value: 'tooltip',
label: 'Tooltip'
},
{
value: 'popover',
label: 'Popover'
},
{
value: 'card',
label: 'Card'
},
{
value: 'carousel',
label: 'Carousel'
},
{
value: 'collapse',
label: 'Collapse'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
];
</script>
级联面板 ​
级联面板是级联选择器的核心组件,与级联选择器一样,有单选、多选、动态加载等多种功能。
与原生模式的 AsamCascader 一样,AsamCascaderPanel 接收 options,并通过 props 配置节点行为;详细说明见其 API 文档。
独立面板示例见 AsamCascaderPanel。
自定义级联标签 ​
您可以自定义标签。
通过 AsamCascader 的 tag 插槽自定义标签。使用此自定义渲染时,collapse-tags、collapse-tags-tooltip 和 max-collapse-tags 不再生效。
自定义级联标签
<template>
<div class="m-4">
<p class="example-paragraph">使用插槽可以更灵活地控制展示。</p>
<AsamCascader value-mode="native" :options="options" :props="props" clearable>
<template #tag="{ data }">
<AsamTag
v-for="(item, index) in getTags(data)"
:key="item"
:color="index % 2 === 0 ? '#FFDE0A' : ''"
>
{{ item }}
</AsamTag>
</template>
</AsamCascader>
<p class="example-paragraph">仅显示顶层标签</p>
<AsamCascader value-mode="native" :options="options" :props="props" clearable>
<template #tag="{ data }">
<AsamTag v-for="item in getTopLevelTags(data)" :key="item">
{{ item }}
</AsamTag>
</template>
</AsamCascader>
</div>
</template>
<script lang="ts" setup>
import { AsamCascader, AsamTag } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/custom-tag.vue
import type { AsamCascaderTag } from '@asam-ui/ui';
const props = { multiple: true };
const options = [
{
value: 1,
label: 'Asia',
children: [
{
value: 2,
label: 'China',
children: [
{ value: 3, label: 'Beijing' },
{ value: 4, label: 'Shanghai' },
{ value: 5, label: 'Hangzhou' }
]
},
{
value: 6,
label: 'Japan',
children: [
{ value: 7, label: 'Tokyo' },
{ value: 8, label: 'Osaka' },
{ value: 9, label: 'Kyoto' }
]
},
{
value: 10,
label: 'Korea',
children: [
{ value: 11, label: 'Seoul' },
{ value: 12, label: 'Busan' },
{ value: 13, label: 'Taegu' }
]
}
]
},
{
value: 14,
label: 'Europe',
children: [
{
value: 15,
label: 'France',
children: [
{ value: 16, label: 'Paris' },
{ value: 17, label: 'Marseille' },
{ value: 18, label: 'Lyon' }
]
},
{
value: 19,
label: 'UK',
children: [
{ value: 20, label: 'London' },
{ value: 21, label: 'Birmingham' },
{ value: 22, label: 'Manchester' }
]
}
]
},
{
value: 23,
label: 'North America',
children: [
{
value: 24,
label: 'US',
children: [
{ value: 25, label: 'New York' },
{ value: 26, label: '洛杉矶' },
{ value: 27, label: 'Washington' }
]
},
{
value: 28,
label: 'Canada',
children: [
{ value: 29, label: 'Toronto' },
{ value: 30, label: 'Montreal' },
{ value: 31, label: 'Ottawa' }
]
}
]
}
];
const getTags = (data: AsamCascaderTag[]) => {
return data.map((item) => item.text);
};
const getTopLevelTags = (data: AsamCascaderTag[]) => {
const set: Set<string> = new Set();
for (const datum of data) {
let parent = datum.node?.parent;
while (parent && parent.level !== 1) {
parent = parent.parent;
}
const label = parent?.data?.label;
if (label) set.add(label);
}
return [...set];
};
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4 {
margin: var(--asam-space-lg);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
<template>
<div class="m-4">
<p class="example-paragraph">使用插槽可以更灵活地控制展示。</p>
<AsamCascader value-mode="native" :options="options" :props="props" clearable>
<template #tag="{ data }">
<AsamTag
v-for="(item, index) in getTags(data)"
:key="item"
:color="index % 2 === 0 ? '#FFDE0A' : ''"
>
{{ item }}
</AsamTag>
</template>
</AsamCascader>
<p class="example-paragraph">仅显示顶层标签</p>
<AsamCascader value-mode="native" :options="options" :props="props" clearable>
<template #tag="{ data }">
<AsamTag v-for="item in getTopLevelTags(data)" :key="item">
{{ item }}
</AsamTag>
</template>
</AsamCascader>
</div>
</template>
<script setup>
import { AsamCascader, AsamTag } from '@asam-ui/ui';
const props = { multiple: true };
const options = [
{
value: 1,
label: 'Asia',
children: [
{
value: 2,
label: 'China',
children: [
{ value: 3, label: 'Beijing' },
{ value: 4, label: 'Shanghai' },
{ value: 5, label: 'Hangzhou' }
]
},
{
value: 6,
label: 'Japan',
children: [
{ value: 7, label: 'Tokyo' },
{ value: 8, label: 'Osaka' },
{ value: 9, label: 'Kyoto' }
]
},
{
value: 10,
label: 'Korea',
children: [
{ value: 11, label: 'Seoul' },
{ value: 12, label: 'Busan' },
{ value: 13, label: 'Taegu' }
]
}
]
},
{
value: 14,
label: 'Europe',
children: [
{
value: 15,
label: 'France',
children: [
{ value: 16, label: 'Paris' },
{ value: 17, label: 'Marseille' },
{ value: 18, label: 'Lyon' }
]
},
{
value: 19,
label: 'UK',
children: [
{ value: 20, label: 'London' },
{ value: 21, label: 'Birmingham' },
{ value: 22, label: 'Manchester' }
]
}
]
},
{
value: 23,
label: 'North America',
children: [
{
value: 24,
label: 'US',
children: [
{ value: 25, label: 'New York' },
{ value: 26, label: '洛杉矶' },
{ value: 27, label: 'Washington' }
]
},
{
value: 28,
label: 'Canada',
children: [
{ value: 29, label: 'Toronto' },
{ value: 30, label: 'Montreal' },
{ value: 31, label: 'Ottawa' }
]
}
]
}
];
const getTags = (data) => {
return data.map((item) => item.text);
};
const getTopLevelTags = (data) => {
const set = new Set();
for (const datum of data) {
let parent = datum.node?.parent;
while (parent && parent.level !== 1) {
parent = parent.parent;
}
const label = parent?.data?.label;
if (label) set.add(label);
}
return [...set];
};
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4 {
margin: var(--asam-space-lg);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
选中项显示策略 ​
控制在多选模式下已选值的显示方式。
在多选模式下,你可以使用 show-checked-strategy 来控制已选值的显示方式。默认策略为 child,即显示所有已选中的子节点。 parent 策略仅在其所有子节点都被选中时显示父节点。
选中项显示策略
<template><StandaloneDemo /></template>
<script lang="ts" setup>
import * as __external0 from "vue";
import * as __external1 from "@asam-ui/ui";
const __external: any = {"vue": { ...__external0, __esModule: true },
"@asam-ui/ui": { ...__external1, __esModule: true }};
const __modules: any = {
"Demo.vue": (module: any, exports: any, require: any) => {
"use strict";
var __importDefault: any = function (mod?: any) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1: any = require("vue");
const vue_2: any = require("vue");
const _hoisted_1: any = { class: "m-4" };
const _hoisted_2: any = { class: "m-4" };
const ui_1: any = require("@asam-ui/ui");
const ControlledBoundary_vue_1: any = __importDefault(require("./ControlledBoundary.vue"));
// Adapted from the fixed upstream MIT example: cascader/show-checked-strategy.vue
const vue_3: any = require("vue");
exports.default = (0, vue_1.defineComponent)({
__name: 'Demo',
setup(__props?: any) {
const value1: any = (0, vue_3.ref)([['guide', 'disciplines', 'feedback']]);
const value2: any = (0, vue_3.ref)([['guide', 'disciplines', 'feedback']]);
const props: any = {
multiple: true
};
const handleChange1: any = (value?: any) => {
console.log('Child strategy:', value);
};
const handleChange2: any = (value?: any) => {
console.log('Parent strategy:', value);
};
const options: any = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{ value: 'feedback', label: '反馈' }
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
}
]
}
];
return (_ctx?: any, _cache?: any) => {
return ((0, vue_2.openBlock)(), (0, vue_2.createElementBlock)(vue_2.Fragment, null, [
_cache[4] || (_cache[4] = (0, vue_2.createElementVNode)("p", { class: "example-paragraph" }, "弹层设为 persistent=false;关闭后保留选中标签,可直接删除或清空,再打开按当前值回填。", -1 /* CACHED */)),
(0, vue_2.createElementVNode)("div", _hoisted_1, [
_cache[2] || (_cache[2] = (0, vue_2.createElementVNode)("p", { class: "example-paragraph" }, "策略:child(默认,显示全部选中的子节点)", -1 /* CACHED */)),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamCascader), {
"value-mode": "native",
modelValue: value1.value,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event?: any) => ((value1).value = $event)),
options: options,
props: props,
"show-checked-strategy": "child",
persistent: false,
clearable: "",
onChange: handleChange1
}, null, 8 /* PROPS */, ["modelValue"])
]),
(0, vue_2.createElementVNode)("div", _hoisted_2, [
_cache[3] || (_cache[3] = (0, vue_2.createElementVNode)("p", { class: "example-paragraph" }, "策略:parent(全部子节点选中时仅显示父节点)", -1 /* CACHED */)),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamCascader), {
"value-mode": "native",
modelValue: value2.value,
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event?: any) => ((value2).value = $event)),
options: options,
props: props,
"show-checked-strategy": "parent",
persistent: false,
clearable: "",
onChange: handleChange2
}, null, 8 /* PROPS */, ["modelValue"])
]),
(0, vue_2.createVNode)(ControlledBoundary_vue_1.default)
], 64 /* STABLE_FRAGMENT */));
};
}
});
exports.default.__scopeId = "data-v-4e4f54df";
},
"ControlledBoundary.vue": (module: any, exports: any, require: any) => {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1: any = require("vue");
const vue_2: any = require("vue");
const _hoisted_1: any = { class: "controlled-boundary" };
const _hoisted_2: any = { class: "boundary-actions" };
const _hoisted_3: any = { class: "boundary-model" };
const _hoisted_4: any = { class: "boundary-display" };
const _hoisted_5: any = { class: "boundary-events" };
const _hoisted_6: any = { class: "boundary-transformations" };
const vue_3: any = require("vue");
const ui_1: any = require("@asam-ui/ui");
exports.default = (0, vue_1.defineComponent)({
__name: 'ControlledBoundary',
setup(__props?: any) {
const mode: any = (0, vue_3.ref)('native');
const behavior: any = (0, vue_3.ref)('reject');
const configuration: any = { multiple: false, emitPath: false };
const children: any = [
{ value: 2, label: '节点2', raw: { id: 2 } },
{ value: 3, label: '节点3', raw: { id: 3 } },
{ value: 4, label: '节点4', raw: { id: 4 } }
];
const boundaryOptions: any = [{ value: 1, label: '根节点', raw: { id: 1 }, children }];
const nativeModel: any = (0, vue_3.ref)(3);
const valueModel: any = (0, vue_3.ref)(3);
const objectModel: any = (0, vue_3.ref)(children[1]);
const control: any = (0, vue_3.ref)();
const transformations: any = (0, vue_3.ref)(0);
const events: any = (0, vue_3.ref)([]);
const display: any = (0, vue_3.ref)({
text: '',
nodes: [],
panel: false
});
const model: any = (0, vue_3.computed)(() => mode.value === 'native'
? nativeModel.value
: mode.value === 'value'
? valueModel.value
: objectModel.value);
async function readDisplay() {
await (0, vue_3.nextTick)();
display.value = {
text: (0, vue_3.unref)(control.value?.presentText) ?? '',
nodes: control.value?.getCheckedNodes(true)?.map((node?: any) => node.value) ?? [],
panel: !!control.value?.cascaderPanelRef
};
}
function record(name?: any, value?: any) {
events.value.push({ name, value });
void readDisplay();
}
function transformedValue() {
return ++transformations.value % 2 ? 3 : 2;
}
function updateNative(value?: any) {
record('update:modelValue', value);
if (behavior.value !== 'reject')
nativeModel.value = behavior.value === 'transform' ? transformedValue() : value;
}
function updateValue(value?: any) {
record('update:modelValue', value);
if (behavior.value !== 'reject')
valueModel.value = behavior.value === 'transform' ? transformedValue() : value;
}
function updateObject(value?: any) {
record('update:modelValue', value);
if (behavior.value === 'reject')
return;
const transformed: any = behavior.value === 'transform' ? transformedValue() : undefined;
objectModel.value =
transformed === undefined
? value
: (children.find((option?: any) => option.value === transformed) ?? null);
}
function resetLog() {
events.value = [];
transformations.value = 0;
void readDisplay();
}
async function closePanel() {
control.value?.togglePopperVisible(false);
await readDisplay();
}
async function openPanel() {
control.value?.togglePopperVisible(true);
await readDisplay();
}
async function setParent() {
nativeModel.value = 4;
valueModel.value = 4;
objectModel.value = children[2];
await readDisplay();
}
return (_ctx?: any, _cache?: any) => {
return ((0, vue_2.openBlock)(), (0, vue_2.createElementBlock)("section", _hoisted_1, [
_cache[17] || (_cache[17] = (0, vue_2.createElementVNode)("h3", null, "常驻面板的受控回写边界", -1 /* CACHED */)),
_cache[18] || (_cache[18] = (0, vue_2.createElementVNode)("p", { class: "example-paragraph" }, " 初始宿主值为3。选择节点2后,忽略回写或第一次转换回旧值3时,常驻面板可能保留候选2。 关闭再打开不会自动回滚;随后将宿主改为4,可观察真实新值的同步。 ", -1 /* CACHED */)),
(0, vue_2.createElementVNode)("label", null, [
_cache[8] || (_cache[8] = (0, vue_2.createTextVNode)(" 值模式 ", -1 /* CACHED */)),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamSelect), {
modelValue: mode.value,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event?: any) => ((mode).value = $event)),
onChange: resetLog
}, {
default: (0, vue_2.withCtx)(() => [
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamOption), {
value: "native",
label: 'native'
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[5] || (_cache[5] = [
(0, vue_2.createTextVNode)("native", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamOption), {
value: "value",
label: 'value'
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[6] || (_cache[6] = [
(0, vue_2.createTextVNode)("value", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamOption), {
value: "object",
label: 'object'
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[7] || (_cache[7] = [
(0, vue_2.createTextVNode)("object", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
})
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["modelValue"])
]),
(0, vue_2.createElementVNode)("label", null, [
_cache[12] || (_cache[12] = (0, vue_2.createTextVNode)(" 宿主回写 ", -1 /* CACHED */)),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamSelect), {
modelValue: behavior.value,
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event?: any) => ((behavior).value = $event)),
onChange: resetLog
}, {
default: (0, vue_2.withCtx)(() => [
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamOption), {
value: "accept",
label: '接受候选值'
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[9] || (_cache[9] = [
(0, vue_2.createTextVNode)("接受候选值", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamOption), {
value: "reject",
label: '忽略回写'
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[10] || (_cache[10] = [
(0, vue_2.createTextVNode)("忽略回写", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamOption), {
value: "transform",
label: '非幂等转换:依次返回3、2、3'
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[11] || (_cache[11] = [
(0, vue_2.createTextVNode)("非幂等转换:依次返回3、2、3", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
})
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["modelValue"])
]),
(0, vue_2.createElementVNode)("div", _hoisted_2, [
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamButton), {
type: "default",
"native-type": "button",
onClick: closePanel
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[13] || (_cache[13] = [
(0, vue_2.createTextVNode)("关闭面板", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamButton), {
type: "default",
"native-type": "button",
onClick: openPanel
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[14] || (_cache[14] = [
(0, vue_2.createTextVNode)("重新打开", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamButton), {
type: "default",
"native-type": "button",
onClick: readDisplay
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[15] || (_cache[15] = [
(0, vue_2.createTextVNode)("读取显示与节点", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamButton), {
type: "default",
"native-type": "button",
onClick: setParent
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[16] || (_cache[16] = [
(0, vue_2.createTextVNode)("宿主改为4", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
})
]),
(mode.value === 'native')
? ((0, vue_2.openBlock)(), (0, vue_2.createBlock)((0, vue_2.unref)(ui_1.AsamCascader), {
key: 0,
ref_key: "control",
ref: control,
"value-mode": "native",
"model-value": nativeModel.value,
options: boundaryOptions,
props: configuration,
persistent: true,
"onUpdate:modelValue": updateNative,
onChange: _cache[2] || (_cache[2] = ($event?: any) => (record('change', $event)))
}, null, 8 /* PROPS */, ["model-value"]))
: (mode.value === 'value')
? ((0, vue_2.openBlock)(), (0, vue_2.createBlock)((0, vue_2.unref)(ui_1.AsamCascader), {
key: 1,
ref_key: "control",
ref: control,
"value-mode": "value",
"model-value": valueModel.value,
options: boundaryOptions,
props: configuration,
persistent: true,
"onUpdate:modelValue": updateValue,
onChange: _cache[3] || (_cache[3] = ($event?: any) => (record('change', $event)))
}, null, 8 /* PROPS */, ["model-value"]))
: ((0, vue_2.openBlock)(), (0, vue_2.createBlock)((0, vue_2.unref)(ui_1.AsamCascader), {
key: 2,
ref_key: "control",
ref: control,
"value-mode": "object",
"model-value": objectModel.value,
options: boundaryOptions,
props: configuration,
persistent: true,
"onUpdate:modelValue": updateObject,
onChange: _cache[4] || (_cache[4] = ($event?: any) => (record('change', $event)))
}, null, 8 /* PROPS */, ["model-value"])),
(0, vue_2.createElementVNode)("output", _hoisted_3, "宿主模型:" + (0, vue_2.toDisplayString)(model.value), 1 /* TEXT */),
(0, vue_2.createElementVNode)("output", _hoisted_4, " 实际显示:" + (0, vue_2.toDisplayString)(display.value.text) + ";公开节点:" + (0, vue_2.toDisplayString)(display.value.nodes) + ";面板存在:" + (0, vue_2.toDisplayString)(display.value.panel), 1 /* TEXT */),
(0, vue_2.createElementVNode)("output", _hoisted_5, "模型事件:" + (0, vue_2.toDisplayString)(events.value), 1 /* TEXT */),
(0, vue_2.createElementVNode)("output", _hoisted_6, "转换调用:" + (0, vue_2.toDisplayString)(transformations.value), 1 /* TEXT */)
]));
};
}
});
exports.default.__scopeId = "data-v-66e8a5c6";
},
};
const __dependencies: any = {"Demo.vue":{"./ControlledBoundary.vue":"ControlledBoundary.vue"},"ControlledBoundary.vue":{}};
const __cache: any = Object.create(null);
function __require(id: any): any {
if (__external[id]) return __external[id];
if (__cache[id]) return __cache[id].exports;
const module: any = { exports: {} };
__cache[id] = module;
__modules[id](module, module.exports, (dependency: any) => __require(__dependencies[id][dependency] || dependency));
return module.exports;
}
const StandaloneDemo = __require('Demo.vue').default;
</script>
<style>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4[data-v-4e4f54df] {
margin: var(--asam-space-lg);
}
p[data-v-4e4f54df]:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
.controlled-boundary[data-v-66e8a5c6] {
display: grid;
gap: var(--asam-space-sm, 8px);
margin-block: var(--asam-space-lg, 24px);
}
.boundary-actions[data-v-66e8a5c6] {
display: flex;
flex-wrap: wrap;
gap: var(--asam-space-sm, 8px);
}
output[data-v-66e8a5c6] {
overflow-wrap: anywhere;
}
p[data-v-66e8a5c6]:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
<template><StandaloneDemo /></template>
<script setup>
import * as __external0 from "vue";
import * as __external1 from "@asam-ui/ui";
const __external = {"vue": { ...__external0, __esModule: true },
"@asam-ui/ui": { ...__external1, __esModule: true }};
const __modules = {
"Demo.vue": (module, exports, require) => {
"use strict";
var __importDefault = function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1 = require("vue");
const _hoisted_1 = { class: "m-4" };
const _hoisted_2 = { class: "m-4" };
const ui_1 = require("@asam-ui/ui");
const ControlledBoundary_vue_1 = __importDefault(require("./ControlledBoundary.vue"));
// Adapted from the fixed upstream MIT example: cascader/show-checked-strategy.vue
const vue_2 = require("vue");
exports.default = {
__name: 'Demo',
setup(__props) {
const value1 = (0, vue_2.ref)([['guide', 'disciplines', 'feedback']]);
const value2 = (0, vue_2.ref)([['guide', 'disciplines', 'feedback']]);
const props = {
multiple: true
};
const handleChange1 = (value) => {
console.log('Child strategy:', value);
};
const handleChange2 = (value) => {
console.log('Parent strategy:', value);
};
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{ value: 'feedback', label: '反馈' }
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
}
]
}
];
return (_ctx, _cache) => {
return ((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)(vue_1.Fragment, null, [
_cache[4] || (_cache[4] = (0, vue_1.createElementVNode)("p", { class: "example-paragraph" }, "弹层设为 persistent=false;关闭后保留选中标签,可直接删除或清空,再打开按当前值回填。", -1 /* CACHED */)),
(0, vue_1.createElementVNode)("div", _hoisted_1, [
_cache[2] || (_cache[2] = (0, vue_1.createElementVNode)("p", { class: "example-paragraph" }, "策略:child(默认,显示全部选中的子节点)", -1 /* CACHED */)),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamCascader), {
"value-mode": "native",
modelValue: value1.value,
"onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((value1).value = $event)),
options: options,
props: props,
"show-checked-strategy": "child",
persistent: false,
clearable: "",
onChange: handleChange1
}, null, 8 /* PROPS */, ["modelValue"])
]),
(0, vue_1.createElementVNode)("div", _hoisted_2, [
_cache[3] || (_cache[3] = (0, vue_1.createElementVNode)("p", { class: "example-paragraph" }, "策略:parent(全部子节点选中时仅显示父节点)", -1 /* CACHED */)),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamCascader), {
"value-mode": "native",
modelValue: value2.value,
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => ((value2).value = $event)),
options: options,
props: props,
"show-checked-strategy": "parent",
persistent: false,
clearable: "",
onChange: handleChange2
}, null, 8 /* PROPS */, ["modelValue"])
]),
(0, vue_1.createVNode)(ControlledBoundary_vue_1.default)
], 64 /* STABLE_FRAGMENT */));
};
}
};
exports.default.__scopeId = "data-v-7631403f";
},
"ControlledBoundary.vue": (module, exports, require) => {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1 = require("vue");
const _hoisted_1 = { class: "controlled-boundary" };
const _hoisted_2 = { class: "boundary-actions" };
const _hoisted_3 = { class: "boundary-model" };
const _hoisted_4 = { class: "boundary-display" };
const _hoisted_5 = { class: "boundary-events" };
const _hoisted_6 = { class: "boundary-transformations" };
const ui_1 = require("@asam-ui/ui");
const vue_2 = require("vue");
exports.default = {
__name: 'ControlledBoundary',
setup(__props) {
const mode = (0, vue_2.ref)('native');
const behavior = (0, vue_2.ref)('reject');
const configuration = { multiple: false, emitPath: false };
const children = [
{ value: 2, label: '节点2', raw: { id: 2 } },
{ value: 3, label: '节点3', raw: { id: 3 } },
{ value: 4, label: '节点4', raw: { id: 4 } }
];
const boundaryOptions = [{ value: 1, label: '根节点', raw: { id: 1 }, children }];
const nativeModel = (0, vue_2.ref)(3);
const valueModel = (0, vue_2.ref)(3);
const objectModel = (0, vue_2.ref)(children[1]);
const control = (0, vue_2.ref)();
const transformations = (0, vue_2.ref)(0);
const events = (0, vue_2.ref)([]);
const display = (0, vue_2.ref)({
text: '',
nodes: [],
panel: false
});
const model = (0, vue_2.computed)(() => mode.value === 'native'
? nativeModel.value
: mode.value === 'value'
? valueModel.value
: objectModel.value);
async function readDisplay() {
await (0, vue_2.nextTick)();
display.value = {
text: (0, vue_2.unref)(control.value?.presentText) ?? '',
nodes: control.value?.getCheckedNodes(true)?.map((node) => node.value) ?? [],
panel: !!control.value?.cascaderPanelRef
};
}
function record(name, value) {
events.value.push({ name, value });
void readDisplay();
}
function transformedValue() {
return ++transformations.value % 2 ? 3 : 2;
}
function updateNative(value) {
record('update:modelValue', value);
if (behavior.value !== 'reject')
nativeModel.value = behavior.value === 'transform' ? transformedValue() : value;
}
function updateValue(value) {
record('update:modelValue', value);
if (behavior.value !== 'reject')
valueModel.value = behavior.value === 'transform' ? transformedValue() : value;
}
function updateObject(value) {
record('update:modelValue', value);
if (behavior.value === 'reject')
return;
const transformed = behavior.value === 'transform' ? transformedValue() : undefined;
objectModel.value =
transformed === undefined
? value
: (children.find((option) => option.value === transformed) ?? null);
}
function resetLog() {
events.value = [];
transformations.value = 0;
void readDisplay();
}
async function closePanel() {
control.value?.togglePopperVisible(false);
await readDisplay();
}
async function openPanel() {
control.value?.togglePopperVisible(true);
await readDisplay();
}
async function setParent() {
nativeModel.value = 4;
valueModel.value = 4;
objectModel.value = children[2];
await readDisplay();
}
return (_ctx, _cache) => {
return ((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)("section", _hoisted_1, [
_cache[17] || (_cache[17] = (0, vue_1.createElementVNode)("h3", null, "常驻面板的受控回写边界", -1 /* CACHED */)),
_cache[18] || (_cache[18] = (0, vue_1.createElementVNode)("p", { class: "example-paragraph" }, " 初始宿主值为3。选择节点2后,忽略回写或第一次转换回旧值3时,常驻面板可能保留候选2。 关闭再打开不会自动回滚;随后将宿主改为4,可观察真实新值的同步。 ", -1 /* CACHED */)),
(0, vue_1.createElementVNode)("label", null, [
_cache[8] || (_cache[8] = (0, vue_1.createTextVNode)(" 值模式 ", -1 /* CACHED */)),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamSelect), {
modelValue: mode.value,
"onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((mode).value = $event)),
onChange: resetLog
}, {
default: (0, vue_1.withCtx)(() => [
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamOption), {
value: "native",
label: 'native'
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[5] || (_cache[5] = [
(0, vue_1.createTextVNode)("native", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamOption), {
value: "value",
label: 'value'
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[6] || (_cache[6] = [
(0, vue_1.createTextVNode)("value", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamOption), {
value: "object",
label: 'object'
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[7] || (_cache[7] = [
(0, vue_1.createTextVNode)("object", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
})
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["modelValue"])
]),
(0, vue_1.createElementVNode)("label", null, [
_cache[12] || (_cache[12] = (0, vue_1.createTextVNode)(" 宿主回写 ", -1 /* CACHED */)),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamSelect), {
modelValue: behavior.value,
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => ((behavior).value = $event)),
onChange: resetLog
}, {
default: (0, vue_1.withCtx)(() => [
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamOption), {
value: "accept",
label: '接受候选值'
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[9] || (_cache[9] = [
(0, vue_1.createTextVNode)("接受候选值", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamOption), {
value: "reject",
label: '忽略回写'
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[10] || (_cache[10] = [
(0, vue_1.createTextVNode)("忽略回写", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamOption), {
value: "transform",
label: '非幂等转换:依次返回3、2、3'
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[11] || (_cache[11] = [
(0, vue_1.createTextVNode)("非幂等转换:依次返回3、2、3", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
})
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["modelValue"])
]),
(0, vue_1.createElementVNode)("div", _hoisted_2, [
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamButton), {
type: "default",
"native-type": "button",
onClick: closePanel
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[13] || (_cache[13] = [
(0, vue_1.createTextVNode)("关闭面板", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamButton), {
type: "default",
"native-type": "button",
onClick: openPanel
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[14] || (_cache[14] = [
(0, vue_1.createTextVNode)("重新打开", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamButton), {
type: "default",
"native-type": "button",
onClick: readDisplay
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[15] || (_cache[15] = [
(0, vue_1.createTextVNode)("读取显示与节点", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamButton), {
type: "default",
"native-type": "button",
onClick: setParent
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[16] || (_cache[16] = [
(0, vue_1.createTextVNode)("宿主改为4", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
})
]),
(mode.value === 'native')
? ((0, vue_1.openBlock)(), (0, vue_1.createBlock)((0, vue_1.unref)(ui_1.AsamCascader), {
key: 0,
ref_key: "control",
ref: control,
"value-mode": "native",
"model-value": nativeModel.value,
options: boundaryOptions,
props: configuration,
persistent: true,
"onUpdate:modelValue": updateNative,
onChange: _cache[2] || (_cache[2] = $event => (record('change', $event)))
}, null, 8 /* PROPS */, ["model-value"]))
: (mode.value === 'value')
? ((0, vue_1.openBlock)(), (0, vue_1.createBlock)((0, vue_1.unref)(ui_1.AsamCascader), {
key: 1,
ref_key: "control",
ref: control,
"value-mode": "value",
"model-value": valueModel.value,
options: boundaryOptions,
props: configuration,
persistent: true,
"onUpdate:modelValue": updateValue,
onChange: _cache[3] || (_cache[3] = $event => (record('change', $event)))
}, null, 8 /* PROPS */, ["model-value"]))
: ((0, vue_1.openBlock)(), (0, vue_1.createBlock)((0, vue_1.unref)(ui_1.AsamCascader), {
key: 2,
ref_key: "control",
ref: control,
"value-mode": "object",
"model-value": objectModel.value,
options: boundaryOptions,
props: configuration,
persistent: true,
"onUpdate:modelValue": updateObject,
onChange: _cache[4] || (_cache[4] = $event => (record('change', $event)))
}, null, 8 /* PROPS */, ["model-value"])),
(0, vue_1.createElementVNode)("output", _hoisted_3, "宿主模型:" + (0, vue_1.toDisplayString)(model.value), 1 /* TEXT */),
(0, vue_1.createElementVNode)("output", _hoisted_4, " 实际显示:" + (0, vue_1.toDisplayString)(display.value.text) + ";公开节点:" + (0, vue_1.toDisplayString)(display.value.nodes) + ";面板存在:" + (0, vue_1.toDisplayString)(display.value.panel), 1 /* TEXT */),
(0, vue_1.createElementVNode)("output", _hoisted_5, "模型事件:" + (0, vue_1.toDisplayString)(events.value), 1 /* TEXT */),
(0, vue_1.createElementVNode)("output", _hoisted_6, "转换调用:" + (0, vue_1.toDisplayString)(transformations.value), 1 /* TEXT */)
]));
};
}
};
exports.default.__scopeId = "data-v-f2fad550";
},
};
const __dependencies = {"Demo.vue":{"./ControlledBoundary.vue":"ControlledBoundary.vue"},"ControlledBoundary.vue":{}};
const __cache = Object.create(null);
function __require(id) {
if (__external[id]) return __external[id];
if (__cache[id]) return __cache[id].exports;
const module = { exports: {} };
__cache[id] = module;
__modules[id](module, module.exports, (dependency) => __require(__dependencies[id][dependency] || dependency));
return module.exports;
}
const StandaloneDemo = __require('Demo.vue').default;
</script>
<style>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.m-4[data-v-7631403f] {
margin: var(--asam-space-lg);
}
p[data-v-7631403f]:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
.controlled-boundary[data-v-f2fad550] {
display: grid;
gap: var(--asam-space-sm, 8px);
margin-block: var(--asam-space-lg, 24px);
}
.boundary-actions[data-v-f2fad550] {
display: flex;
flex-wrap: wrap;
gap: var(--asam-space-sm, 8px);
}
output[data-v-f2fad550] {
overflow-wrap: anywhere;
}
p[data-v-f2fad550]:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
示例前两个多选实例显式设置 persistent=false,并提供 native 路径预选值。 完整说明。
后面的受控回写实例固定 persistent=true,提供 native/value/object 模式和接受、忽略、非幂等转换三种宿主处理。 完整说明。
点击节点选择 ​
此功能适用于启用 multiple 或 checkStrictly 的情况。
设置 checkOnClickNode 后,除前缀图标外,点击节点本身也能切换选中状态。
使用 showPrefix 控制前缀的显示。
使用提示 checkOnClickLeaf 控制是否仅在点击叶子节点时触发选择,默认启用。
点击节点选择
<template>
<div class="flex flex-col items-center demo-spacing-1">
<AsamSwitch v-model="showPrefix" active-text="显示前缀" inactive-text="隐藏前缀" />
<div class="flex flex-wrap demo-spacing-2">
<div class="m-4 demo-spacing-3">
<p class="example-paragraph">checkStrictly 单选模式</p>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
:props="props1"
clearable
/>
</div>
<div class="m-4 demo-spacing-4">
<p class="example-paragraph">多选模式</p>
<AsamCascader
value-mode="native"
v-model="value2"
show-checked-strategy="parent"
:options="options"
:props="props2"
clearable
/>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { AsamSwitch, AsamCascader } from '@asam-ui/ui';
import type { AsamCascaderNativeProps, AsamValue } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/check-on-click-node.vue
import { computed, ref } from 'vue';
const value = ref<AsamCascaderNativeProps['modelValue']>();
const value2 = ref<AsamCascaderNativeProps['modelValue']>();
const showPrefix = ref<AsamValue>(true);
const props1 = computed(() => ({
showPrefix: showPrefix.value === true,
checkStrictly: true,
checkOnClickNode: true
}));
const props2 = computed(() => ({
showPrefix: showPrefix.value === true,
multiple: true,
checkOnClickNode: true
}));
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.flex {
display: flex;
}
.flex-wrap {
flex-wrap: wrap;
}
.items-center {
align-items: center;
}
.m-4 {
margin: var(--asam-space-lg);
}
.flex-col {
flex-direction: column;
}
</style>
<style scoped>
.demo-spacing-1 {
gap: var(--asam-space-md);
}
.demo-spacing-2 {
gap: var(--asam-space-md);
}
.demo-spacing-3 {
display: grid;
gap: var(--asam-space-md);
}
.demo-spacing-4 {
display: grid;
gap: var(--asam-space-md);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
<template>
<div class="flex flex-col items-center demo-spacing-1">
<AsamSwitch v-model="showPrefix" active-text="显示前缀" inactive-text="隐藏前缀" />
<div class="flex flex-wrap demo-spacing-2">
<div class="m-4 demo-spacing-3">
<p class="example-paragraph">checkStrictly 单选模式</p>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
:props="props1"
clearable
/>
</div>
<div class="m-4 demo-spacing-4">
<p class="example-paragraph">多选模式</p>
<AsamCascader
value-mode="native"
v-model="value2"
show-checked-strategy="parent"
:options="options"
:props="props2"
clearable
/>
</div>
</div>
</div>
</template>
<script setup>
import { AsamSwitch, AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/check-on-click-node.vue
import { computed, ref } from 'vue';
const value = ref();
const value2 = ref();
const showPrefix = ref(true);
const props1 = computed(() => ({
showPrefix: showPrefix.value === true,
checkStrictly: true,
checkOnClickNode: true
}));
const props2 = computed(() => ({
showPrefix: showPrefix.value === true,
multiple: true,
checkOnClickNode: true
}));
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
}
]
}
]
},
{
value: 'component',
label: '组件',
children: [
{
value: 'basic',
label: 'Basic',
children: [
{
value: 'layout',
label: 'Layout'
}
]
},
{
value: 'form',
label: 'Form',
children: [
{
value: 'radio',
label: 'Radio'
}
]
}
]
},
{
value: 'resource',
label: '资源',
children: [
{
value: 'axure',
label: 'Axure Components'
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.flex {
display: flex;
}
.flex-wrap {
flex-wrap: wrap;
}
.items-center {
align-items: center;
}
.m-4 {
margin: var(--asam-space-lg);
}
.flex-col {
flex-direction: column;
}
</style>
<style scoped>
.demo-spacing-1 {
gap: var(--asam-space-md);
}
.demo-spacing-2 {
gap: var(--asam-space-md);
}
.demo-spacing-3 {
display: grid;
gap: var(--asam-space-md);
}
.demo-spacing-4 {
display: grid;
gap: var(--asam-space-md);
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
自定义头部与底部 ​
你可以通过插槽来自定义下拉菜单的头部和底部。
使用插槽自定义内容。
虚拟滚动 ​
当处理大量数据时,您可以启用虚拟滚动以提高性能。
将 virtual-scroll 设置为 true 以启用虚拟滚动。 您还可以使用 height 自定义菜单高度,并使用 item-size 自定义节点高度。 默认高度为 204px,默认节点大小为 34px。
虚拟滚动
<template>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
:filter-method="filterMethod"
filterable
virtual-scroll
clearable
placeholder="大数据量选择器"
/>
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/virtual-scroll.vue
import { ref } from 'vue';
import type { AsamCascaderNode, AsamCascaderNativeProps } from '@asam-ui/ui';
interface CascaderExampleOption {
value: string;
label: string;
children?: CascaderExampleOption[];
}
const value = ref<AsamCascaderNativeProps['modelValue']>([]);
const filterMethod = (node: AsamCascaderNode, keyword: string) => {
return node.text.toLowerCase().includes(keyword.toLowerCase());
};
const generateOptions = (count: number): CascaderExampleOption[] => {
return Array.from({ length: count }).map((_, index) => ({
value: `option-${index}`,
label: `Option ${index + 1}`,
children: [
{
value: `child-${index}-1`,
label: `Child ${index + 1}-1`,
children: [
{
value: `grandchild-${index}-1-1`,
label: `Grandchild ${index + 1}-1-1`
},
{
value: `grandchild-${index}-1-2`,
label: `Grandchild ${index + 1}-1-2`
}
]
},
{
value: `child-${index}-2`,
label: `Child ${index + 1}-2`
}
]
}));
};
const options = ref<CascaderExampleOption[]>(generateOptions(20000));
</script>
<template>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
:filter-method="filterMethod"
filterable
virtual-scroll
clearable
placeholder="大数据量选择器"
/>
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/virtual-scroll.vue
import { ref } from 'vue';
const value = ref([]);
const filterMethod = (node, keyword) => {
return node.text.toLowerCase().includes(keyword.toLowerCase());
};
const generateOptions = (count) => {
return Array.from({ length: count }).map((_, index) => ({
value: `option-${index}`,
label: `Option ${index + 1}`,
children: [
{
value: `child-${index}-1`,
label: `Child ${index + 1}-1`,
children: [
{
value: `grandchild-${index}-1-1`,
label: `Grandchild ${index + 1}-1-1`
},
{
value: `grandchild-${index}-1-2`,
label: `Grandchild ${index + 1}-1-2`
}
]
},
{
value: `child-${index}-2`,
label: `Child ${index + 1}-2`
}
]
}));
};
const options = ref(generateOptions(20000));
</script>
自定义建议列表宽度 ​
建议面板(筛选时)的宽度默认会根据匹配到的选项中的最大宽度自动计算。 完整说明。
使用提示
fit-input-width 属性仅控制搜索时建议面板的宽度,不影响默认的级联面板。
自定义建议列表宽度
<template>
<div class="flex flex-wrap gap-4 items-center">
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
placeholder="默认展开面板"
filterable
/>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
placeholder="匹配输入框宽度"
filterable
fit-input-width
/>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
placeholder="固定宽度(400px)"
filterable
:fit-input-width="400"
>
<template #suggestion-item="{ item }">
<div>{{ item.text }} (较长的自定义内容)</div>
</template>
</AsamCascader>
</div>
</template>
<script lang="ts" setup>
import { AsamCascader } from '@asam-ui/ui';
import type { AsamCascaderNativeProps } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/fit-input-width.vue
import { ref } from 'vue';
const value = ref<AsamCascaderNativeProps['modelValue']>();
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.flex {
display: flex;
}
.flex-wrap {
flex-wrap: wrap;
}
.items-center {
align-items: center;
}
.gap-4 {
gap: var(--asam-space-lg);
}
</style>
<template>
<div class="flex flex-wrap gap-4 items-center">
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
placeholder="默认展开面板"
filterable
/>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
placeholder="匹配输入框宽度"
filterable
fit-input-width
/>
<AsamCascader
value-mode="native"
v-model="value"
:options="options"
placeholder="固定宽度(400px)"
filterable
:fit-input-width="400"
>
<template #suggestion-item="{ item }">
<div>{{ item.text }} (较长的自定义内容)</div>
</template>
</AsamCascader>
</div>
</template>
<script setup>
import { AsamCascader } from '@asam-ui/ui';
// Adapted from the fixed upstream MIT example: cascader/fit-input-width.vue
import { ref } from 'vue';
const value = ref();
const options = [
{
value: 'guide',
label: '指南',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: '一致性'
},
{
value: 'feedback',
label: '反馈'
},
{
value: 'efficiency',
label: '效率'
},
{
value: 'controllability',
label: '可控性'
}
]
},
{
value: 'navigation',
label: 'Navigation',
children: [
{
value: 'side nav',
label: 'Side Navigation'
},
{
value: 'top nav',
label: 'Top Navigation'
}
]
}
]
}
];
</script>
<style scoped>
/* Keep layout utilities local so the downloaded SFC needs no CSS preset. */
.flex {
display: flex;
}
.flex-wrap {
flex-wrap: wrap;
}
.items-center {
align-items: center;
}
.gap-4 {
gap: var(--asam-space-lg);
}
</style>
Cascader API ​
属性 ​
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| model-value / v-model | 选中项绑定值 | string / number /arraystring[] | number[] | any |
— |
| options | 选项的数据源, value 和 label 可以通过 CascaderProps 自定义. | arrayAsamCascaderOption[] |
— |
| props | 配置选项, 请参阅下面 CascaderProps 表。 | objectCascaderProps |
— |
| size | 输入框尺寸 | enum'large' | 'default' | 'small' |
— |
| placeholder | 输入框占位文本 | string | — |
| disabled | 指定选项的禁用为选项对象的某个属性值 | boolean | — |
| clearable | 是否支持清空选项 | boolean | — |
| clear-icon | 自定义清除图标 | string / objectComponent |
CircleClose |
| show-all-levels | 输入框中是否显示选中值的完整路径 | boolean | true |
| collapse-tags | 多选模式下是否折叠Tag | boolean | — |
| collapse-tags-tooltip | 当鼠标悬停于折叠标签的文本时,是否显示所有选中的标签。要使用此属性,collapse-tags属性必须设定为 true | boolean | false |
| max-collapse-tags-tooltip-height | collapse tags 的最大高度 | string / number | — |
| separator | 用于分隔选项的字符 | string | ' / ' |
| filterable | 该选项是否可以被搜索 | boolean | — |
| filter-method | 自定义搜索逻辑,第一个参数是node,第二个参数是keyword,返回的布尔值表示是否保留该选项 | Function(node: AsamCascaderNode, keyword: string) => boolean |
— |
| debounce | 搜索关键词正在输入时的去抖延迟,单位为毫秒 | number | 300 |
| before-filter | 过滤函数调用前,所要调用的钩子函数,该函数接收要过滤的值作为参数。如果该函数的返回值是 false 或者是一个被拒绝的 Promise,那么接下来的过滤逻辑便不会执行。 | Function(value: string) => boolean |
— |
| popper-class | Cascader 下拉菜单和标签提示的自定义类名 | string | '' |
| popper-style | Cascader 下拉菜单和标签提示的自定义样式 | string / object | — |
| teleported | 弹层是否使用 teleport | boolean | true |
| effect | Tooltip 主题,内置了 dark / light 两种 | enum'dark' | 'light' / string |
light |
| tag-type | 标签类型 | enum'success' | 'info' | 'warning' | 'danger' |
info |
| tag-effect | tag effect | enum'light' | 'dark' | 'plain' |
light |
| validate-event | 是否触发表单验证 | boolean | true |
| max-collapse-tags | 需要显示的 Tag 的最大数量要使用此功能,collapse-tags的值必须为true | number | 1 |
| empty-values | 组件的空值集合, 参见配置容器 | array | — |
| value-on-clear | 清空操作的返回值, 参见配置容器 | string / number / boolean / Function | — |
| persistent | 当下拉框未被激活并且persistent设置为false,下拉框容器会被删除。 | boolean | true |
| fallback-placements | 文字提示可用的位置列表 popper.js | arrayPlacement[] |
— |
| placement | 下拉框出现的位置 | enum'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end' |
bottom-start |
| show-checked-strategy | 多选模式下已选节点的展示策略。当你想让显示更简洁时,使用 parent。当你想显示每个子项时,使用 child。 | enum'parent' | 'child' |
child |
| virtual-scroll | 是否为大数据启用虚拟滚动 | boolean | false |
| fit-input-width | 建议面板的宽度是否与输入框一致;如果值为 number,则宽度为固定值。 | boolean / number | false |
| item-size | 虚拟滚动的节点高度 (px) | number | 34 |
| height | 虚拟滚动的菜单高度 (px) | number | 204 |
事件 ​
| 名称 | 说明 | 类型 |
|---|---|---|
| change | 当绑定值变化时触发的事件 | Function(value: AsamCascaderNativeProps['modelValue']) => void |
| expand-change | 当展开节点发生变化时触发 | Function(value: AsamCascaderNativeProps['modelValue']) => void |
| blur | 当失去焦点时触发 | Function(event: FocusEvent) => void |
| focus | 当获得焦点时触发 | Function(event: FocusEvent) => void |
| clear | 可清空的单选模式下用户点击清空按钮时触发 | Function() => void |
| visible-change | 下拉框出现/隐藏时触发 | Function(value: boolean) => void |
| remove-tag | 在多选模式下,移除Tag时触发 | Function(value: AsamCascaderNode['valueByOption']) => void |
插槽 ​
| 名称 | 说明 | 类型 |
|---|---|---|
| default | 下级节点的自定义内容,它们分别是当前节点对象和节点数据。 | object{ node: any, data: any } |
| empty | 无匹配选项时的内容 | — |
| prefix | 输入框头部内容 | — |
| suggestion-item | 搜索时自定义建议项内容 | object{ item: AsamCascaderNode } |
| tag | 自定义tag样式 | object{ data: AsamCascaderTag[], deleteTag: (tag: AsamCascaderTag) => void } |
| header | 下拉列表顶部的内容 | — |
| footer | 下拉列表底部的内容 | — |
实例方法与状态 ​
| 名称 | 说明 | 类型 |
|---|---|---|
| getCheckedNodes | 获取一个当前选中节点的数组。(仅仅是传单) 是否只返回叶选中的节点,默认是 false | Function(leafOnly: boolean) => AsamCascaderNode[] | undefined |
| cascaderPanelRef | cascader 面板的 ref | objectComputedRef<any> |
| togglePopperVisible | 切换 popper 可见状态 | Function(visible?: boolean) => void |
| contentRef | cascader 内容的 ref | objectComputedRef<any> |
| presentText | 选中的内容文本 | objectComputedRef<string> |
| focus | 使 input 获取焦点 | Function() => void |
| blur | 使 input 失去焦点 | Function() => void |
级联配置类型(CascaderProps) ​
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| expandTrigger | 次级菜单的展开方式 | enum'click' | 'hover' |
click |
| multiple | 是否多选 | boolean | false |
| checkStrictly | 是否严格的遵守父子节点不互相关联 | boolean | false |
| emitPath | 在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置 false,则只返回该节点的值 | boolean | true |
| lazy | 是否动态加载子节点,需与 lazyLoad 方法结合使用 | boolean | false |
| lazyLoad | 加载子节点数据的方法,仅在 lazy 为 true 时生效;支持通过 reject 回调拒绝加载。 |
Function(node: Node, resolve: Resolve, reject: () => void) => void |
— |
| value | 指定选项的值为选项对象的某个属性值 | string | value |
| label | 指定节点标签为节点对象的某个属性值 | string | label |
| children | 指定选项的子选项为选项对象的某个属性值 | string | children |
| disabled | 指定选项的禁用为选项对象的某个属性值 | string | disabled |
| leaf | 指定选项的叶子节点的标志位为选项对象的某个属性值 | string | leaf |
| hoverThreshold | hover 时展开菜单的灵敏度阈值 | number | 500 |
| checkOnClickNode | 点击节点时是否选中或取消选中该节点 | boolean | false |
| checkOnClickLeaf | 点击叶节点(最后一个子节点)时是否检查或取消节点 | boolean | true |
| showPrefix | 是否显示单选框或复选框的前缀(图标) | boolean | true |
ASAM 模式与默认值 ​
默认 valueMode="value",单选返回叶值或 TreeSelect 节点值,清空为 null;valueMode="object" 返回带 raw 的节点对象,多选清空为 []。 完整说明。
标准化多选默认数组;value 模式可显式 multipleValueMode="string" 与 separator。 完整说明。
控件尺寸使用 large/big/default/small 四档及 ConfigProvider 的继承值。 完整说明。
标准化懒加载 ​
load/lazyLoad 返回 { value, label, raw, children?, leaf?, isLeaf? },不是原生任意对象。 完整说明。
三模式动态模型、回填与源切换
<template>
<div class="hierarchy-example">
<p class="example-paragraph">依次展开“根节点”和子节点,加载两层;数字 0、false 与空字符串保留原类型。</p>
<label
>value<AsamCascader v-model="value" :props="{ lazy: true, lazyLoad: load }" clearable
/></label>
<label
>object<AsamCascader
v-model="objectValue"
value-mode="object"
:props="{ lazy: true, lazyLoad: load }"
clearable
/></label>
<label
>多选<AsamCascader
v-model="multiple"
multiple
:props="{ lazy: true, lazyLoad: load }"
clearable
/></label>
<label
>字符串存储<AsamCascader
v-model="tokens"
multiple
multiple-value-mode="string"
:options="stringOptions"
/></label>
<div>
<AsamButton type="default" @click="restore">回填数字 0</AsamButton
><AsamButton type="default" @click="clear">清空</AsamButton
><AsamButton type="default" @click="replace">切换源并丢弃迟到回调</AsamButton>
</div>
<output
>源 {{ version }};value={{ JSON.stringify(value) }};object={{
JSON.stringify(objectValue)
}};multiple={{ JSON.stringify(multiple) }};tokens={{ tokens }}</output
>
</div>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { AsamCascader, AsamButton } from '@asam-ui/ui';
import type { AsamCascaderLazyLoad, AsamHierarchyOption, AsamValue } from '@asam-ui/ui';
const version = ref(1);
const value = ref<AsamValue | null>(null);
const objectValue = ref<AsamHierarchyOption | null>(null);
const multiple = ref<AsamValue[]>([]);
const tokens = ref('');
const stringOptions = [
{ value: 1, label: '一', raw: {} },
{ value: 2, label: '二', raw: {} }
];
const load = computed<AsamCascaderLazyLoad>(() => {
const sourceVersion = version.value;
return (node, resolve) => {
setTimeout(() => {
resolve(
node.level === 0
? [
{
value: 'root',
label: '根节点 ' + sourceVersion,
raw: { sourceVersion },
leaf: false,
isLeaf: false
}
]
: [0, false, ''].map((value) => ({
value,
label:
typeof value +
':' +
JSON.stringify(value) +
' / 源' +
sourceVersion,
raw: { sourceVersion },
leaf: true,
isLeaf: true
}))
);
}, 400);
};
});
function restore() {
value.value = 0;
objectValue.value = { value: 0, label: '回填 0', raw: { restored: true } };
}
function clear() {
value.value = null;
objectValue.value = null;
multiple.value = [];
tokens.value = '';
}
function replace() {
clear();
version.value++;
}
</script>
<style scoped>
.hierarchy-example {
display: grid;
gap: var(--asam-space-md);
}
label {
display: flex;
align-items: center;
gap: var(--asam-space-sm);
}
output {
overflow-wrap: anywhere;
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
<template>
<div class="hierarchy-example">
<p class="example-paragraph">依次展开“根节点”和子节点,加载两层;数字 0、false 与空字符串保留原类型。</p>
<label
>value<AsamCascader v-model="value" :props="{ lazy: true, lazyLoad: load }" clearable
/></label>
<label
>object<AsamCascader
v-model="objectValue"
value-mode="object"
:props="{ lazy: true, lazyLoad: load }"
clearable
/></label>
<label
>多选<AsamCascader
v-model="multiple"
multiple
:props="{ lazy: true, lazyLoad: load }"
clearable
/></label>
<label
>字符串存储<AsamCascader
v-model="tokens"
multiple
multiple-value-mode="string"
:options="stringOptions"
/></label>
<div>
<AsamButton type="default" @click="restore">回填数字 0</AsamButton
><AsamButton type="default" @click="clear">清空</AsamButton
><AsamButton type="default" @click="replace">切换源并丢弃迟到回调</AsamButton>
</div>
<output
>源 {{ version }};value={{ JSON.stringify(value) }};object={{
JSON.stringify(objectValue)
}};multiple={{ JSON.stringify(multiple) }};tokens={{ tokens }}</output
>
</div>
</template>
<script setup>
import { computed, ref } from 'vue';
import { AsamCascader, AsamButton } from '@asam-ui/ui';
const version = ref(1);
const value = ref(null);
const objectValue = ref(null);
const multiple = ref([]);
const tokens = ref('');
const stringOptions = [
{ value: 1, label: '一', raw: {} },
{ value: 2, label: '二', raw: {} }
];
const load = computed(() => {
const sourceVersion = version.value;
return (node, resolve) => {
setTimeout(() => {
resolve(
node.level === 0
? [
{
value: 'root',
label: '根节点 ' + sourceVersion,
raw: { sourceVersion },
leaf: false,
isLeaf: false
}
]
: [0, false, ''].map((value) => ({
value,
label:
typeof value +
':' +
JSON.stringify(value) +
' / 源' +
sourceVersion,
raw: { sourceVersion },
leaf: true,
isLeaf: true
}))
);
}, 400);
};
});
function restore() {
value.value = 0;
objectValue.value = { value: 0, label: '回填 0', raw: { restored: true } };
}
function clear() {
value.value = null;
objectValue.value = null;
multiple.value = [];
tokens.value = '';
}
function replace() {
clear();
version.value++;
}
</script>
<style scoped>
.hierarchy-example {
display: grid;
gap: var(--asam-space-md);
}
label {
display: flex;
align-items: center;
gap: var(--asam-space-sm);
}
output {
overflow-wrap: anywhere;
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
局部与全局挂载 ​
切换公开挂载参数后,再打开浮层观察内容位于当前组件附近或挂载到 body。 开关显示当前模式,两个模式均可操作;关闭后可以再次切换。
局部与全局挂载
<template>
<div ref="mountTarget" class="popup-stage" :class="{ local: !globalPopup }">
<div class="popup-mode">
<ContainerSwitch
v-model="globalPopup"
active-text="全局挂载到 body"
inactive-text="局部挂载到当前区域"
/>
</div>
<div class="example">
<AsamCascader
ref="control"
v-bind="{ filterable: true, clearable: true, 'aria-label': '选择团队' }"
v-model="value"
:options="options"
@change="event = JSON.stringify($event)"
:teleported="globalPopup"
>
<template #default="{ data }"> {{ data.label }}节点 </template>
<template #empty> 没有可选节点 </template>
</AsamCascader>
<AsamButton type="default" @click="control?.focus()"> 聚焦 </AsamButton>
<output>值:{{ value }};事件:{{ event }}</output>
</div>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamCascaderBasicExample' });
import { ref } from 'vue';
import { AsamCascader, AsamButton } from '@asam-ui/ui';
import type { AsamCascaderExpose } from '@asam-ui/ui';
const control = ref<AsamCascaderExpose>();
const options = [
{
label: '团队',
value: 'team',
raw: {},
children: [
{ label: '设计', value: 'design', raw: {} },
{ label: '开发', value: 'dev', raw: {} }
]
}
];
const value = ref<string | null>('design');
const event = ref('尚未更改');
import { ref as containerRef } from 'vue';
import { AsamSwitch as ContainerSwitch } from '@asam-ui/ui';
const globalPopup = containerRef(true);
const mountTarget = containerRef<HTMLElement>();
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
<style scoped>
.popup-stage {
position: relative;
isolation: isolate;
min-height: 140px;
padding: var(--asam-space-md);
border: 1px dashed var(--asam-color-border);
}
.popup-mode {
margin-bottom: var(--asam-space-lg);
}
</style>
<template>
<div ref="mountTarget" class="popup-stage" :class="{ local: !globalPopup }">
<div class="popup-mode">
<ContainerSwitch
v-model="globalPopup"
active-text="全局挂载到 body"
inactive-text="局部挂载到当前区域"
/>
</div>
<div class="example">
<AsamCascader
ref="control"
v-bind="{ filterable: true, clearable: true, 'aria-label': '选择团队' }"
v-model="value"
:options="options"
@change="event = JSON.stringify($event)"
:teleported="globalPopup"
>
<template #default="{ data }"> {{ data.label }}节点 </template>
<template #empty> 没有可选节点 </template>
</AsamCascader>
<AsamButton type="default" @click="control?.focus()"> 聚焦 </AsamButton>
<output>值:{{ value }};事件:{{ event }}</output>
</div>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamCascaderBasicExample' });
import { ref } from 'vue';
import { AsamCascader, AsamButton } from '@asam-ui/ui';
const control = ref();
const options = [
{
label: '团队',
value: 'team',
raw: {},
children: [
{ label: '设计', value: 'design', raw: {} },
{ label: '开发', value: 'dev', raw: {} }
]
}
];
const value = ref('design');
const event = ref('尚未更改');
import { ref as containerRef } from 'vue';
import { AsamSwitch as ContainerSwitch } from '@asam-ui/ui';
const globalPopup = containerRef(true);
const mountTarget = containerRef();
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
<style scoped>
.popup-stage {
position: relative;
isolation: isolate;
min-height: 140px;
padding: var(--asam-space-md);
border: 1px dashed var(--asam-color-border);
}
.popup-mode {
margin-bottom: var(--asam-space-lg);
}
</style>
API
属性 AsamCascaderProps
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
options | 规范化静态选项。懒加载回调返回相同选项结构;远程来源使用独立组件。 | readonly AsamHierarchyOption<V, I>[] | undefined | AsamCascaderOption[] | undefined | () => [] |
separator | 用于分隔选项的字符 | string | undefined | undefined |
disabled | 指定选项的禁用为选项对象的某个属性值 | boolean | undefined | undefined |
placeholder | 输入框占位文本 | string | undefined | '请选择' |
filterable | 该选项是否可以被搜索 | boolean | undefined | false |
clearable | 是否支持清空选项 | boolean | undefined | true |
teleported | 弹层是否使用 teleport | boolean | undefined | true |
size | 输入框尺寸 | enum"large" | "big" | "default" | "small"完整类型:AsamControlSize | undefined | undefined |
modelValue | 指定选项的值为选项对象的某个属性值 | 查看完整类型string | undefined | V | null | undefined | AsamHierarchyOption<V, I> | null | undefined | readonly V[] | undefined | readonly AsamHierarchyOption<V, I>[] | undefined | (AsamCascaderProps<V, I>)["modelValue"] | undefined |
multiple | — | true | false | undefined | true | undefined | undefined |
valueMode | — | enum"value" | "object" | "native"完整类型:"value" | undefined | "object" | "native" | 'value' |
multipleValueMode | — | enum"string" | "array"完整类型:"string" | undefined | "array" | undefined | undefined |
effect | Tooltip 主题,内置了 dark / light 两种 | enum"light" | "dark"完整类型:(AsamCascaderProps<V, I>)["effect"] | "light" |
popperClass | 级联下拉面板的自定义类名。 | (AsamCascaderProps<V, I>)["popperClass"] | undefined |
popperStyle | 级联下拉面板的自定义样式。 | (AsamCascaderProps<V, I>)["popperStyle"] | undefined |
fallbackPlacements | 下拉面板可采用的位置列表。 | (AsamCascaderProps<V, I>)["fallbackPlacements"] | ["bottom-start","bottom","top-start","top","right","left"] |
placement | 下拉框出现的位置 | enum"auto" | "auto-start" | "auto-end" | "top" | "bottom" | "right" | "left" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end"完整类型:(AsamCascaderProps<V, I>)["placement"] | "bottom-start" |
persistent | 当下拉框未被激活并且persistent设置为false,下拉框容器会被删除。 | boolean | undefined | true |
height | 虚拟滚动菜单高度。 | number | undefined | 204 |
itemSize | 虚拟滚动节点高度。 | number | undefined | 34 |
filterMethod | 自定义搜索逻辑,第一个参数是node,第二个参数是keyword,返回的布尔值表示是否保留该选项 | ((node: AsamCascaderNode, keyword: string) => boolean) | undefined | 函数默认值(作为值传递) |
checkOnClickNode | 点击节点时是否选中或取消选中该节点 | boolean | undefined | false |
emptyValues | 组件支持的空值集合。 | unknown[] | undefined | — |
valueOnClear | 清空时返回的值;需要 undefined 时使用 () => undefined。 | (AsamCascaderProps<V, I>)["valueOnClear"] | undefined |
validateEvent | 是否触发表单验证 | boolean | undefined | true |
virtualScroll | 是否为大数据启用虚拟滚动 | boolean | undefined | false |
clearIcon | 自定义清除图标 | (AsamCascaderProps<V, I>)["clearIcon"] | {"name":"CircleClose","__name":"circle-close"} |
debounce | 搜索关键词正在输入时的去抖延迟,单位为毫秒 | number | undefined | 300 |
collapseTags | 多选模式下是否折叠Tag | boolean | undefined | false |
collapseTagsTooltip | 当鼠标悬停于折叠标签的文本时,是否显示所有选中的标签。要使用此功能,collapse-tags的值必须为true | boolean | undefined | false |
maxCollapseTags | 需要显示的 Tag 的最大数量。只有当 collapse-tags 设置为 true 时才会生效。 | number | undefined | 1 |
fitInputWidth | 建议面板的宽度是否与输入框一致;如果值为 number,则宽度为固定值。 | number | boolean | undefined | false |
tagType | 标签类型 | enum"primary" | "success" | "danger" | "warning" | "info"完整类型:"primary" | "success" | "danger" | "warning" | "info" | undefined | "info" |
tagEffect | 标签效果 | enum"light" | "dark" | "plain"完整类型:"light" | "dark" | "plain" | undefined | "light" |
showAllLevels | 输入框中是否显示选中值的完整路径 | boolean | undefined | true |
maxCollapseTagsTooltipHeight | 折叠标签提示的最大像素高度,需要启用 collapse-tags-tooltip。 | string | number | undefined | — |
beforeFilter | 过滤函数调用前,所要调用的钩子函数,该函数接收要过滤的值作为参数。如果该函数的返回值是 false 或者是一个被拒绝的 Promise,那么接下来的过滤逻辑便不会执行。 | ((value: string) => boolean | Promise<any>) | undefined | 函数默认值(作为值传递) |
showCheckedStrategy | parent 策略适合显示汇总父项;child 策略适合逐项展示所选子节点。 | enum"parent" | "child"完整类型:"parent" | "child" | undefined | "child" |
showPrefix | 是否显示单选框或复选框的前缀(图标) | boolean | undefined | true |
props | 配置选项, 请参阅下面 CascaderProps 表。 | 查看完整类型AsamCascaderSelectionProps<V, I> | undefined | Omit<AsamCascaderNativeConfig, "lazyLoad"> & { readonly lazyLoad?: AsamCascaderLazyLoad<V, I> | undefined; } & { readonly multiple: true; } | AsamCascaderNativeConfig | undefined | 工厂函数(每个实例创建) |
事件 AsamCascaderEmits
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
update:modelValue | — | (AsamCascaderEmits)["update:modelValue"] | — |
change | — | (AsamCascaderEmits)["change"] | — |
clear | — | (AsamCascaderEmits)["clear"] | — |
focus | — | [event: FocusEvent] | — |
blur | — | [event: FocusEvent] | — |
visibleChange | — | [val: boolean] | — |
expandChange | — | (AsamCascaderEmits)["expandChange"] | — |
removeTag | — | (AsamCascaderEmits)["removeTag"] | — |
插槽 AsamCascaderSlots
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
default | — | 查看完整类型((scope: {
/** Present in normalized modes; native mode retains only the upstream slot fields. */
option?: AsamHierarchyOption; data: AsamCascaderOption; node: AsamCascaderNode; }) => unknown) | undefined | — |
empty | — | (() => unknown) | undefined | — |
prefix | — | (() => unknown) | undefined | — |
header | — | (() => unknown) | undefined | — |
footer | — | (() => unknown) | undefined | — |
tag | — | ((scope: { data: AsamCascaderTag[]; deleteTag: (tag: AsamCascaderTag) => void; }) => unknown) | undefined | — |
suggestion-item | — | ((scope: { item: AsamCascaderNode; }) => unknown) | undefined | — |
实例方法与状态 AsamCascaderExpose
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
focus | — | () => void | — |
getCheckedNodes | 获取一个当前选中节点的数组。(仅仅是传单) 是否只返回叶选中的节点,默认是 false | (leafOnly: boolean) => AsamCascaderNode[] | undefined | — |
contentRef | cascader 内容的 ref | HTMLElement | undefined | — |
blur | — | () => void | — |
cascaderPanelRef | cascader 面板的 ref | (AsamCascaderExpose)["cascaderPanelRef"] | — |
togglePopperVisible | 切换浮层可见状态。 | (visible?: boolean) => void | — |
presentText | 选中的内容文本 | string | — |
类型 AsamHierarchyOption
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
label | — | string | — |
value | — | V | — |
disabled | — | boolean | undefined | — |
raw | — | I | — |
children | — | (readonly AsamOption<V, I>[] & readonly AsamHierarchyOption<V, I>[]) | undefined | — |
leaf | 懒加载叶节点标记;自定义原生映射也可从 raw 读取字段。 | boolean | undefined | — |
isLeaf | — | boolean | undefined | — |
类型 AsamCascaderLazyLoad
(node: AsamCascaderNode, resolve: (options?: readonly AsamHierarchyOption<V, I>[]) => void, reject: () => void): void
类型 AsamCascaderSelectionProps
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
disabled | — | (AsamCascaderSelectionProps<V, I>)["disabled"] | — |
lazy | — | boolean | undefined | — |
value | — | string | undefined | — |
label | — | string | undefined | — |
checkStrictly | — | boolean | undefined | — |
checkOnClickNode | — | boolean | undefined | — |
checkOnClickLeaf | — | boolean | undefined | — |
multiple | — | boolean | undefined | — |
showPrefix | — | boolean | undefined | — |
expandTrigger | — | enum"hover" | "click"完整类型:(AsamCascaderSelectionProps<V, I>)["expandTrigger"] | — |
emitPath | — | boolean | undefined | — |
children | — | string | undefined | — |
leaf | — | (AsamCascaderSelectionProps<V, I>)["leaf"] | — |
hoverThreshold | — | number | undefined | — |
lazyLoad | — | AsamCascaderLazyLoad<V, I> | undefined | — |
类型 AsamCascaderNativeProps
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
effect | Tooltip 主题,内置了 dark / light 两种 | enum"light" | "dark"完整类型:(AsamCascaderNativeProps)["effect"] | — |
popperClass | 级联下拉面板的自定义类名。 | (AsamCascaderNativeProps)["popperClass"] | — |
popperStyle | 级联下拉面板的自定义样式。 | (AsamCascaderNativeProps)["popperStyle"] | — |
fallbackPlacements | 下拉面板可采用的位置列表。 | (AsamCascaderNativeProps)["fallbackPlacements"] | — |
placement | 下拉框出现的位置 | enum"auto" | "auto-start" | "auto-end" | "top" | "bottom" | "right" | "left" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end"完整类型:(AsamCascaderNativeProps)["placement"] | — |
persistent | 当下拉框未被激活并且persistent设置为false,下拉框容器会被删除。 | boolean | undefined | — |
teleported | 弹层是否使用 teleport | boolean | undefined | — |
disabled | 指定选项的禁用为选项对象的某个属性值 | boolean | undefined | — |
size | 输入框尺寸 | enum"" | "large" | "default" | "small"完整类型:"" | "large" | "default" | "small" | undefined | — |
height | 虚拟滚动菜单高度。 | number | undefined | — |
props | 配置选项, 请参阅下面 CascaderProps 表。 | AsamCascaderNativeConfig | undefined | — |
itemSize | 虚拟滚动节点高度。 | number | undefined | — |
separator | 用于分隔选项的字符 | string | undefined | — |
modelValue | 指定选项的值为选项对象的某个属性值 | (AsamCascaderNativeProps)["modelValue"] | — |
filterMethod | 自定义搜索逻辑,第一个参数是node,第二个参数是keyword,返回的布尔值表示是否保留该选项 | ((node: AsamCascaderNode, keyword: string) => boolean) | undefined | — |
checkOnClickNode | 点击节点时是否选中或取消选中该节点 | boolean | undefined | — |
options | 选项的数据源, value 和 label 可以通过 CascaderProps 自定义. | AsamCascaderOption[] | undefined | — |
emptyValues | 组件支持的空值集合。 | unknown[] | undefined | — |
valueOnClear | 清空时返回的值;需要 undefined 时使用 () => undefined。 | (AsamCascaderNativeProps)["valueOnClear"] | — |
validateEvent | 是否触发表单验证 | boolean | undefined | — |
virtualScroll | 是否为大数据启用虚拟滚动 | boolean | undefined | — |
clearable | 是否支持清空选项 | boolean | undefined | — |
clearIcon | 自定义清除图标 | (AsamCascaderNativeProps)["clearIcon"] | — |
placeholder | 输入框占位文本 | string | undefined | — |
filterable | 该选项是否可以被搜索 | boolean | undefined | — |
debounce | 搜索关键词正在输入时的去抖延迟,单位为毫秒 | number | undefined | — |
collapseTags | 多选模式下是否折叠Tag | boolean | undefined | — |
collapseTagsTooltip | 当鼠标悬停于折叠标签的文本时,是否显示所有选中的标签。要使用此功能,collapse-tags的值必须为true | boolean | undefined | — |
maxCollapseTags | 需要显示的 Tag 的最大数量。只有当 collapse-tags 设置为 true 时才会生效。 | number | undefined | — |
fitInputWidth | 建议面板的宽度是否与输入框一致;如果值为 number,则宽度为固定值。 | number | boolean | undefined | — |
tagType | 标签类型 | enum"primary" | "success" | "danger" | "warning" | "info"完整类型:"primary" | "success" | "danger" | "warning" | "info" | undefined | — |
tagEffect | 标签效果 | enum"light" | "dark" | "plain"完整类型:"light" | "dark" | "plain" | undefined | — |
showAllLevels | 输入框中是否显示选中值的完整路径 | boolean | undefined | — |
maxCollapseTagsTooltipHeight | 折叠标签提示的最大像素高度,需要启用 collapse-tags-tooltip。 | string | number | undefined | — |
beforeFilter | 过滤函数调用前,所要调用的钩子函数,该函数接收要过滤的值作为参数。如果该函数的返回值是 false 或者是一个被拒绝的 Promise,那么接下来的过滤逻辑便不会执行。 | ((value: string) => boolean | Promise<any>) | undefined | — |
showCheckedStrategy | parent 策略适合显示汇总父项;child 策略适合逐项展示所选子节点。 | enum"parent" | "child"完整类型:"parent" | "child" | undefined | — |
showPrefix | 是否显示单选框或复选框的前缀(图标) | boolean | undefined | — |
用法与契约补充说明 ​
ASAM 扩展与迁移 ​
ASAM 扩展包括四档密度及 value/object、array/string 模型策略。静态组件不处理 request/dictType;未知值保留回显,选项到达后重新解析。native 模式直接使用原始 options/data 和字段映射,禁止混入规范化字符串存储。树选择提供公开树实例方法,级联提供 focus/blur、节点读取和弹层操作;具体列表见 API。
ASAM 扩展与迁移 ​
迁移旧挂载属性:popper-append-to-body 已淘汰,当前组件没有此属性。使用 teleported 控制级联弹层是否传送到组件外(默认 true);false 将弹层留在原位置。appendTo / append-to 是支持它的弹层入口用于指定传送目标的属性,固定版本的 Cascader 未公开此属性,不能直接传入级联组件;它与 teleported 的开关语义不同。
受控回写边界 ​
打开面板后,点击节点会产生候选值并发出 update:modelValue 和 change。固定 2.14.7 下,宿主忽略这次回写,或将候选转换回未发生变化的旧模型时,persistent=true 的面板可能继续显示候选值,getCheckedNodes 也可能返回该候选;关闭再打开不会自动回滚。此现象在原生级联、ASAM native、value 和 object 模式的对照中均已观察到,不能仅凭宿主模型未变就认为界面已经复位。
受控回写边界 ​
父级随后传入实际变化的 modelValue 时由原生组件重新同步显示和节点。persistent=false 关闭后销毁面板,公开 cascaderPanelRef 与 getCheckedNodes 遵循原生当前面板生命周期;ASAM 不再保存独立选择快照,也不补写原生标签删除或受控回滚算法。下方策略示例展示宿主模型、实际显示与公开节点的对照。
有禁用选项 ​
本例中,options指定的数组中的第一个元素含有disabled: true键值对,因此是禁用的。在默认情况下,Cascader 会检查数据中每一项的disabled字段是否为true,如果你的数据中表示禁用含义的字段名不为disabled,可以通过props.disabled属性来指定(详见下方 API 表格)。当然,value、label和children这三个字段名也可以通过同样的方式指定。
动态加载 ​
通过lazy开启动态加载,并通过lazyload来设置加载数据源的方法。 lazyload方法有两个参数,第一个参数node为当前点击的节点,第二个resolve为数据加载完成的回调(必须调用)。为了更准确的显示节点的状态,还可以对节点数据添加是否为叶子节点的标志位 (默认字段为leaf,可通过props.leaf修改)。否则,将以有无子节点来判断其是否为叶子节点。
选中项显示策略 ​
示例前两个多选实例显式设置 persistent=false,并提供 native 路径预选值。关闭会销毁弹层面板,重新打开由原生组件按当前宿主值重建;parent 与 child 保留各自展示策略。关闭状态下标签、删除、清空以及 getCheckedNodes 的结果以 AsamCascader 当前公开实例为准,不保证销毁面板后仍有节点快照。宿主拒绝回写时的显示也遵循原生行为。
选中项显示策略 ​
后面的受控回写实例固定 persistent=true,提供 native/value/object 模式和接受、忽略、非幂等转换三种宿主处理。宿主模型、实际显示、公开节点和模型事件分别展示;先选择节点2,可观察忽略或第一次转换回旧值3的边界,再关闭/重开并将宿主实际改为4观察同步。这些按钮只调用公开弹层方法或改变宿主模型,没有切换 persistent 或强制重建组件来回滚。
自定义建议列表宽度 ​
建议面板(筛选时)的宽度默认会根据匹配到的选项中的最大宽度自动计算。 如果您通过 suggestion-item 插槽自定义建议选项,选项中显示的文本很可能不等于 label 的值,从而导致计算错误。 在这种情况下,您可以使用 fit-input-width 属性来固定其宽度。 当值为 number 时,宽度为固定的具体像素值。
ASAM 模式与默认值 ​
默认 valueMode="value",单选返回叶值或 TreeSelect 节点值,清空为 null;valueMode="object" 返回带 raw 的节点对象,多选清空为 []。0、false 与空字符串都是有效值。标准化 Cascader 固定 emitPath=false,需要完整路径使用 native。Cascader 顶层 multiple 显式值优先,未指定时读取 props.multiple。TreeSelect 默认 checkStrictly=true,显式 false 恢复父子联动;默认多选显示勾选框,显式 showCheckbox=false 可关闭。
ASAM 模式与默认值 ​
标准化多选默认数组;value 模式可显式 multipleValueMode="string" 与 separator。分隔符不能为空,值不能包含分隔符,全树序列化 token 不得冲突。object 与 native 不接受字符串存储策略。未知选中值保留回填,已加载节点提供实际显示标签,不主动改写宿主旧对象。loader/options/valueMode 变更隔离迟到回调。
ASAM 模式与默认值 ​
控件尺寸使用 large/big/default/small 四档及 ConfigProvider 的继承值。原生表中的 large/default/small 是底层尺寸,不能作为 ASAM 尺寸全集。基础组件只接收 options 或宿主 lazy 回调;Remote/Dict 的 provider、搜索及完整树获取属于对应数据入口。
标准化懒加载 ​
load/lazyLoad 返回 { value, label, raw, children?, leaf?, isLeaf? },不是原生任意对象。Cascader 默认读取 leaf,TreeSelect 默认读取 isLeaf;自定义字段通过 props.leaf/props.isLeaf 映射,额外业务字段可来自 raw。内部实例 key 为带类型字符串,业务 v-model 保留原值;原生模式使用原始 key。每次 loader 的 resolve 仅接收一次,重复值、循环树或不合法字符串序列化会抛类型错误;reject 保留原生失败重试语义。内联 props 重建但 loader 本身未变时不会重复初始化动态节点。validateEvent=false 停止包装层的 change 验证,表单 disabled 继续由原生上下文继承。
更多参数与事件说明 ​
ASAM 扩展与迁移 ​
模板中的 update:modelValue 与 change 按当前 valueMode、顶层或级联嵌套 multiple、multipleValueMode 推断:单值为节点值或 null,单对象为规范化节点或 null,多选为可写值数组或对象数组,字符串存储为 string(清空为 '')。camelCase 与 kebab-case 属性遵循同一约束;单选父 ref 必须允许 null,不得用全模式 union 代替当前模式。native 保留原生声明的模型 union 和原生清空值,不能将路径/多选示例的初始数组视为所有返回形状。TS 示例中的窄类型声明可直接复制。
SSR 使用限制 ​
固定 2.14.7 下,同一 SSR 服务进程连续渲染常驻级联弹层(persistent=true)时,可能出现节点 DOM ID 的 hydration mismatch;原生级联与 AsamCascader 均已实际复现。首次水合检查覆盖同一个新建 SSR 应用,不保证上述连续请求场景。模型值和标签显示正常也不代表水合没有警告。
关联组件
参数与事件补充说明
组合契约按分支生效;请同时查看公开类型。
参数与事件说明
options
必填:否;声明来源:ASAM 声明。
默认值与来源
() => [](源码表达式;ASAM 声明)来源分支 9
固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码工厂(未执行):() => [] as CascaderOption[](2.14.7;源码事实,未作为 ASAM 运行实测)
separator
必填:否;声明来源:ASAM 声明。
默认值与来源
undefined(源码表达式;ASAM 声明)来源分支 9
固定上游文档默认:' / '(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:' / '(2.14.7;源码事实,未作为 ASAM 运行实测)
disabled
必填:否;声明来源:ASAM 声明。
disabled 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
枚举:false / true
默认值与来源
undefined(已安装运行时;已安装组件)来源分支 9
固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:undefined(2.14.7;源码事实,未作为 ASAM 运行实测)
placeholder
必填:否;声明来源:ASAM 声明。
默认值与来源
'请选择'(源码表达式;ASAM 声明)来源分支 9
固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
filterable
必填:否;声明来源:ASAM 声明。
filterable 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)来源分支 9
固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
clearable
必填:否;声明来源:ASAM 声明。
clearable 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
枚举:false / true
默认值与来源
true(源码表达式;ASAM 声明)来源分支 9
固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
teleported
必填:否;声明来源:ASAM 声明。
teleported 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
枚举:false / true
默认值与来源
true(已安装运行时;已安装组件)来源分支 9
固定上游文档默认:true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
size
必填:否;声明来源:ASAM 声明。
size 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"large" / "big" / "default" / "small"
默认值与来源
undefined(源码表达式;ASAM 声明)modelValue
必填:否;声明来源:ASAM 声明。
默认值与来源
undefined(源码表达式;ASAM 声明)来源分支 9
固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码未声明 default(2.14.7;源码事实,未作为 ASAM 运行实测)
multiple
必填:按分支;声明来源:ASAM 声明。
multiple 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
契约分支 1
枚举:true
契约分支 2
枚举:false
契约分支 6
枚举:true
默认值与来源
undefined(源码表达式;ASAM 声明)valueMode
必填:否;声明来源:ASAM 声明。
valueMode 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"value"
枚举:"object"
枚举:"native"
默认值与来源
'value'(源码表达式;ASAM 声明)multipleValueMode
必填:否;声明来源:ASAM 声明。
multipleValueMode 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"string"
枚举:"array"
默认值与来源
undefined(源码表达式;ASAM 声明)effect
必填:否;声明来源:上游声明。
effect 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"light" / "dark"
默认值与来源
"light"(已安装运行时;已安装组件)固定上游文档默认:light(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:'light'(2.14.7;源码事实,未作为 ASAM 运行实测)
popperClass
必填:否;声明来源:上游声明。
popperClass 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false
默认值与来源
undefined(已安装运行时;已安装组件)固定上游文档默认:''(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
popperStyle
必填:否;声明来源:上游声明。
popperStyle 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false
嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
默认值与来源
undefined(已安装运行时;已安装组件)固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
fallbackPlacements
必填:否;声明来源:上游声明。
默认值与来源
["bottom-start","bottom","top-start","top","right","left"](已安装运行时;已安装组件)固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:['bottom-start', 'bottom', 'top-start', 'top', 'right', 'left'](2.14.7;源码事实,未作为 ASAM 运行实测)
placement
必填:否;声明来源:上游声明。
placement 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"auto" / "auto-start" / "auto-end" / "top" / "bottom" / "right" / "left" / "top-start" / "top-end" / "bottom-start" / "bottom-end" / "right-start" / "right-end" / "left-start" / "left-end"
默认值与来源
"bottom-start"(已安装运行时;已安装组件)固定上游文档默认:bottom-start(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:'bottom-start'(2.14.7;源码事实,未作为 ASAM 运行实测)
persistent
必填:否;声明来源:上游声明。
persistent 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
true(已安装运行时;已安装组件)固定上游文档默认:true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
height
必填:否;声明来源:上游声明。
默认值与来源
204(已安装运行时;已安装组件)固定上游文档默认:204(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:CASCADER_PANEL_HEIGHT(2.14.7;源码事实,未作为 ASAM 运行实测)
itemSize
必填:否;声明来源:上游声明。
默认值与来源
34(已安装运行时;已安装组件)固定上游文档默认:34(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:CASCADER_PANEL_ITEM_SIZE(2.14.7;源码事实,未作为 ASAM 运行实测)
filterMethod
必填:否;声明来源:上游声明。
filterMethod 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(node: AsamCascaderNode, keyword: string): boolean
默认值与来源
函数默认值(作为值传递)(函数值(不执行);已安装组件)固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码函数默认值(作为值,不执行):(node: CascaderNode, keyword: string) =>
node.text.includes(keyword)(2.14.7;源码事实,未作为 ASAM 运行实测)
checkOnClickNode
必填:否;声明来源:上游声明。
checkOnClickNode 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)emptyValues
必填:否;声明来源:上游声明。
valueOnClear
必填:否;声明来源:上游声明。
valueOnClear 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
valueOnClear.apply:(this: Function, thisArg: any, argArray?: any) => any— 依赖声明调用函数,以指定对象作为 this,并使用指定数组作为函数参数。
事件参数:
(this: Function, thisArg: any, argArray?: any): any嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
valueOnClear.call:(this: Function, thisArg: any, ...argArray: any[]) => any— 依赖声明调用对象方法,并以另一个对象作为当前 this。
事件参数:
(this: Function, thisArg: any, ...argArray: any[]): any嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
valueOnClear.bind:(this: Function, thisArg: any, ...argArray: any[]) => any— 依赖声明创建具有相同函数体的绑定函数,将 this 绑定到指定对象,并设置初始参数。
事件参数:
(this: Function, thisArg: any, ...argArray: any[]): any嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
valueOnClear.toString:() => string— 依赖声明返回函数的字符串表示。
事件参数:
(): string嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
valueOnClear.prototype:any— 依赖声明valueOnClear.length:number— 依赖声明valueOnClear.arguments:any— 依赖声明valueOnClear.caller:Function— 依赖声明嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
valueOnClear.name:string— 依赖声明返回函数名称;函数名称只读,不能修改。
valueOnClear.__@hasInstance@8888:(value: any) => boolean— 依赖声明当函数用作构造函数时,判断指定值是否继承自该函数;构造函数可以覆盖此方法,控制 instanceof 对实例的识别。
事件参数:
(value: any): boolean嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
默认值与来源
undefined(已安装运行时;已安装组件)validateEvent
必填:否;声明来源:上游声明。
validateEvent 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
true(已安装运行时;已安装组件)固定上游文档默认:true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
virtualScroll
必填:否;声明来源:上游声明。
virtualScroll 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)固定上游文档默认:false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
clearIcon
必填:否;声明来源:上游声明。
clearIcon 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(props: any, ctx: Parameters<Extract<NonNullable<(AsamCascaderProps<V, I>)["clearIcon"]>, (...args: never[]) => unknown>>[1]): any
clearIcon.__isFragment:undefined— 依赖声明clearIcon.__isTeleport:undefined— 依赖声明clearIcon.__isSuspense:undefined— 依赖声明
默认值与来源
{"name":"CircleClose","__name":"circle-close"}(已安装运行时;已安装组件)固定上游文档默认:CircleClose(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:CircleClose(2.14.7;源码事实,未作为 ASAM 运行实测)
debounce
必填:否;声明来源:上游声明。
默认值与来源
300(已安装运行时;已安装组件)固定上游文档默认:300(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:300(2.14.7;源码事实,未作为 ASAM 运行实测)
collapseTags
必填:否;声明来源:上游声明。
collapseTags 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
collapseTagsTooltip
必填:否;声明来源:上游声明。
collapseTagsTooltip 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)固定上游文档默认:false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
maxCollapseTags
必填:否;声明来源:上游声明。
默认值与来源
1(已安装运行时;已安装组件)固定上游文档默认:1(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:1(2.14.7;源码事实,未作为 ASAM 运行实测)
fitInputWidth
必填:否;声明来源:上游声明。
fitInputWidth 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(已安装运行时;已安装组件)固定上游文档默认:false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:false(2.14.7;源码事实,未作为 ASAM 运行实测)
tagType
必填:否;声明来源:上游声明。
tagType 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"primary" / "success" / "danger" / "warning" / "info"
默认值与来源
"info"(已安装运行时;已安装组件)固定上游文档默认:info(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
tagEffect
必填:否;声明来源:上游声明。
tagEffect 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"light" / "dark" / "plain"
默认值与来源
"light"(已安装运行时;已安装组件)固定上游文档默认:light(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
showAllLevels
必填:否;声明来源:上游声明。
showAllLevels 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
true(已安装运行时;已安装组件)固定上游文档默认:true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
maxCollapseTagsTooltipHeight
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码未声明 default(2.14.7;源码事实,未作为 ASAM 运行实测)
beforeFilter
必填:否;声明来源:上游声明。
beforeFilter 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(value: string): boolean | Promise<any>
默认值与来源
函数默认值(作为值传递)(函数值(不执行);已安装组件)固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码函数默认值(作为值,不执行):() => true(2.14.7;源码事实,未作为 ASAM 运行实测)
showCheckedStrategy
必填:否;声明来源:上游声明。
showCheckedStrategy 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"parent" / "child"
默认值与来源
"child"(已安装运行时;已安装组件)固定上游文档默认:child(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:'child'(2.14.7;源码事实,未作为 ASAM 运行实测)
showPrefix
必填:否;声明来源:上游声明。
showPrefix 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
true(已安装运行时;已安装组件)固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
props
必填:否;声明来源:ASAM 声明。
props 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
props.expandTrigger:PublicMember<NonNullable<AsamCascaderNativeConfig | undefined>, "expandTrigger">— 上游声明次级菜单的展开方式
固定上游文档默认:
click(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
"hover"/"click"props.multiple:boolean | undefined— 上游声明是否多选
固定上游文档默认:
false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.checkStrictly:boolean | undefined— 上游声明是否严格的遵守父子节点不互相关联
固定上游文档默认:
false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.emitPath:boolean | undefined— 上游声明在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置 false,则只返回该节点的值
固定上游文档默认:
true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.lazy:boolean | undefined— 上游声明是否动态加载子节点,需与 lazyLoad 方法结合使用
固定上游文档默认:
false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.lazyLoad:PublicMember<NonNullable<AsamCascaderNativeConfig | undefined>, "lazyLoad">— 上游声明加载动态数据的方法,仅在 lazy 为 true 时有效 reject 参数在 2.11.5 版本及以上支持。
固定上游文档默认:
未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)事件参数:
(node: AsamCascaderNode, resolve: Parameters<Extract<NonNullable<PublicMember<NonNullable<AsamCascaderNativeConfig | undefined>, "lazyLoad">>, (...args: never[]) => unknown>>[1], reject: () => void): voidprops.value:string | undefined— 上游声明指定选项的值为选项对象的某个属性值
固定上游文档默认:
value(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)props.label:string | undefined— 上游声明指定节点标签为节点对象的某个属性值
固定上游文档默认:
label(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)props.children:string | undefined— 上游声明指定选项的子选项为选项对象的某个属性值
固定上游文档默认:
children(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)props.disabled:PublicMember<NonNullable<AsamCascaderNativeConfig | undefined>, "disabled">— 上游声明指定选项的禁用为选项对象的某个属性值
固定上游文档默认:
disabled(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)事件参数:
(data: AsamCascaderOption, node: AsamCascaderNode): booleanprops.leaf:PublicMember<NonNullable<AsamCascaderNativeConfig | undefined>, "leaf">— 上游声明指定选项的叶子节点的标志位为选项对象的某个属性值
固定上游文档默认:
leaf(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)事件参数:
(data: AsamCascaderOption, node: AsamCascaderNode): booleanprops.hoverThreshold:number | undefined— 上游声明hover 时展开菜单的灵敏度阈值
固定上游文档默认:
500(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)props.checkOnClickNode:boolean | undefined— 上游声明点击节点时是否选中或取消选中该节点
固定上游文档默认:
false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.checkOnClickLeaf:boolean | undefined— 上游声明点击叶节点(最后一个子节点)时是否检查或取消节点
固定上游文档默认:
true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.showPrefix:boolean | undefined— 上游声明是否显示单选框或复选框的前缀(图标)
固定上游文档默认:
true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/true
默认值与来源
工厂函数(每个实例创建)(实例工厂;已安装组件)来源分支 9
固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码工厂(未执行):() => ({}) as CascaderProps(2.14.7;源码事实,未作为 ASAM 运行实测)
AsamCascaderProps 公开类型视图
import type { Attrs } from 'vue';
import type { AsamCascaderProps, AsamValue, AsamHierarchyOption, AsamHierarchyRuntimeProps, AsamControlSize, AsamCascaderNode, AsamCascaderSelectionProps, AsamCascaderNativeConfig, AsamCascaderLazyLoad, AsamCascaderOption } from '@asam-ui/ui';
type PublicMember<T, K extends PropertyKey> = T extends unknown ? K extends keyof T ? T[K] : never : never;
// AsamCascaderProps
type PublicContract<V extends AsamValue = AsamValue, I extends object = object> = AsamCascaderProps<V, I>;
参数与事件说明
update:modelValue
必填:是;声明来源:ASAM 声明。
change
必填:是;声明来源:ASAM 声明。
clear
必填:是;声明来源:ASAM 声明。
focus
必填:是;声明来源:ASAM 声明。
blur
必填:是;声明来源:ASAM 声明。
visibleChange
必填:是;声明来源:ASAM 声明。
expandChange
必填:是;声明来源:ASAM 声明。
removeTag
必填:是;声明来源:ASAM 声明。
AsamCascaderEmits 公开类型视图
import type { AsamCascaderEmits, AsamValue, AsamHierarchyOption, AsamHierarchyEmits } from '@asam-ui/ui';
// AsamCascaderEmits
type PublicContract = {
"update:modelValue": (AsamCascaderEmits)["update:modelValue"];
"change": (AsamCascaderEmits)["change"];
"clear": (AsamCascaderEmits)["clear"];
"focus": [event: FocusEvent];
"blur": [event: FocusEvent];
"visibleChange": [val: boolean];
"expandChange": (AsamCascaderEmits)["expandChange"];
"removeTag": (AsamCascaderEmits)["removeTag"];
};
参数与事件说明
default
必填:否;声明来源:ASAM 声明。
default 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(scope: {
/** Present in normalized modes; native mode retains only the upstream slot fields. */
option?: AsamHierarchyOption; data: AsamCascaderOption; node: AsamCascaderNode; }): unknown
empty
必填:否;声明来源:ASAM 声明。
empty 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
prefix
必填:否;声明来源:ASAM 声明。
prefix 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
header
必填:否;声明来源:ASAM 声明。
header 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
footer
必填:否;声明来源:ASAM 声明。
footer 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
tag
必填:否;声明来源:ASAM 声明。
tag 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(scope: { data: AsamCascaderTag[]; deleteTag: (tag: AsamCascaderTag) => void; }): unknown
suggestion-item
必填:否;声明来源:ASAM 声明。
suggestion-item 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(scope: { item: AsamCascaderNode; }): unknown
AsamCascaderSlots 公开类型视图
import type { AsamCascaderSlots, AsamHierarchyOption, AsamCascaderOption, AsamCascaderNode, AsamCascaderTag } from '@asam-ui/ui';
// AsamCascaderSlots
type PublicContract = {
"default"?: ((scope: {
/** Present in normalized modes; native mode retains only the upstream slot fields. */
option?: AsamHierarchyOption; data: AsamCascaderOption; node: AsamCascaderNode; }) => unknown) | undefined;
"empty"?: (() => unknown) | undefined;
"prefix"?: (() => unknown) | undefined;
"header"?: (() => unknown) | undefined;
"footer"?: (() => unknown) | undefined;
"tag"?: ((scope: { data: AsamCascaderTag[]; deleteTag: (tag: AsamCascaderTag) => void; }) => unknown) | undefined;
"suggestion-item"?: ((scope: { item: AsamCascaderNode; }) => unknown) | undefined;
};
参数与事件说明
focus
必填:是;声明来源:上游声明。
focus 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): void
getCheckedNodes
必填:是;声明来源:上游声明。
getCheckedNodes 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(leafOnly: boolean): AsamCascaderNode[] | undefined
contentRef
必填:是;声明来源:上游声明。
contentRef 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
嵌套展开边界:大型实例类型;完整类型见公开类型视图。
blur
必填:是;声明来源:上游声明。
blur 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): void
cascaderPanelRef
必填:是;声明来源:上游声明。
togglePopperVisible
必填:是;声明来源:上游声明。
togglePopperVisible 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(visible?: boolean | undefined): void
presentText
必填:是;声明来源:上游声明。
AsamCascaderExpose 公开类型视图
import type { AsamCascaderExpose, AsamCascaderNode, AsamHierarchyRuntimeProps } from '@asam-ui/ui';
// AsamCascaderExpose
type PublicContract = {
"focus": () => void;
"getCheckedNodes": (leafOnly: boolean) => AsamCascaderNode[] | undefined;
"contentRef": HTMLElement | undefined;
"blur": () => void;
"cascaderPanelRef": (AsamCascaderExpose)["cascaderPanelRef"];
"togglePopperVisible": (visible?: boolean) => void;
"presentText": string;
};
参数与事件说明
label
必填:是;声明来源:数据 / provider 协议。
value
必填:是;声明来源:数据 / provider 协议。
disabled
必填:否;声明来源:数据 / provider 协议。
disabled 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
raw
必填:是;声明来源:数据 / provider 协议。
children
必填:否;声明来源:数据 / provider 协议。
leaf
必填:否;声明来源:ASAM 声明。
leaf 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
isLeaf
必填:否;声明来源:ASAM 声明。
isLeaf 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
AsamHierarchyOption 公开类型视图
import type { AsamHierarchyOption, AsamValue, AsamOption } from '@asam-ui/ui';
// AsamHierarchyOption
type PublicContract<V extends AsamValue = AsamValue, I extends object = object> = {
readonly "label": string;
readonly "value": V;
readonly "disabled"?: boolean | undefined;
readonly "raw": I;
readonly "children"?: (readonly AsamOption<V, I>[] & readonly AsamHierarchyOption<V, I>[]) | undefined;
readonly "leaf"?: boolean | undefined;
readonly "isLeaf"?: boolean | undefined;
};
AsamCascaderLazyLoad 公开类型视图
import type { AsamCascaderLazyLoad, AsamValue, AsamCascaderNode, AsamHierarchyOption } from '@asam-ui/ui';
// AsamCascaderLazyLoad
type PublicContract<V extends AsamValue = AsamValue, I extends object = object> = {
(node: AsamCascaderNode, resolve: (options?: readonly AsamHierarchyOption<V, I>[]) => void, reject: () => void): void;
};
参数与事件说明
disabled
必填:否;声明来源:上游声明。
disabled 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(data: AsamCascaderOption, node: AsamCascaderNode): boolean
lazy
必填:否;声明来源:上游声明。
lazy 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
value
必填:否;声明来源:上游声明。
label
必填:否;声明来源:上游声明。
checkStrictly
必填:否;声明来源:上游声明。
checkStrictly 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
checkOnClickNode
必填:否;声明来源:上游声明。
checkOnClickNode 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
checkOnClickLeaf
必填:否;声明来源:上游声明。
checkOnClickLeaf 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
multiple
必填:否;声明来源:上游声明。
multiple 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
showPrefix
必填:否;声明来源:上游声明。
showPrefix 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
expandTrigger
必填:否;声明来源:上游声明。
expandTrigger 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"hover" / "click"
emitPath
必填:否;声明来源:上游声明。
emitPath 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
children
必填:否;声明来源:上游声明。
leaf
必填:否;声明来源:上游声明。
leaf 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(data: AsamCascaderOption, node: AsamCascaderNode): boolean
hoverThreshold
必填:否;声明来源:上游声明。
lazyLoad
必填:否;声明来源:ASAM 声明。
lazyLoad 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(node: AsamCascaderNode, resolve: (options?: readonly AsamHierarchyOption<V, I>[] | undefined) => void, reject: () => void): void
AsamCascaderSelectionProps 公开类型视图
import type { AsamCascaderSelectionProps, AsamValue, AsamCascaderOption, AsamCascaderNode, AsamHierarchyRuntimeProps, AsamCascaderLazyLoad, AsamHierarchyOption } from '@asam-ui/ui';
// AsamCascaderSelectionProps
type PublicContract<V extends AsamValue = AsamValue, I extends object = object> = {
"disabled"?: (AsamCascaderSelectionProps<V, I>)["disabled"];
"lazy"?: boolean | undefined;
"value"?: string | undefined;
"label"?: string | undefined;
"checkStrictly"?: boolean | undefined;
"checkOnClickNode"?: boolean | undefined;
"checkOnClickLeaf"?: boolean | undefined;
"multiple"?: boolean | undefined;
"showPrefix"?: boolean | undefined;
"expandTrigger"?: (AsamCascaderSelectionProps<V, I>)["expandTrigger"];
"emitPath"?: boolean | undefined;
"children"?: string | undefined;
"leaf"?: (AsamCascaderSelectionProps<V, I>)["leaf"];
"hoverThreshold"?: number | undefined;
readonly "lazyLoad"?: AsamCascaderLazyLoad<V, I> | undefined;
};
参数与事件说明
effect
必填:否;声明来源:上游声明。
effect 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"light" / "dark"
默认值与来源
未知 / 未声明固定上游源码默认表达式:'light'(2.14.7;源码事实,未作为 ASAM 运行实测)
popperClass
必填:否;声明来源:上游声明。
popperClass 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false
popperStyle
必填:否;声明来源:上游声明。
popperStyle 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false
嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
fallbackPlacements
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游源码默认表达式:['bottom-start', 'bottom', 'top-start', 'top', 'right', 'left'](2.14.7;源码事实,未作为 ASAM 运行实测)
placement
必填:否;声明来源:上游声明。
placement 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"auto" / "auto-start" / "auto-end" / "top" / "bottom" / "right" / "left" / "top-start" / "top-end" / "bottom-start" / "bottom-end" / "right-start" / "right-end" / "left-start" / "left-end"
默认值与来源
未知 / 未声明固定上游源码默认表达式:'bottom-start'(2.14.7;源码事实,未作为 ASAM 运行实测)
persistent
必填:否;声明来源:上游声明。
persistent 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
未知 / 未声明固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
teleported
必填:否;声明来源:上游声明。
teleported 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
disabled
必填:否;声明来源:上游声明。
disabled 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
未知 / 未声明固定上游源码默认表达式:undefined(2.14.7;源码事实,未作为 ASAM 运行实测)
size
必填:否;声明来源:上游声明。
size 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"" / "large" / "default" / "small"
height
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游源码默认表达式:CASCADER_PANEL_HEIGHT(2.14.7;源码事实,未作为 ASAM 运行实测)
props
必填:否;声明来源:上游声明。
props 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
props.expandTrigger:PublicMember<NonNullable<AsamCascaderNativeConfig | undefined>, "expandTrigger">— 上游声明次级菜单的展开方式
固定上游文档默认:
click(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
"hover"/"click"props.multiple:boolean | undefined— 上游声明是否多选
固定上游文档默认:
false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.checkStrictly:boolean | undefined— 上游声明是否严格的遵守父子节点不互相关联
固定上游文档默认:
false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.emitPath:boolean | undefined— 上游声明在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置 false,则只返回该节点的值
固定上游文档默认:
true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.lazy:boolean | undefined— 上游声明是否动态加载子节点,需与 lazyLoad 方法结合使用
固定上游文档默认:
false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.lazyLoad:PublicMember<NonNullable<AsamCascaderNativeConfig | undefined>, "lazyLoad">— 上游声明加载动态数据的方法,仅在 lazy 为 true 时有效 reject 参数在 2.11.5 版本及以上支持。
固定上游文档默认:
未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)事件参数:
(node: AsamCascaderNode, resolve: Parameters<Extract<NonNullable<PublicMember<NonNullable<AsamCascaderNativeConfig | undefined>, "lazyLoad">>, (...args: never[]) => unknown>>[1], reject: () => void): voidprops.value:string | undefined— 上游声明指定选项的值为选项对象的某个属性值
固定上游文档默认:
value(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)props.label:string | undefined— 上游声明指定节点标签为节点对象的某个属性值
固定上游文档默认:
label(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)props.children:string | undefined— 上游声明指定选项的子选项为选项对象的某个属性值
固定上游文档默认:
children(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)props.disabled:PublicMember<NonNullable<AsamCascaderNativeConfig | undefined>, "disabled">— 上游声明指定选项的禁用为选项对象的某个属性值
固定上游文档默认:
disabled(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)事件参数:
(data: AsamCascaderOption, node: AsamCascaderNode): booleanprops.leaf:PublicMember<NonNullable<AsamCascaderNativeConfig | undefined>, "leaf">— 上游声明指定选项的叶子节点的标志位为选项对象的某个属性值
固定上游文档默认:
leaf(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)事件参数:
(data: AsamCascaderOption, node: AsamCascaderNode): booleanprops.hoverThreshold:number | undefined— 上游声明hover 时展开菜单的灵敏度阈值
固定上游文档默认:
500(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)props.checkOnClickNode:boolean | undefined— 上游声明点击节点时是否选中或取消选中该节点
固定上游文档默认:
false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.checkOnClickLeaf:boolean | undefined— 上游声明点击叶节点(最后一个子节点)时是否检查或取消节点
固定上游文档默认:
true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/trueprops.showPrefix:boolean | undefined— 上游声明是否显示单选框或复选框的前缀(图标)
固定上游文档默认:
true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)枚举:
false/true
默认值与来源
未知 / 未声明固定上游源码工厂(未执行):() => ({}) as CascaderProps(2.14.7;源码事实,未作为 ASAM 运行实测)
itemSize
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游源码默认表达式:CASCADER_PANEL_ITEM_SIZE(2.14.7;源码事实,未作为 ASAM 运行实测)
separator
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游源码默认表达式:' / '(2.14.7;源码事实,未作为 ASAM 运行实测)
modelValue
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游源码未声明 default(2.14.7;源码事实,未作为 ASAM 运行实测)
filterMethod
必填:否;声明来源:上游声明。
filterMethod 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(node: AsamCascaderNode, keyword: string): boolean
默认值与来源
未知 / 未声明固定上游源码函数默认值(作为值,不执行):(node: CascaderNode, keyword: string) =>
node.text.includes(keyword)(2.14.7;源码事实,未作为 ASAM 运行实测)
checkOnClickNode
必填:否;声明来源:上游声明。
checkOnClickNode 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
options
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游源码工厂(未执行):() => [] as CascaderOption[](2.14.7;源码事实,未作为 ASAM 运行实测)
emptyValues
必填:否;声明来源:上游声明。
valueOnClear
必填:否;声明来源:上游声明。
valueOnClear 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
valueOnClear.apply:(this: Function, thisArg: any, argArray?: any) => any— 依赖声明调用函数,以指定对象作为 this,并使用指定数组作为函数参数。
事件参数:
(this: Function, thisArg: any, argArray?: any): any嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
valueOnClear.call:(this: Function, thisArg: any, ...argArray: any[]) => any— 依赖声明调用对象方法,并以另一个对象作为当前 this。
事件参数:
(this: Function, thisArg: any, ...argArray: any[]): any嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
valueOnClear.bind:(this: Function, thisArg: any, ...argArray: any[]) => any— 依赖声明创建具有相同函数体的绑定函数,将 this 绑定到指定对象,并设置初始参数。
事件参数:
(this: Function, thisArg: any, ...argArray: any[]): any嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
valueOnClear.toString:() => string— 依赖声明返回函数的字符串表示。
事件参数:
(): string嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
valueOnClear.prototype:any— 依赖声明valueOnClear.length:number— 依赖声明valueOnClear.arguments:any— 依赖声明valueOnClear.caller:Function— 依赖声明嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
valueOnClear.name:string— 依赖声明返回函数名称;函数名称只读,不能修改。
valueOnClear.__@hasInstance@8888:(value: any) => boolean— 依赖声明当函数用作构造函数时,判断指定值是否继承自该函数;构造函数可以覆盖此方法,控制 instanceof 对实例的识别。
事件参数:
(value: any): boolean嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
validateEvent
必填:否;声明来源:上游声明。
validateEvent 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
未知 / 未声明固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
virtualScroll
必填:否;声明来源:上游声明。
virtualScroll 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
clearable
必填:否;声明来源:上游声明。
clearable 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
clearIcon
必填:否;声明来源:上游声明。
clearIcon 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(props: any, ctx: Parameters<Extract<NonNullable<(AsamCascaderNativeProps)["clearIcon"]>, (...args: never[]) => unknown>>[1]): any
clearIcon.__isFragment:undefined— 依赖声明clearIcon.__isTeleport:undefined— 依赖声明clearIcon.__isSuspense:undefined— 依赖声明
默认值与来源
未知 / 未声明固定上游源码默认表达式:CircleClose(2.14.7;源码事实,未作为 ASAM 运行实测)
placeholder
必填:否;声明来源:上游声明。
filterable
必填:否;声明来源:上游声明。
filterable 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
debounce
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游源码默认表达式:300(2.14.7;源码事实,未作为 ASAM 运行实测)
collapseTags
必填:否;声明来源:上游声明。
collapseTags 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
collapseTagsTooltip
必填:否;声明来源:上游声明。
collapseTagsTooltip 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
maxCollapseTags
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游源码默认表达式:1(2.14.7;源码事实,未作为 ASAM 运行实测)
fitInputWidth
必填:否;声明来源:上游声明。
fitInputWidth 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
未知 / 未声明固定上游源码默认表达式:false(2.14.7;源码事实,未作为 ASAM 运行实测)
tagType
必填:否;声明来源:上游声明。
tagType 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"primary" / "success" / "danger" / "warning" / "info"
tagEffect
必填:否;声明来源:上游声明。
tagEffect 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"light" / "dark" / "plain"
showAllLevels
必填:否;声明来源:上游声明。
showAllLevels 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
未知 / 未声明固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
maxCollapseTagsTooltipHeight
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游源码未声明 default(2.14.7;源码事实,未作为 ASAM 运行实测)
beforeFilter
必填:否;声明来源:上游声明。
beforeFilter 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(value: string): boolean | Promise<any>
默认值与来源
未知 / 未声明固定上游源码函数默认值(作为值,不执行):() => true(2.14.7;源码事实,未作为 ASAM 运行实测)
showCheckedStrategy
必填:否;声明来源:上游声明。
showCheckedStrategy 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"parent" / "child"
默认值与来源
未知 / 未声明固定上游源码默认表达式:'child'(2.14.7;源码事实,未作为 ASAM 运行实测)
showPrefix
必填:否;声明来源:上游声明。
showPrefix 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
未知 / 未声明固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
AsamCascaderNativeProps 公开类型视图
import type { Attrs } from 'vue';
import type { AsamCascaderNativeProps, AsamHierarchyRuntimeProps, AsamCascaderNativeConfig, AsamCascaderNode, AsamCascaderOption } from '@asam-ui/ui';
type PublicMember<T, K extends PropertyKey> = T extends unknown ? K extends keyof T ? T[K] : never : never;
// AsamCascaderNativeProps
type PublicContract = {
readonly "effect"?: (AsamCascaderNativeProps)["effect"];
readonly "popperClass"?: (AsamCascaderNativeProps)["popperClass"];
readonly "popperStyle"?: (AsamCascaderNativeProps)["popperStyle"];
readonly "fallbackPlacements"?: (AsamCascaderNativeProps)["fallbackPlacements"];
readonly "placement"?: (AsamCascaderNativeProps)["placement"];
readonly "persistent"?: boolean | undefined;
readonly "teleported"?: boolean | undefined;
readonly "disabled"?: boolean | undefined;
readonly "size"?: "" | "large" | "default" | "small" | undefined;
readonly "height"?: number | undefined;
readonly "props"?: AsamCascaderNativeConfig | undefined;
readonly "itemSize"?: number | undefined;
readonly "separator"?: string | undefined;
readonly "modelValue"?: (AsamCascaderNativeProps)["modelValue"];
readonly "filterMethod"?: ((node: AsamCascaderNode, keyword: string) => boolean) | undefined;
readonly "checkOnClickNode"?: boolean | undefined;
readonly "options"?: AsamCascaderOption[] | undefined;
readonly "emptyValues"?: unknown[] | undefined;
readonly "valueOnClear"?: (AsamCascaderNativeProps)["valueOnClear"];
readonly "validateEvent"?: boolean | undefined;
readonly "virtualScroll"?: boolean | undefined;
readonly "clearable"?: boolean | undefined;
readonly "clearIcon"?: (AsamCascaderNativeProps)["clearIcon"];
readonly "placeholder"?: string | undefined;
readonly "filterable"?: boolean | undefined;
readonly "debounce"?: number | undefined;
readonly "collapseTags"?: boolean | undefined;
readonly "collapseTagsTooltip"?: boolean | undefined;
readonly "maxCollapseTags"?: number | undefined;
readonly "fitInputWidth"?: number | boolean | undefined;
readonly "tagType"?: "primary" | "success" | "danger" | "warning" | "info" | undefined;
readonly "tagEffect"?: "light" | "dark" | "plain" | undefined;
readonly "showAllLevels"?: boolean | undefined;
readonly "maxCollapseTagsTooltipHeight"?: string | number | undefined;
readonly "beforeFilter"?: ((value: string) => boolean | Promise<any>) | undefined;
readonly "showCheckedStrategy"?: "parent" | "child" | undefined;
readonly "showPrefix"?: boolean | undefined;
};