前言
我们之前已经学了SweetAlert2,这节课我们简单进行一下进阶的学习~
对话框重用
我们可以使用Swal.mixin来创建可重用的对话框
如
const Toast = Swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
didOpen: (toast) => {
toast.addEventListener('mouseenter', Swal.stopTimer)
toast.addEventListener('mouseleave', Swal.resumeTimer)
}
})
Toast.fire({
icon: 'success',
title: 'Signed in successfully'
})
模板声明
我们也可以在html中写template模板然后在Swal传入来触发弹窗
使用这种声明方式,在SSR情况下比较方便(本人未尝试)
代码如下
<template id="my-template">
<swal-title>
Save changes to "Untitled 1" before closing?
</swal-title>
<swal-icon type="warning" color="red"></swal-icon>
<swal-button type="confirm">
Save As
</swal-button>
<swal-button type="cancel">
Cancel
</swal-button>
<swal-button type="deny">
Close without Saving
</swal-button>
<swal-param name="allowEscapeKey" value="false" />
<swal-param
name="customClass"
value='{ "popup": "my-popup" }' />
</template>
然后我们使用
Swal.fire({
template: '#my-template'
})
触发弹窗,其中template就是我们的template标签的id名
支持的模板参数如下,因为这个感觉较为小众,所以我就没有尝试了
<swal-title>...</swal-title>
<swal-html>...</swal-html>
<swal-footer>...</swal-footer>
<swal-param name="..." value="..." />
<swal-button type="..." color="..." aria-label="...">...</swal-button>
<swal-image src="..." width="..." height="..." alt="..." />
<swal-icon type="..." color="...">...</swal-icon>
<swal-input type="..." label="..." placeholder="..." value="..." />
<swal-input-option value="...">...</swal-input-option>
声明式触发弹窗
我们也可以在html中通过声明属性的方式,然后触发弹窗,这时候我们需要使用的命令是bindClickHandler方法
例子如下
<button data-swal-template="#my-template">
Trigger modal
</button>
<button data-swal-toast-template="#my-template">
Trigger toast
</button>
然后我们在js写
Swal.bindClickHandler()
Swal.mixin({
toast: true,
}).bindClickHandler('data-swal-toast-template')
bindClickHandler如果不填写任何字符串,则默认为'data-swal-template'
读取属性的字符串作为模板
而如果传入了,则读取相应属性的模板
这里我是通过源码大概看了一下才理解的,官方一笔带过,大家有兴趣也可以看一下,代码如下
let bodyClickListenerAdded = false
const clickHandlers = {}
export function bindClickHandler (attr = 'data-swal-template') {
clickHandlers[attr] = this
if (!bodyClickListenerAdded) {
document.body.addEventListener('click', bodyClickListener)
bodyClickListenerAdded = true
}
}
const bodyClickListener = (event) => {
for (let el = event.target; el && el !== document; el = el.parentNode) {
for (const attr in clickHandlers) {
const template = el.getAttribute(attr)
if (template) {
clickHandlers[attr].fire({ template })
return
}
}
}
}
处理按钮的返回值
当用户单击按钮的时候,Swal.fire返回的promise将返回一个SweetAlertResult对象
键值如下
isConfirmed:当确认按钮被点击,返回的result的这个属性将为true
isDenied:当拒绝按钮被点击,返回的result的这个属性将为true,当弹窗有输入结果的时候,可以使用returnInputValueOnDeny: true返回输入的值
isDismissed:当取消按钮被点击,返回的result的这个属性将为true,而dismiss属性将为Swal.DismissReason.cancel
value:该值来源于窗口弹出,返回的result的这个属性有多种可能的值,当点击确认按钮时为true,拒绝为false,和存在输入框的时候为输入框的值
dismiss:当点击取消按钮的时候存在该属性,为取消原因,关于取消原因可以查看接下来的内容
取消原因
当用户点击取消按钮的时候,Swal.fire将返回一个对象,包含了{ isDismissed: true,dismiss: reason },其中reason包含了取消的详细原因
原因如下
Swal.DismissReason.backdrop:点击了外部背景,相关配置为allowOutsideClick
Swal.DismissReason.cancel:点击了取消按钮,相关配置为showCancelButton
Swal.DismissReason.close:点击了关闭按钮,相关配置为showCloseButton
Swal.DismissReason.esc:按了esc键,相关配置为allowEscapeKey
Swal.DismissReason.timer:时间超时,对话框自动关闭,相关配置为timer
如果使用了Swal.close关闭窗口,则Promise返回的obj中isDismissed:为true,但dismiss属性为undefined
图标
如下
输入类型
这里我们也可以限制对话框内的输入类型
首先是text类型
const ipAPI = '//api.ipify.org?format=json'
const inputValue = fetch(ipAPI)
.then(response => response.json())
.then(data => data.ip)
const { value: ipAddress } = await Swal.fire({
title: 'Enter your IP address',
input: 'text',
inputLabel: 'Your IP address',
inputValue: inputValue,
showCancelButton: true,
inputValidator: (value) => {
if (!value) {
return 'You need to write something!'
}
}
})
if (ipAddress) {
Swal.fire(`Your IP address is ${ipAddress}`)
}
inputLabel
是显示的文本
inputValue
是显示的值,如果是text,email,number,tel,textarea等类型,则可以传入一个promise值
inputValidator
对其进行合法性校验
**const { value: ipAddress } = await Swal.fire**
这里做了一个结构,对Swal.fire返回的promise做了一个await语法糖,同步等待返回对象,同时对对象进行解构拿到value的值,叫变量ipAddress
并在最后显示出来。
然后是email类型,代码如下
const { value: email } = await Swal.fire({
title: 'Input email address',
input: 'email',
inputLabel: 'Your email address',
inputPlaceholder: 'Enter your email address'
})
if (email) {
Swal.fire(`Entered email: ${email}`)
}
非常简单,不解释
url类型
const { value: url } = await Swal.fire({
input: 'url',
inputLabel: 'URL address',
inputPlaceholder: 'Enter the URL'
})
if (url) {
Swal.fire(`Entered URL: ${url}`)
}
password类型
const { value: password } = await Swal.fire({
title: 'Enter your password',
input: 'password',
inputLabel: 'Password',
inputPlaceholder: 'Enter your password',
inputAttributes: {
maxlength: 10,
autocapitalize: 'off',
autocorrect: 'off'
}
})
if (password) {
Swal.fire(`Entered password: ${password}`)
}
maxlength
最大长度
autocapitalize
取消首字母大写
autocorrect
关闭自动修正,这个可以百度一下看看
textarea类型
const { value: text } = await Swal.fire({
input: 'textarea',
inputLabel: 'Message',
inputPlaceholder: 'Type your message here...',
inputAttributes: {
'aria-label': 'Type your message here'
},
showCancelButton: true
})
if (text) {
Swal.fire(text)
}
inputAttributes
添加到html对象的输入属性,其中键为属性名称,而值为添加的对应值
select类型
const { value: fruit } = await Swal.fire({
title: 'Select field validation',
input: 'select',
inputOptions: {
'Fruits': {
apples: 'Apples',
bananas: 'Bananas',
grapes: 'Grapes',
oranges: 'Oranges'
},
'Vegetables': {
potato: 'Potato',
broccoli: 'Broccoli',
carrot: 'Carrot'
},
'icecream': 'Ice cream'
},
inputPlaceholder: 'Select a fruit',
showCancelButton: true,
inputValidator: (value) => {
return new Promise((resolve) => {
if (value === 'oranges') {
resolve()
} else {
resolve('You need to select oranges :)')
}
})
}
})
if (fruit) {
Swal.fire(`You selected: ${fruit}`)
}
inputOptions
为选项值
radio类型
/* inputOptions can be an object or Promise */
const inputOptions = new Promise((resolve) => {
setTimeout(() => {
resolve({
'#ff0000': 'Red',
'#00ff00': 'Green',
'#0000ff': 'Blue'
})
}, 1000)
})
const { value: color } = await Swal.fire({
title: 'Select color',
input: 'radio',
inputOptions: inputOptions,
inputValidator: (value) => {
if (!value) {
return 'You need to choose something!'
}
}
})
if (color) {
Swal.fire({ html: `You selected: ${color}` })
}
这里他为了演示,返回了一个promise并设置一秒后结束promise
返回的值是对象,其中键是对应的值,而属性则是名字
checkbox类型
const { value: accept } = await Swal.fire({
title: 'Terms and conditions',
input: 'checkbox',
inputValue: 1,
inputPlaceholder:
'I agree with the terms and conditions',
confirmButtonText:
'Continue <i class="fa fa-arrow-right"></i>',
inputValidator: (result) => {
return !result && 'You need to agree with T&C'
}
})
if (accept) {
Swal.fire('You agreed with T&C :)')
}
设定了默认值以及单选框文本
file类型
const { value: file } = await Swal.fire({
title: 'Select image',
input: 'file',
inputAttributes: {
'accept': 'image/*',
'aria-label': 'Upload your profile picture'
}
})
if (file) {
const reader = new FileReader()
reader.onload = (e) => {
Swal.fire({
title: 'Your uploaded picture',
imageUrl: e.target.result,
imageAlt: 'The uploaded picture'
})
}
reader.readAsDataURL(file)
}
这里没什么特别需要讲解的
range类型
Swal.fire({
title: 'How old are you?',
icon: 'question',
input: 'range',
inputLabel: 'Your age',
inputAttributes: {
min: 8,
max: 120,
step: 1
},
inputValue: 25
})
进度条类型,min为最小,max为最大,step为阶段提升值,inputValue为默认值
提示
不支持多个输入框输入
但是可以通过html以及preConfirm属性来实现。
在preConfirm你可以返回自定义结果,preConfirm可以接受一个promise
例子如下
const { value: formValues } = await Swal.fire({
title: 'Multiple inputs',
html:
'<input id="swal-input1" class="swal2-input">' +
'<input id="swal-input2" class="swal2-input">',
focusConfirm: false,
preConfirm: () => {
return [
document.getElementById('swal-input1').value,
document.getElementById('swal-input2').value
]
}
})
if (formValues) {
Swal.fire(JSON.stringify(formValues))
}
主题
sweetalert2有多种主题
如何引入主题
可以直接引入对应的css文件以及sweetalert2的js文件
如
https://cdn.jsdelivr.net/npm/@sweetalert2/theme-dark@3/dark.css
https://cdn.jsdelivr.net/npm/sweetalert2@9/dist/sweetalert2.min.js
引入以上两个文件
关于css文件地址
你可以在
https://cdn.jsdelivr.net/npm/@sweetalert2/themes@latest/
找到对应的文件目录以及对应的css文件。
结语
拖了这么久终于给sweetalert2完结了...累死了