- 前端
- UI组件
- 移动开发
【免费下载链接】cube-ui
:large_orange_diamond: A fantastic mobile ui lib implement by Vue
在 cube-ui 中,通过
$createXxx系列 API 调用 Toast、Dialog、Picker 等弹层类组件时,会涉及单例(singleton)与多例(multiton)两种实例化策略。本指南以官方文档 Singleton Pattern 为主体,结合 create-api 实现 与各组件模块源码,系统梳理这两种模式的定义方式、1.11 版本前后的行为差异、默认取值,以及如何在实例化时按需切换,帮助你在业务中准确预判弹层实例的复用与隔离行为。
什么是组件的单例与多例模式
在通过 API 方式(而非模板方式)调用组件时,cube-ui 会针对每一个调用创建对应的组件实例与视图层。所谓"单例 / 多例",指的是多次实例化同一个组件时,实例与视图层的数量关系:
- 单例(singleton):在同一个组件(component)作用域内多次实例化,最终只存在一个实例、一个对应的视图层。后续调用会复用此前创建的实例与视图。
- 多例(multiton):每一次实例化都会新建一个独立实例,对应多个互不影响、各自独立的视图层。
说明:在 1.11 版本之前,单例的约束范围没有明确限定为"同一组件内",即全局范围内同一组件只会有一个实例;1.11 起语义收紧为"同一组件内",不同组件各自维护自己的单例实例(详见下文版本差异)。
这一机制直接决定了你的业务代码中多次弹出同一弹层时,是"共用一个实例、重复使用"还是"各自独立、可同时存在多个",是使用 API 调用组件时必须理解的核心行为。
哪些组件涉及单例/多例
在 cube-ui 中,所有通过 API 调用的组件都是弹层类(popup)组件,其中最常用的是:
- Toast
- Picker
- TimePicker
- Dialog
- ActionSheet
这些组件的 API 能力统一由createAPI函数提供,而组件是否为单例,在组件定义(注册 API 时)就已经决定。例如:
- toast 的 API 注册 中调用
createAPI(Vue, Toast, ['timeout'], true),true表示单例; - dialog 的 API 注册 中调用
createAPI(Vue, Dialog, [...], true),同样为单例; - action-sheet 的 API 注册 中调用
createAPI(Vue, ActionSheet, ['select', 'cancel'], true),也是单例; - 而 picker 的 API 注册 与 time-picker 的 API 注册 中
createAPI(...)未传入该参数,默认即为多例。
createAPI内部通过vue-create-api插件(见 create-api.js)为组件挂载$createXxx方法,因此所有 API 调用最终都汇聚到同一套单例/多例判定逻辑上。
1.11 版本前后的行为差异
1.11 及以后(推荐语义)
自 1.11 起,单例的判定范围明确为同一个组件内:
- 若组件为单例,在同一组件内多次实例化,只会存在一个实例与一个视图层;
- 若组件为多例,每次实例化都会新建实例,多个视图层互不影响。
也就是说,不同业务组件各自维护自己的单例实例,A 组件里弹出的 Toast 与 B 组件里弹出的 Toast 是相互独立的两个实例,避免跨组件状态串扰。
1.11 之前(旧语义)
在 1.11 之前,单例的判定没有"同一组件内"的限定:
- 若组件为单例,全局范围内多次实例化只会存在一个实例与一个视图层;
- 若组件为多例,每次实例化都会新建实例,多个视图层互不影响。
如果你的项目还停留在 1.11 之前的版本,需要留意这种全局复用的语义;升级到 1.11 及以上后,单例语义更精确,也更适合大型业务中多页面/多组件各自管理弹层。
默认的单例/多例配置
cube-ui 对常用弹层组件的默认行为做了差异化设计,原则是"简单高频的弹层用单例,复杂低频的用多例":
| 组件 | 默认模式 | 原因 |
|---|---|---|
| Toast | 单例 | 提示类场景简单、高频,复用一个实例即可 |
| Dialog | 单例 | 对话框场景简单,通常同时只出现一个 |
| ActionSheet | 单例 | 操作面板场景简单,通常同时只出现一个 |
| Picker | 多例 | 场景更复杂,常伴随大量额外数据处理,可能需要同时存在多个 |
| TimePicker | 多例 | 同 Picker,场景复杂,需要各自独立的实例 |
这一默认设计在源码中有直接对应:单例组件在注册 API 时传入true(如 toast/api.js、dialog/api.js、action-sheet/api.js),多例组件不传该参数(如 picker/api.js、time-picker/api.js)。
注意:出于 Picker 与 TimePicker 的场景复杂度考虑,这两个组件不支持单例模式。如果你强行向$createPicker/$createTimePicker传入单例参数,开发环境下会触发 cube-ui 的提示(详见下文)。
如何在实例化时切换单例/多例
虽然默认行为在组件定义时已确定,但 cube-ui 允许你在实例化时通过$createXxx的第二个参数临时覆盖:
const dialog = this.$createDialog({ type: 'confirm', title: 'title', content: 'content' }, false) dialog.show()上面这段代码把本应默认为单例的 Dialog 显式改为多例(false):每调用一次$createDialog都会生成独立的 Dialog 实例,多个实例的视图层互不影响,可同时存在多个对话框。
$createXxx(配置对象, single)中第二个参数single的取值含义:
- 不传或传
true:按组件默认模式(单例组件为单例); - 传
false:强制使用多例模式,每次调用创建新实例。
在常规业务中,默认行为已能满足绝大多数需求,只有在你有特殊需求(例如需要同时展示多个互不干扰的对话框、或需要独立管理各自状态的弹层)时才需要显式传入false。
在实例化时传入 single 参数的源码实现与限制
$createXxx的第二个参数最终会传递到createAPI的底层判定逻辑中。以 Picker / TimePicker 为例,源码中注册了一个before钩子来拦截单例请求(见 picker/api.js 与 time-picker/api.js):
const pickerAPI = createAPI(Vue, Picker, ['select', 'value-change', 'cancel', 'change']) pickerAPI.before((data, renderFn, single) => { if (single) { tip('Picker component can not be a singleton.') } })当single为真(即调用方尝试把 Picker 当作单例)时,会通过tip打印一条开发期警告Picker component can not be a singleton.(TimePicker 同理)。tip来自 debug.js,仅在非生产环境下输出,因此该限制是运行时的软约束:开发环境会得到警告,生产环境静默——但请务必不要依赖这种"能跑就行"的写法,应始终遵守"Picker / TimePicker 不支持单例"的既定契约。
在示例项目中观察单例/多例的实际使用
cube-ui 的 example 项目大量使用了$createXxxAPI,可作参考:
- action-sheet.vue 示例页:通过
this.$createActionSheet({...})创建操作面板,配合$createToast使用,ActionSheet 默认为单例; - picker.vue 示例页:多次调用
this.$createPicker({...})创建不同的 Picker(普通、多列、字段别名、动态数据等),得益于多例模式,各 Picker 实例相互独立,可以分别维护数据与状态; - cascade-picker.vue、date-picker.vue 等页面也展示了
$createDialog与$createToast的组合使用。
这些示例印证了上述默认行为:复杂选择类组件(Picker 系)因多例而彼此独立,简单提示类组件(Toast/Dialog/ActionSheet)因单例而复用实例。
总结:如何选择单例还是多例
在实际业务中,可以按以下准则决策:
- 优先使用默认行为:Toast、Dialog、ActionSheet 用单例,Picker、TimePicker 用多例,通常无需改动;
- 需要同时展示多个同类型弹层(例如两个互不影响的确认框、多个独立的操作面板),给单例组件显式传入
false; - 不要尝试把 Picker / TimePicker 变为单例,它们的设计不支持该模式,强行使用会触发开发期警告;
- 注意版本语义:1.11 之前单例为全局唯一,1.11 及以后单例限定在"同一组件内",升级后需复核弹层实例的复用边界是否符合预期。
- 前端
- UI组件
- 移动开发
【免费下载链接】cube-ui
:large_orange_diamond: A fantastic mobile ui lib implement by Vue
相关推荐
cube-ui 单例模式解析:API 调用组件的实例与视图管理机制
cube ui 单例模式解析:API 调用组件的实例与视图管理机制 本文以 document/components/docs/zh CN/singleton.m
前端UI组件移动开发spin.js中的Singleton Pattern:单例模式测试
spin.js中的Singleton Pattern:单例模式测试 你是否曾在开发中遇到过这样的困扰:页面同时加载多个加载动画(Spinner)导致DOM混乱?
UI组件前端cube-ui 移动端组件库全览:组件体系、双调用模式与核心模块解析
cube ui 移动端组件库全览:组件体系、双调用模式与核心模块解析 cube ui 是滴滴出行团队基于 Vue.js 实现的精致移动端组件库,从内部业务组件库
前端UI组件移动开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考