likes
comments
collection
share

详解 Electron 对话框

作者站长头像
站长
· 阅读数 18

在 Electron 应用中,有三类对话框:

  • 选择对话框
  • 保存对话框
  • 消息对话框

它们都是用 Dialog 类统一管理的:

详解 Electron 对话框

接下来对这三类对话框进行详细介绍:

选择对话框

用于选择电脑上的文件或目录,效果如下:

详解 Electron 对话框

该 API 有同步和异步两个版本:

// 同步版本,返回 string[] | undefined,
// 返回用户选择的文件路径,如果对话框被取消了,则返回 undefined。
dialog.showOpenDialogSync([browserWindow, ]options)

// 返回 promise,会 resolve 一个对象,包含:
// canceled: boolean 对话框是否被取消
// filePaths: string[] 用户选择的文件路径数组
dialog.showOpenDialog([browserWindow, ]options)

这里需要注意的是:第一个参数 browserWindow 对象是可选的,如果传值,那么对话框会以模态框的形式展示,附属在这个指定的 browserWindow 对象上,具体的样式为:

详解 Electron 对话框

比较重要的是 options 对象,有以下的属性:

  • title:对话框窗口标题
  • defaultPath:默认打开的路径
  • buttonLabel:「确认」按钮的自定义文案
  • filters:指定可选的文件类型
  • properties:对话框相关的属性

title

在 macOS 系统上,title 属性是无法设置标题的,但是可以通过 message属性在输入框上方展示一条消息,类似于 Windows 上的标题效果:

详解 Electron 对话框

defaultPath

defaultPath 用于指定打开路径,默认情况下会打开上次用户选择的路径,如果应用需要打开特定目录下的文件时,可以使用此参数。

buttonLabel

在 macOS 系统下,默认的文案是「打开」,可以通过 buttonLabel来修改这个文案,例如:

详解 Electron 对话框

filters

用于根据后缀对文件类型进行过滤,值是一个数组,数组里面是一个包含 name 和 extension 属性的对象,例如:

filters: [
  { name: '图片', extensions: ['jpg', 'png', 'gif'] },
  { name: '视频', extensions: ['mkv', 'avi', 'mp4'] },
  { name: '自定义文件类型', extensions: ['json'] },
  { name: '任意类型', extensions: ['*'] },
]

在 macOS 系统下,设置了 filters 之后,打开对话框乍一看没有任何区别,其实是起作用了,需要手动点一下左下角的「选项」,上方才会出现 Format 下拉菜单,菜单名称就是在 filters 里面定义的 name 字段,当选择了某个指定 name 之后,会按照该 name 对应的 extensions 对文件进行过滤。

详解 Electron 对话框

需要注意的是,指定扩展名的时候不包含 .前缀。

properties

这是比较重要的一个属性了,包含以下字段:

  • openFile:允许选择文件
  • openDirectory:允许选择文件夹
  • multiSelections:允许多选
  • showHiddenFiles:显示隐藏文件

在 macOS 上是可以同时选择文件和目录的,但是在 Windows 和 Linux 上不行,如果将 properties 设置为 ["openFile"、"openDirectory"],则将显示为目录选择器。隐藏文件默认是不展示的,如果项目中需要选择这些文件,可以指定 showHiddenFiles属性:

详解 Electron 对话框

保存对话框

详解 Electron 对话框

showSaveDialog 的属性和 showOpenDialog 几乎是完全一致的,区别在于 open 是选择已经存在的文件和目录,save 则是用于指定一个文件路径,用于将来保存信息。

open 对话框没有标题栏,而保存对话框是默认有标题栏的,所以 title 属性起作用,默认是「存储」,我们可以改成任意的字符串。

详解 Electron 对话框

如果仅是点击「存储」,没有后续任何操作,那么是不会有任何效果的,这个 API 的目的就是指定文件路径,至于后面代码逻辑是否要真正创建文件,则不一定。

如果文件已经存在,还是会给出提示的,但如果代码不做处理,是不会覆盖的。

详解 Electron 对话框

消息对话框

用于弹出提示消息,语法是:

dialog.showMessageBox([browserWindow, ]options)

options 的选项为:

  • title:标题
  • message:内容
  • detail:额外信息
  • type:类型
  • icon:图标
  • buttons:按钮
  • textWidth:文本宽度
  • defaultId:默认选中的按钮索引
  • cancelId:按 ESC 取消时返回的索引

在 macOS 系统上,title是不起作用的,例如:

dialog
  .showMessageBox({
    icon: path.join(__dirname, 'apple.png'),
    type: 'info',
    title: '消息标题', // 可能不显示
    message: '消息内容',
    detail: '更详细的信息',
    buttons: ['按钮1', '按钮2'],
  })
  .then((it) => {
    console.log('result', it)
  })

效果如下:

详解 Electron 对话框

返回值是 Promise,resolve 一个对象,结构为:

{ response: 1, checkboxChecked: false }

其中 response 字段表示用户选择的按钮索引,buttons 数组可以是任意长度,当长度为三个的时候,按钮从左右排列变成了上下排列:

详解 Electron 对话框

当超过三个按钮的时候,按钮的样式会发生一些变化:

详解 Electron 对话框

buttons 数组的第一项,即按钮1的位置比较特殊,当左右结构的时候,它在最右边,当上下结构的时候,它在最下面,这是因为默认索引为0的按钮默认是取消按钮,而取消按钮的位置一般都是在右侧或最下面。

返回值 checkboxChecked 表示复选框是否被选中,因为 options 里面有个选项是 checkboxLabel,表示是否展示复选框,如果设置了值:

dialog.showMessageBox({
  icon: path.join(__dirname, 'apple.png'),
  type: 'info',
  title: '消息标题',
  message: '消息内容',
  detail: '更详细的信息',
  buttons: ['按钮1', '按钮2'],
  checkboxLabel: '觉得自己帅的请勾上此选项', // 底部复选框
})

那么会在底部出现一个 checkbox:

详解 Electron 对话框

如果用户勾选了,那么返回值里面的 checkboxChecked字段就是 true。

另外,在默认情况下,按钮是没有选中状态的,如果要设置一个高亮的默认选中的按钮,可以用 defaultId来指定默认按钮的索引,在 macOS 下默认选中的按钮会变成蓝底白字的样式:

详解 Electron 对话框

消息对话框类型(type)有五种取值:默认(none)、信息(info)、错误(error)、询问(question)和警告(warning),设置之后,icon 的样式会发生一些变化,例如设置为 warning 之后:

详解 Electron 对话框

不过实际上并没有那么多种类型:

  • 在 macOS 系统, warning 和 error 的效果是完全一样的;
  • 在 Linux 系统,question 和 info 的效果是完全一样的;

消息对话框的布局是非常固定的,常用于展示一些提示信息,如果需要展示复杂的信息,例如图文混排、字体倾斜等,需要自定义 BrowserWindow 了。

还有一种简单的错误对话框:

showErrorBox(title, content)

只有两个参数:

  • title:显示在错误框中的标题.
  • content:显示在错误框中的文本内容.

效果:

详解 Electron 对话框

可以看到,其实就是 type 为 warning 的 message 对话框简单形式,只有一个按钮,且不能自定义 icon。

留给读者的思考题

实现下面的效果:用户点击保存按钮之后,弹出保存对话框,将 textarea 中的文本保存到用户指定的文件当中。

详解 Electron 对话框

转载自:https://juejin.cn/post/7202799873841201208
评论
请登录