Skip to content

全局弹框

本节讲基础库中的弹框模块

准备工作

安装Jiess时,通常会将弹框的操作实例注入上下文

javascript
import { h, reactive, withDirectives } from 'vue';
import { $entry } from '@jiess/plus';
// 导入vue3的环境对象,react同理
import JiessEnv from '@jiess/plus/vue3';
// 从基础库导入弹框相关的实例
import { $tanInstance, $dialogInstance } from '@/.jiess';

const jiess = $entry(JiessEnv, 
// 静态注入到jiess实例中
{
	h,
	reactive,
	withDirectives
}, 
// 动态注入到组件上下文中
{
	// 注入高级弹框实例
	tan: $tanInstance,
	// 注入通用弹框实例
	dialog: $dialogInstance,
});

接下来,在项目根节点,安装全局弹框

在项目根节点使用弹框,可以确保全局的共享和全局唯一

基础介绍

不同的弹框,往往需要单独的定义,因为很难通过配置来应对变化无穷的弹框内容

思考一下

一个中等的项目,通常会用到上百个弹框;因此,就需要定义定义上百次,而每个弹框都有自己的弹出, 关闭,需要定义相应的变量与方法,以及一系列的交互逻辑...

其实,抛开弹框内容,就弹框本身的交互逻辑而言,其代码是相似的;所以在项目中, 反复的定义弹框,就一定会产生许多冗余的代码

使用dialog开启弹框

js
function setup() {
	this.add(
		this.render({
			is: 'button',
			onClick: () => {
				// 点击按钮,唤醒弹框
				this.dialog(show => {
					return {
						title: '弹框标题',
						width: '1080px',
						children: '这是弹框的内容'
					}
				});
			}
		}, '点击打开弹框')
	)
}

注:示例中的show为Jiess响应式,用于控制弹框的关闭

JiessDialog组件特点

  • 将需要渲染的弹出内容封装为组件,在组件中开辟单独的空间,在弹框中渲染
  • 支持弹出任意层数,也可以任意关闭弹层,彻底破除弹出层级的限制

dialog 方法

在前面安装Jiess的过程中,已在上下文挂载了dialog方法, 通过上下文调用dialog方法,便可以获取全局的弹框单例

js
function setup() {
	// 通过上下文调用dialog方法
	const instance = this.dialog();
	// 使用dialog操作对象
	dialog.open(config);
}

直接调用dialog方法,并传入配置函数,会默认执行instance.open()方法

js
function setup() {
	// 通过上下文调用dialog方法
	// 如果传入参数调用,则自动调用instance.open
	this.dialog(show => {
		return {
			title: '弹框标题',
			children: '弹框内容'
		}
	});
}

instance对象

弹框的instance是用于操作弹框的单例,提供如下方法:

open

  • 类型 Function
  • 参数 (param = show => {}, ...arg)
  • 返回
  • 详细

用于新开启一个弹框,首参param为弹框必要配置函数,后面参数为弹框内子元素

注:param为函数类型,并提供响应式对象show,可以关闭弹框

close

  • 类型 Function
  • 参数 (show)
  • 返回
  • 详细

关闭弹框,通过使用回调函数中的响应式对象show,关闭弹框

closeAll

  • 类型 Function
  • 参数 无
  • 返回
  • 详细

直接关闭所有弹框

开启弹框

首先是一个基础弹框的例子

js
function setup() {
	this.add(
		this.render({
			is: 'button',
			onClick: () => {
				this.dialog(show => {
					return {
						title: '基础弹框示例',
						children: [
							'弹框中的内容',
							// 使用vue2组件的footer插槽渲染底部按钮
							this.render({ slot: 'footer' },
								this.render({
									is: 'button',
									onClick: () => {
										// 点击确认按钮关闭
										show.value = false
									}
								}, '确定')
							)
						]
					};
				})
			}
		}, '点击弹框')
	)
}
js
function setup() {
	this.add(
		this.render({
			is: 'button',
			onClick: () => {
				this.dialog(show => {
					return {
						title: '基础弹框示例',
						$slots: {
							// 使用vue3组件的footer插槽渲染底部按钮
							footer: () => this.render({
								is: 'button',
								onClick: () => {
									// 点击确认按钮关闭
									show.value = false
								}
							}, '确定')
						},
						children: '弹框中的内容'
					};
				})
			}
		}, '点击弹框')
	)
}
js
function setup() {
	this.add(
		this.render({
			is: 'button',
			onClick: () => {
				this.dialog(show => {
					return {
						title: '基础弹框示例',
						children: '弹框中的内容',
						onOk: () => {
							// 点击确认按钮关闭
							show.value = false
						}
					};
				})
			}
		}, '点击弹框')
	)
}

接下来是一个开启无限极弹出的例子

js
import { Button } from 'element-ui';

export default function() {
	let level = 1;
	const area = this.area({ header: '无限弹框示例' });
	const config = (show) => ({
		title: `当前层级【第${level++}层】`,
		children: [
			this.render({
				is: Button,
				children: '新弹出一层',
				onClick: () => this.dialog(config)
			}),
			this.render({
				is: Button,
				children: '关闭当前层',
				onClick: () => show.value = false
			}),
			this.render({
				is: Button,
				children: '关闭最上层',
				onClick: () => this.dialog().close()
			}),
			this.render({
				is: Button,
				children: '关闭所有层',
				onClick: () => {
					level = 1;
					this.dialog().closeAll();
				},
			})
		]
	});
	area.add(
		this.render({
			is: Button,
			type: 'primary',
			children: '开启无限弹框',
			onClick: () => this.dialog(config),
		}),
	).done();
}
js
import { ElButton } from 'element-plus';

export default function() {
	let level = 1;
	const area = this.area({ header: '无限弹框示例' });
	const config = (show) => ({
		title: `当前层级【第${level++}层】`,
		children: [
			this.render({
				is: ElButton,
				children: '新弹出一层',
				onClick: () => this.dialog(config)
			}),
			this.render({
				is: ElButton,
				children: '关闭当前层',
				onClick: () => show.value = false
			}),
			this.render({
				is: ElButton,
				children: '关闭最上层',
				onClick: () => this.dialog().close()
			}),
			this.render({
				is: ElButton,
				children: '关闭所有层',
				onClick: () => {
					level = 1;
					this.dialog().closeAll();
				},
			})
		]
	});
	area.add(
		this.render({
			is: ElButton,
			type: 'primary',
			children: '开启无限弹框',
			onClick: () => this.dialog(config),
		}),
	).done();
}
js
import { Button } from 'antd';

function setup() {
	let level = 1;
	const area = this.area({ title: '无限弹框示例' });
	const config = (show) => ({
		title: `当前层级【第${level++}层】`,
		children: [
			this.render({
				is: Button,
				children: '新弹出一层',
				onClick: () => this.dialog(config)
			}),
			this.render({
				is: Button,
				children: '关闭当前层',
				onClick: () => show.value = false
			}),
			this.render({
				is: Button,
				children: '关闭最上层',
				onClick: () => this.dialog().close()
			}),
			this.render({
				is: Button,
				children: '关闭所有层',
				onClick: () => {
					level = 1;
					this.dialog().closeAll();
				},
			})
		]
	});
	area.add(
		this.render({
			is: Button,
			type: 'primary',
			children: '开启无限弹框',
			onClick: () => this.dialog(config),
		}),
	).done();
}

全局无限制弹框的示例

查看示例


$tan 方法

在前面安装Jiess的过程中,已在上下文挂载了$tan方法,同样可通过上下文调用; $tan是基于dialog的深度封装,也称为高级弹框

获取tanInstance单例

js
function setup() {
	const tanInstance = this.$tan();
	// 使用dialog操作对象
	tanInstance.alert({...config});
}

传入配置对象,执行tanInstance.alert

js
function setup() {
	// 自动调用tanInstance.alert()方法
	this.$tan({
		title: '弹框标题',
		width: '1080px',
		children: '这是弹框的内容',
	});
}

高级弹框使用示例

js
function setup() {
	this.add(
		this.render({
			is: 'button',
			onClick: () => {
				// 点击按钮,弹出弹框
				this.$tan.alert({
					title: '弹框标题',
					width: '1080px',
					children: '这是弹框的内容',
					buttons: (close, show) => {
						// 数组中的元素为按钮配置,使用时结合各自UI按钮按钮文档配置
						return [{
								type: 'primary',
								text: '确定',
								onClick: () => {
									// 打开第二层弹框
									this.$tan.alert({
										title: '提示',
										children: '您点击了确定按钮',
										onClose: (innerClose) => {
											// 关闭二层弹框
											innerClose();
											// 关闭外层弹框
											close();
										}
									})
								}
							},
							// 这里没有绑定事件,则点击触发关闭事件
							{ type: 'primary', text: '关闭' }
						]
					}
				});
			}
		}, '点击打开弹框')
	)
}
js
function setup() {
	this.add(
		this.render({
			is: 'button',
			onClick: () => {
				// 点击按钮,弹出弹框
				this.$tan.alert({
					title: '弹框标题',
					width: '1080px',
					children: '这是弹框的内容',
					buttons: (close, show) => {
						// 数组中的元素为按钮配置,使用时结合各自UI按钮按钮文档配置
						return [{
								type: 'primary',
								text: '确定',
								onClick: () => {
									// 打开第二层弹框
									this.$tan.alert({
										title: '提示',
										children: '您点击了确定按钮',
										onClose: (innerClose) => {
											// 关闭二层弹框
											innerClose();
											// 关闭外层弹框
											close();
										}
									})
								}
							},
							// 这里没有绑定事件,则点击触发关闭事件
							{ type: 'primary', text: '关闭' }
						]
					}
				});
			}
		}, '点击打开弹框')
	)
}
js
function setup() {
	this.add(
		this.render({
			is: 'button',
			onClick: () => {
				// 点击按钮,弹出弹框
				this.$tan({
					title: '弹框标题',
					width: '1080px',
					children: '这是弹框的内容',
					// 解开内置的取消按钮
					cancelButtonProps: null,
					// 在antd中,只允许控制确定按钮
					button: (close, show) => {
						return {
							text: '确定',
							onClick: () => {
								// 打开第二层弹框
								this.$tan({
									title: '提示',
									children: '您点击了确定按钮',
									onClose: innerClose => {
										// 关闭二层弹框
										innerClose();
										// 关闭外层弹框
										close();
									}
								})
							}
						}
					}
				});
			}
		}, '点击打开弹框')
	)
}

注:show为Jiess响应式数据,close和show均用于控制弹框的关闭

使用$tan.alert弹出弹框


$tan配置对象属性介绍:

title

  • 类型 String
  • 必要 否
  • 默认 ——
  • 说明 弹框标题

width

  • 类型 String
  • 必要 否
  • 默认 与$dialog一致
  • 说明 弹框宽度

children

  • 类型 基础数据|组件
  • 必要 否
  • 默认 ——
  • 说明 弹框宽度

buttons

  • 类型 Array|function
  • 必要 否
  • 默认 [{ type: 'primary', text: '关闭', onClick: close }]
  • 说明 底部按钮

buttons为函数时

为了手动关闭弹框,可以将buttons定义为函数,这样就会暴露两个形参

  • close:关闭当前弹框的函数
  • show: 使用响应式关闭弹框

注:还可以使用$dialog.close关闭当前弹框

hasButtons

  • 类型 Boolean
  • 必要 否
  • 默认 true
  • 说明 是否需要底部按钮

其他属性

对于配置的其他属性,直接应用于$dialog.open配置中