开发了一个 vue 的弹窗组件 用于满足日常开发中的弹窗需求

2019-11-19 12:01:29 +08:00
 a62527776a

样式复刻 ios 的弹窗
开发了蛮长一段时间 基本现在都经常用他
开发的初衷是经常开发一些活动页
但是页面都是一些比较简单的 不是很想引入 UI 库 但是单独的弹窗仓库都没有太好看的 就自己开发了一个

因为要支持 script 引入,所以打包了一份 vue-dialog-x.window.js

支持 5 种弹窗形式 分别是 alert confirm prompt actions dialog


支持 Promise 的 iOS 样式风格的弹窗提示

代码样例

基础

await this.$dialog.confirm({
  title: '提示',
  message: '请登陆后再试',
  okText: '去登陆'
})

异步 confirm

async () => {
  await dialogX.confirm({
    message: '点击确认后购买', 
    wait: async next => {
      await fetch('xxx') // 比如 请求接口
      next()
    }
  })
  dialogX.alert({message: '购买成功'})
}

Links

demo 地址

官网以及文档地址

Github

演示

5304 次点击
所在节点    分享创造
19 条回复
mcfog
2019-11-19 12:33:06 +08:00
总体还行,挑些毛病的话:

已经 promise 和 async await 都上了还用 wait 这样的回调参数来做“后续干啥”,甚至这个回调参数里还有个 next callback 看着难受

活动页弹个窗这种小事还带上 vue 难受
yamedie
2019-11-19 12:40:28 +08:00
写法上, 感觉没有 vantUI 的$dialog.confirm().then().catch(), 链式调用来的优雅
zhw2590582
2019-11-19 12:46:06 +08:00
next 可以省掉
a62527776a
2019-11-19 13:24:06 +08:00
@mcfog
@zhw2590582 wait 回调参数的应用场景是这样的,
用户点击确认后发送请求至接口 这段时间内弹窗不关闭 不允许用户做操作
就是图 2 和图 4 的场景
调用了 next 之后才会关闭弹窗
如果没有这种场景就不需要 wait 参数来回调 就是正常的 Promise 函数
a62527776a
2019-11-19 13:29:48 +08:00
看来是我写的太令人容易误解了
a62527776a
2019-11-19 13:33:19 +08:00
@yamedie wait 只是一个增强的功能 正常就是 then catch 这么用的 /(ㄒoㄒ)/~~
mcfog
2019-11-19 14:07:03 +08:00
@a62527776a next 仍然多余

提供这样一个不上不下的功能没啥意思,不如给用户完全控制框里的渲染和逻辑的方式
随便说几个场景吧:
a)取消也要异步 block 住
b)block 过程中用户希望在按钮上显示菊花 /其他文字
c)block 过程中用户希望改变框内主体的展示,变灰加字进度条都有可能需要
d)失败场景可能的需求有:框仍然消失 /框消失并通知外部改变状态 /框保留按钮变回可点 /框保留按钮状态改变 /弹第二个 alert 框告知用户失败并组合上述任意交互等等
不管你的默认行为怎么写,总会有其他需求,诱惑你再加更多 option 和 callback
问题的根源可能在于你没想清楚自己的组件的边界在哪里。我能猜到加这个 wait 的机制能满足你多数的需求,提高你的效率,但放到开源组件里,这个选项满足别人一半的需求,逼迫别人要么魔改 hack 要么不用,就是“不好用”的组件了
wunonglin
2019-11-19 14:13:03 +08:00
a62527776a
2019-11-19 15:45:05 +08:00
@mcfog 这个功能我在 iOS 上经常有遇到过 我不大觉得这是个多余的功能

你说的场景我觉得很有参考意义 比如:失败后框保留按钮变回可点 这个是我在 wait 函数中没有考虑到的 我觉得我会考虑加上这个功能

我开发这个仓库的定位更多是实现面向 C 端用户的交互反馈 我想着能 cover 掉 ios 上弹窗的各种情况就可以了 应该不大适合需要定制化弹窗的面向企业的场景
zhw2590582
2019-11-19 17:29:42 +08:00
哈哈,好吧,可能是我没理解你的用意吧,都已经用了 async await 了,假如异步操作 fetch 需要一秒时间,无论有没有 next,wait 都是经过一秒后执行完。
a62527776a
2019-11-19 17:32:46 +08:00
@zhw2590582 但是不调用 next 的话 程序就不知道是否结束了 next 就是用来结束程序的 loading 状态的
zhw2590582
2019-11-19 17:37:59 +08:00
可以啊,这样不就好了

async function wait() {
await fetch("xxx");
}

(async () => {
console.log("开始 loading");
await wait();
console.log("结束 loading");
})();
a62527776a
2019-11-19 17:39:09 +08:00
@zhw2590582 我看看我 await 掉可不可以
zhw2590582
2019-11-19 17:39:38 +08:00
应该返回一个 promise 才对

async function wait() {
return await fetch("xxx");
}
a62527776a
2019-11-19 17:52:12 +08:00
@zhw2590582 😂运用不够灵活啊 谢谢你帮我优化代码
a62527776a
2019-11-19 17:52:56 +08:00
@zhw2590582 我看这样可以 我这就把代码修改掉
liuxingbaoyu
2019-11-19 18:09:07 +08:00
前几天还想找个类似的呢,强烈支持!
a62527776a
2019-11-19 18:15:56 +08:00
@wunonglin 你的意思是把 wait 作为链式调用吗?
ChefIsAwesome
2019-11-19 18:39:31 +08:00
因为对话框就是个 view,跟一个页面没啥区别。页面千变万化,从来没人说他可以写一个 page 组件就满足所有需求。所以对话框也一样,没有万能的。
对话框最基本的功能是打开和关闭:
应该有 onOpen,afterOpenAnimationEnd,onClose,afterCloseAnimationEnd 这样的事件。
打开时,对话框的 zIndex 应该是可控的,如果支持打开多个对话框,最新的那个对话框应该层级最高。
在背景上滚鼠标之类的操作,应该不会让页面滚动。点击背景是否应该关闭对话框,应该是个 property。
按下 ESC 应该能关闭对话框。如果支持同时打开多个对话框,按下 ESC 应该只关闭最近打开的那个对话框。
应该有个 property 强制对话框开启,按 ESC 之类的都不起作用。

对话框里做异步操作,怎么禁用按钮,怎么显示 loading,跟对话框组件应该是没什么关系的。
业务型的对话框应该是在普通对话框外面套一层,而不是给普通对话框加参数。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/620972

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX