Appearance
BizBankBranchSelect 联行号选择
联行号选择器:只读触发框(银行 · 网点 + 12 位联行号次行等宽展示)+ 弹层两段式面板——上段银行分组网格(热门置顶行 + 其余网格,单字符图标 + 名称,选中高亮)、下段网点检索(名称 / 联行号 / 全拼与首字母,防抖 300ms)+ 分页列表。支持 remoteMethod 远程检索(银行选择仅对返回结果按 bankKey 前端过滤)、banks / branches 全量数据注入。收款户名开户网点、代发工资、转账汇款等场景的联行号录入。
基础用法
当前选中:(未选择)
联行号:—
点击触发框展开面板:先选银行,再检索或浏览网点列表,选中回填银行、网点全称与 12 位联行号。
<script setup lang="ts">
/** 场景:基础——选银行 + 选开户网点,回填联行号 */
import { ref } from 'vue'
import { BizBankBranchSelect } from 'vue3-ep-biz-lib'
import type { BizBranchValue } from 'vue3-ep-biz-lib'
const value = ref<BizBranchValue | null>(null)
</script>
<template>
<div>
<BizBankBranchSelect v-model="value" />
<p style="margin: 10px 0 0; font-size: 12px; color: var(--el-text-color-secondary)">
当前选中:{{ value === null ? '(未选择)' : `${value.bank} · ${value.branch}` }}
<br />
联行号:{{ value === null ? '—' : value.cnaps }}
</p>
</div>
</template>
显示代码
热门银行
前 3 家标记为热门银行,在面板置顶行一排展示;当前选中:(未选择)
banks 数据带 hot: true 的银行在置顶行紧凑展示(内置数据前 6 家默认热门)。<script setup lang="ts">
/** 场景:热门银行——hot 置顶行紧凑展示 */
import { ref } from 'vue'
import { BizBankBranchSelect } from 'vue3-ep-biz-lib'
import type { BizBankOption, BizBranchOption, BizBranchValue } from 'vue3-ep-biz-lib'
const value = ref<BizBranchValue | null>(null)
/* 自定义热门标记:仅前 3 家置顶 */
const banks: BizBankOption[] = [
{ key: 'icbc', name: '工商银行', hot: true, icon: '工' },
{ key: 'cmb', name: '招商银行', hot: true, icon: '招' },
{ key: 'ccb', name: '建设银行', hot: true, icon: '建' },
{ key: 'abc', name: '农业银行', icon: '农' },
{ key: 'boc', name: '中国银行', icon: '中' },
{ key: 'psbc', name: '邮储银行', icon: '邮' },
]
const branches: BizBranchOption[] = [
{ cnaps: '102110001001', name: '中国工商银行股份有限公司北京分行', bankKey: 'icbc', city: '北京', pinyin: 'beijingfenhangbjfh' },
{ cnaps: '308158400001', name: '招商银行股份有限公司深圳分行', bankKey: 'cmb', city: '深圳', pinyin: 'shenzhenfenhangszfh' },
{ cnaps: '105110000001', name: '中国建设银行股份有限公司天津分行', bankKey: 'ccb', city: '天津', pinyin: 'tianjinfenhangtjfh' },
{ cnaps: '103129000001', name: '中国农业银行股份有限公司上海分行', bankKey: 'abc', city: '上海', pinyin: 'shanghaifenhangshfh' },
{ cnaps: '104129000002', name: '中国银行股份有限公司上海分行', bankKey: 'boc', city: '上海', pinyin: 'shanghaifenhangshfh' },
{ cnaps: '403129000003', name: '中国邮政储蓄银行股份有限公司上海分行', bankKey: 'psbc', city: '上海', pinyin: 'shanghaifenhangshfh' },
]
</script>
<template>
<div>
<BizBankBranchSelect v-model="value" :banks="banks" :branches="branches" />
<p style="margin: 10px 0 0; font-size: 12px; color: var(--el-text-color-secondary)">
前 3 家标记为热门银行,在面板置顶行一排展示;当前选中:{{ value === null ? '(未选择)' : value.branch }}
</p>
</div>
</template>
显示代码
拼音检索
打开面板后在检索框输入(试试:shenzhen / szfh / 北京 / 3081)——全拼「shenzhen」、 首字母「szfh」(深圳分行)、中文名「北京」、联行号前缀「3081」(招商银行行别码)、网点拼音「kejiyuan」(科技园支行)均可命中。
检索框支持网点名称、拼音全拼(如
shenzhen)、拼音首字母(如 szfh)与联行号子串,防抖 300ms。<script setup lang="ts">
/** 场景:拼音检索——全拼 / 首字母 / 联行号子串 */
import { ref } from 'vue'
import { BizBankBranchSelect } from 'vue3-ep-biz-lib'
import type { BizBranchValue } from 'vue3-ep-biz-lib'
const value = ref<BizBranchValue | null>(null)
const keyword = ref('')
</script>
<template>
<div>
<BizBankBranchSelect v-model="value" />
<el-space style="margin-top: 10px" wrap>
<el-button
v-for="word in ['shenzhen', 'szfh', '北京', '3081', 'kejiyuan']"
:key="word"
size="small"
@click="keyword = word"
>
{{ word }}
</el-button>
</el-space>
<p style="margin: 8px 0 0; font-size: 12px; color: var(--el-text-color-secondary)">
打开面板后在检索框输入(试试:{{ keyword === '' ? 'shenzhen / szfh / 北京 / 3081' : keyword }})——全拼「shenzhen」、
首字母「szfh」(深圳分行)、中文名「北京」、联行号前缀「3081」(招商银行行别码)、网点拼音「kejiyuan」(科技园支行)均可命中。
</p>
</div>
</template>
显示代码
远程检索
检索输入后走远程(600ms 模拟延迟,面板显示 loading);切换银行不再请求,仅对返回结果按 bankKey 过滤。 当前选中:(未选择)
注入
remoteMethod 后检索走远程(loading 态);银行选择仅对返回结果按 bankKey 前端过滤。<script setup lang="ts">
/** 场景:远程检索——remoteMethod 注入(setTimeout 模拟),银行仅前端过滤返回结果 */
import { onUnmounted, ref } from 'vue'
import { BizBankBranchSelect } from 'vue3-ep-biz-lib'
import type { BizBranchOption, BizBranchValue } from 'vue3-ep-biz-lib'
const value = ref<BizBranchValue | null>(null)
let timer: ReturnType<typeof setTimeout> | null = null
/* 模拟全量网点库(生产替换为真实接口) */
const ALL: BizBranchOption[] = [
{ cnaps: '308158400001', name: '招商银行股份有限公司深圳分行', bankKey: 'cmb', city: '深圳', pinyin: 'zhaoshangshenzhenfenhangzsyhszfh' },
{ cnaps: '308110000001', name: '招商银行股份有限公司北京分行', bankKey: 'cmb', city: '北京', pinyin: 'zhaoshangbeijingfenhangzsyhbjfh' },
{ cnaps: '308129000001', name: '招商银行股份有限公司上海分行', bankKey: 'cmb', city: '上海', pinyin: 'zhaoshangshanghaifenhangzsyhshfh' },
{ cnaps: '102158400001', name: '中国工商银行股份有限公司深圳分行', bankKey: 'icbc', city: '深圳', pinyin: 'gongshangshenzhenfenhanggsszfh' },
{ cnaps: '102110000002', name: '中国工商银行股份有限公司北京分行', bankKey: 'icbc', city: '北京', pinyin: 'gongshangbeijingfenhanggsbjfh' },
{ cnaps: '105158400001', name: '中国建设银行股份有限公司深圳分行', bankKey: 'ccb', city: '深圳', pinyin: 'jiansheshenzhenfenhangjsszfh' },
{ cnaps: '105158100002', name: '中国建设银行股份有限公司广州分行', bankKey: 'ccb', city: '广州', pinyin: 'jiansheguangzhoufenhangjsgzfh' },
]
const remoteMethod = (query: string): Promise<BizBranchOption[]> =>
new Promise((resolve) => {
if (timer !== null) clearTimeout(timer)
timer = setTimeout(() => {
const q = query.trim().toLowerCase()
resolve(
ALL.filter(
(b) =>
q === '' ||
b.name.includes(query.trim()) ||
b.cnaps.includes(query.trim()) ||
(b.pinyin ?? '').includes(q),
),
)
}, 600)
})
onUnmounted(() => {
if (timer !== null) clearTimeout(timer)
})
</script>
<template>
<div>
<BizBankBranchSelect v-model="value" :remote-method="remoteMethod" />
<p style="margin: 10px 0 0; font-size: 12px; color: var(--el-text-color-secondary)">
检索输入后走远程(600ms 模拟延迟,面板显示 loading);切换银行不再请求,仅对返回结果按 bankKey 过滤。
当前选中:{{ value === null ? '(未选择)' : `${value.bank} · ${value.cnaps}` }}
</p>
</div>
</template>
显示代码
自定义数据
注入城商行数据(2 家银行 6 个网点),完全替换内置示例;当前选中:(未选择)
banks + branches 注入业务全量数据,完全替换内置示例(pinyin 字段用于拼音检索)。<script setup lang="ts">
/** 场景:自定义数据——banks + branches 全量注入替换内置数据 */
import { ref } from 'vue'
import { BizBankBranchSelect } from 'vue3-ep-biz-lib'
import type { BizBankOption, BizBranchOption, BizBranchValue } from 'vue3-ep-biz-lib'
const value = ref<BizBranchValue | null>(null)
/* 城商行示例:两家城市商业银行 + 各 3 个网点 */
const banks: BizBankOption[] = [
{ key: 'bob', name: '北京银行', hot: true, icon: '北' },
{ key: 'sdb', name: '上海银行', icon: '上' },
]
const branches: BizBranchOption[] = [
{ cnaps: '313100000001', name: '北京银行股份有限公司营业部', bankKey: 'bob', city: '北京', pinyin: 'beijingyingyebubjyyb' },
{ cnaps: '313100000002', name: '北京银行股份有限公司中关村支行', bankKey: 'bob', city: '北京', pinyin: 'zhongguancunzhihangzgczh' },
{ cnaps: '313100000003', name: '北京银行股份有限公司城市副中心支行', bankKey: 'bob', city: '北京', pinyin: 'chengshifuzhongxinzhihangcsfzxzh' },
{ cnaps: '313290000001', name: '上海银行股份有限公司营业部', bankKey: 'sdb', city: '上海', pinyin: 'shanghaiyingyebushyyb' },
{ cnaps: '313290000002', name: '上海银行股份有限公司浦东支行', bankKey: 'sdb', city: '上海', pinyin: 'pudongzhihangpdzh' },
{ cnaps: '313290000003', name: '上海银行股份有限公司自贸试验区分行', bankKey: 'sdb', city: '上海', pinyin: 'zimaoshiyanqufenhangzmsyqfh' },
]
</script>
<template>
<div>
<BizBankBranchSelect v-model="value" :banks="banks" :branches="branches" />
<p style="margin: 10px 0 0; font-size: 12px; color: var(--el-text-color-secondary)">
注入城商行数据(2 家银行 6 个网点),完全替换内置示例;当前选中:{{
value === null ? '(未选择)' : `${value.branch} / ${value.cnaps}`
}}
</p>
</div>
</template>
显示代码
分页
当前 page-size:5;工商银行 7 条数据在每页 5 条下可翻页。
page-size 控制每页条数(默认 20),底部简易分页;page-size 置 0 全量展示不分页。<script setup lang="ts">
/** 场景:分页——page-size 翻页与 0 全量展示 */
import { ref } from 'vue'
import { BizBankBranchSelect } from 'vue3-ep-biz-lib'
import type { BizBranchValue } from 'vue3-ep-biz-lib'
const value = ref<BizBranchValue | null>(null)
const pageSize = ref(5)
</script>
<template>
<div>
<el-space style="margin-bottom: 10px" wrap>
<el-radio-group v-model="pageSize" size="small">
<el-radio-button :value="5">每页 5 条</el-radio-button>
<el-radio-button :value="20">每页 20 条</el-radio-button>
<el-radio-button :value="0">不分页</el-radio-button>
</el-radio-group>
</el-space>
<BizBankBranchSelect v-model="value" :page-size="pageSize" />
<p style="margin: 10px 0 0; font-size: 12px; color: var(--el-text-color-secondary)">
当前 page-size:{{ pageSize === 0 ? '0(全量不分页,隐藏底部分页条)' : pageSize }};工商银行 7 条数据在每页 5 条下可翻页。
</p>
</div>
</template>
显示代码
自定义选项
option 插槽参数:branch(网点对象)/ index(当前页序号);当前选中:(未选择)
option 插槽自定义选项行(作用域插槽参数 branch / index)。<script setup lang="ts">
/** 场景:自定义选项——option 作用域插槽改写选项行 */
import { ref } from 'vue'
import { BizBankBranchSelect } from 'vue3-ep-biz-lib'
import type { BizBranchValue } from 'vue3-ep-biz-lib'
const value = ref<BizBranchValue | null>(null)
</script>
<template>
<div>
<BizBankBranchSelect v-model="value">
<template #header>
<div
style="
padding: 6px 8px;
margin-bottom: 8px;
border-radius: var(--el-border-radius-small);
background-color: var(--el-color-primary-light-9);
font-size: 12px;
color: var(--el-color-primary);
"
>
header 插槽:请选择收款方开户网点(大额转账建议核对联行号)
</div>
</template>
<template #option="{ branch, index }">
<span style="flex: 1; min-width: 0; display: inline-flex; align-items: center; gap: 6px">
<el-tag size="small" type="info" effect="plain">{{ index + 1 }}</el-tag>
<span style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">{{
branch.name
}}</span>
</span>
<el-tag size="small" type="success" effect="plain">{{ branch.city ?? '—' }}</el-tag>
</template>
</BizBankBranchSelect>
<p style="margin: 10px 0 0; font-size: 12px; color: var(--el-text-color-secondary)">
option 插槽参数:branch(网点对象)/ index(当前页序号);当前选中:{{
value === null ? '(未选择)' : value.branch
}}
</p>
</div>
</template>
显示代码
事件
v-model:(未选择)
最近一次 change:(无)
change 回传完整网点对象(cnaps / name / bankKey / city / pinyin),清空时回传 null。<script setup lang="ts">
/** 场景:事件——change 回传完整网点对象(清空回传 null) */
import { ref } from 'vue'
import { BizBankBranchSelect } from 'vue3-ep-biz-lib'
import type { BizBranchOption, BizBranchValue } from 'vue3-ep-biz-lib'
const value = ref<BizBranchValue | null>(null)
const last = ref<BizBranchOption | null>(null)
const onChange = (branch: BizBranchOption | null): void => {
last.value = branch
}
</script>
<template>
<div>
<BizBankBranchSelect v-model="value" @change="onChange" />
<p style="margin: 10px 0 0; font-size: 12px; color: var(--el-text-color-secondary); line-height: 1.8">
v-model:{{ value === null ? '(未选择)' : `${value.bank} / ${value.branch}` }}<br />
最近一次 change:{{
last === null ? '(无)' : `${last.name}|${last.city ?? '—'}|${last.cnaps}|bankKey=${last.bankKey}`
}}
</p>
</div>
</template>
显示代码
清空与禁用
左侧:外部预填值,悬浮触发框出现 × 角标,点击即清空(v-model 置 null)
右侧:disabled 禁用态,无法展开面板
clearable 悬浮显示一键清空角标(默认开启);disabled 禁用触发框。<script setup lang="ts">
/** 场景:清空与禁用——clearable 角标 + disabled 禁用 */
import { ref } from 'vue'
import { BizBankBranchSelect } from 'vue3-ep-biz-lib'
import type { BizBranchValue } from 'vue3-ep-biz-lib'
const enabled = ref<BizBranchValue | null>({
bank: '招商银行',
branch: '招商银行股份有限公司深圳分行',
cnaps: '308158400001',
})
const disabledValue = ref<BizBranchValue | null>({
bank: '工商银行',
branch: '中国工商银行股份有限公司北京分行',
cnaps: '102110000001',
})
const clearAll = (): void => {
enabled.value = null
}
</script>
<template>
<div>
<el-space wrap>
<BizBankBranchSelect v-model="enabled" />
<BizBankBranchSelect v-model="disabledValue" disabled />
</el-space>
<p style="margin: 10px 0 0; font-size: 12px; color: var(--el-text-color-secondary); line-height: 1.8">
左侧:外部预填值,悬浮触发框出现 × 角标,点击即清空(v-model 置 null)<br />
右侧:disabled 禁用态,无法展开面板
<el-button size="small" style="margin-left: 8px" @click="clearAll">外部置空同步</el-button>
</p>
</div>
</template>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| v-model | BizBranchValue | null | null | 选中值(bank / branch / cnaps 三元组) |
| banks | BizBankOption[] | 内置 14 家 | 银行列表(key / name / hot / icon) |
| branches | BizBranchOption[] | 内置 79 条示例 | 网点列表(cnaps / name / bankKey / city / pinyin) |
| remote-method | (query: string) => Promise<BizBranchOption[]> | — | 远程检索;注入后检索走远程 |
| placeholder | string | '请选择开户银行网点' | 触发框占位 |
| disabled | boolean | false | 禁用 |
| clearable | boolean | true | 显示清空角标 |
| page-size | number | 20 | 每页条数;0 不分页 |
| no-data-text | string | '未找到匹配网点' | 空态文案 |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| update:modelValue | (value: BizBranchValue | null) | 选中值变化(选中或清空) |
| change | (branch: BizBranchOption | null) | 选中(含完整网点对象)或清空 |
Slots
| 插槽名 | 参数 | 说明 |
|---|---|---|
| header | — | 弹层顶部自定义内容 |
| option | { branch: BizBranchOption, index: number } | 自定义选项行 |
Expose
| 名称 | 类型 | 说明 |
|---|---|---|
| getBranch | () => BizBranchOption | null | 取当前选中网点对象 |
| open / close | () => void | 弹层开合控制 |
| clear | () => void | 清空选中值 |
| getSelected | () => BizBranchValue | null | 取当前选中值三元组 |