基于Svelte3.x自定义多功能svPopup弹出框组件(组件式+函数式)

前几天有分享一个svelte自定义tabbar+navbar组件,今天继续带来svelte自定义弹窗组件。

svPopup 一款基于 Svelte.js 开发的手机端弹框组件。汇集了msg、info、toast、alert、dialog、actionsheet等多种类型弹窗。支持 25+ 参数自定义搭配组合、组件式+函数式两种调用方式。

由于svelte框架比较新,一些相关的项目案例及自定义组件例子比较少,只能看官方语法文档,并结合之前开发的一些vue3弹窗插件,最后实现了如上图所示的svelte自定义弹框。

◆ 引入组件

在需要使用弹窗功能的页面引入Popup组件。

import Popup, {svPopup} from '$lib/Popup'

其中 Popup 是组件式调用, svPopup 是函数式调用。

  • 组件式写法
<Popup
bind:open={isVisibleDialog}
xclose
xposition="top"
title="标题信息"
content="这里是内容信息"
btns={[
{text: '确认', style: 'color:#f60;', click: () => isVisibleDialog=false},
]}
on:open={handleOpen}
on:close={handleClose}
>
<svelte:fragment slot="content"><h3>自定义插槽显示插槽内容!!!</h3></svelte:fragment>
</Popup>
  • 函数式写法
let el = svPopup({
title: '标题信息',
content: '<p style='color:#df6a16;'>这里是内容信息</p>',
xclose: true,
xposition: 'top',
shadeClose: false,
btns: [
{text: '取消', click: () => { el.$set({open: false}) }},
{text: '确认', style: 'color:#f90;', click: () => handleOK},
],
onOpen: () => {},
onClose: () => {}
})

一些简单的弹窗效果可以使用函数式调用,一些复杂的交互功能可以使用组件式自定义slot来实现功能。

<!-- msg提示 -->
<Popup bind:open={showMsg} anim="fadeIn" content="msg提示框测试(3s后窗口关闭)" shadeClose="false" time="3" /> <!-- 自定义多按钮 -->
<Popup bind:open={showMulityBtns} anim="fadeIn" title="<b style='color:red;'>温馨提示</b>" zIndex="6666"
content="<div style='padding:10px 35px;'>是否检查软件更新并下载最新的更新?通过移动网络下载可能产生额外的费用。如果可能,通过WLAN网络下载。</div>"
btns={[
{text: '稍后提示', style: 'color:#2196f3;', click: () => null},
{text: '取消', style: 'color:#a9a9a9;', click: () => showMulityBtns=false},
{text: '立即更新', style: 'color:#00e0a1;', click: handleInfo},
]}
/>

<!-- 底部对话框 -->
<Popup bind:open={showFooter} anim="footer" type="footer" shadeClose="false" zIndex="1001"
content="确定删除该条数据吗?删除后可在7天之内恢复数据,超过7天后数据就无法恢复啦!"
btns={[
{text: '恢复', style: 'color:#00e0a1;', click: handleInfo},
{text: '删除', style: 'color:#ee0a24;', click: () => null},
{text: '取消', style: 'color:#a9a9a9;', click: () => showFooter=false},
]}
/> <!-- ActionSheet底部弹出式菜单 -->
<Popup bind:open={showActionSheet} anim="footer" type="actionsheet" zIndex="2020"
content="弹窗内容,告知当前状态、信息和解决方法,描述文字尽量控制在三行内"
btns={[
{text: '拍照', style: 'color:#09f;', disabled: true, click: handleInfo},
{text: '从手机相册选择', style: 'color:#00e0a1;', click: handleInfo},
{text: '保存图片', style: 'color:#e63d23;', click: () => null},
{text: '取消', click: () => showActionSheet=false},
]}
/>

<!-- Ios样式 -->
<Popup bind:open={showIos1} type="ios" shadeClose="false" title="标题内容" zIndex="1990"
content="弹窗内容,告知当前状态、信息和解决方法,描述文字尽量控制在三行内"
btns={[
{text: '知道了', click: () => showIos1=false},
{text: '确定', style: 'color:#00e0a1;', click: handleInfo},
]}
>
</Popup> <!-- Android样式 -->
<Popup bind:open={showAndroid1} type="android" shadeClose="false" xclose title="标题内容" zIndex="2000"
content="弹窗内容,告知当前状态、信息和解决方法,描述文字尽量控制在三行内"
btns={[
{text: '知道了', click: () => showAndroid1=false},
{text: '确定', style: 'color:#00e0a1;', click: handleInfo},
]}
>
</Popup>
function handleInfo(e) {
console.log(e)
console.log('通过函数方式调用弹窗...') let el = svPopup({
title: '标题',
content: `<div style="padding:20px;">
<p>函数式调用:<em style="color:#999;">svPopup({...})</em></p> </div>`,
btns: [
{
text: '取消',
click: () => {
// 关闭弹窗
el.$set({open: false})
}
},
{
text: '确认',
style: 'color:#09f;',
click: () => {
svPopup({
type: 'toast',
icon: 'loading',
content: '加载中...',
opacity: .2,
time: 2
})
}
},
]
})
}

◆ Svelte弹窗编码实现

  • 支持如下参数自定义配置
<script>
// 是否打开弹窗bind:open={showDialog}
export let open = false
// 弹窗标识符
// export let id = 'svpopup-' + Math.random().toString(32)
export let id = undefined
// 标题
export let title = ''
// 内容
export let content = ''
// 弹窗类型
export let type = ''
// 自定义弹窗样式
export let popupStyle = undefined
// toast图标
export let icon = ''
// 是否显示遮罩层
export let shade = true
// 点击遮罩层是否关闭
export let shadeClose = true
// 遮罩层透明度
export let opacity = ''
// 是否显示圆角
export let round = false
// 是否显示关闭图标
export let xclose = false
// 关闭图标位置
export let xposition = 'right'
// 关闭图标颜色
export let xcolor = '#333'
// 弹窗动画
export let anim = 'scaleIn'
// 弹窗位置
export let position = ''
// 长按/右键弹窗
export let follow = null
// 弹窗自动关闭时间
export let time = 0
// 弹窗层级
export let zIndex = 202203
// 弹窗按钮组
export let btns = null
/* export let btns = [
{ text: '取消', style: 'color:#aaa', disabled: true, click: null },
{ text: '确定', style: 'color:#f90', click: null }
] */ // 函数式打开|关闭回调
export let onOpen = undefined
export let onClose = undefined // 接收函数式移除指令
export let remove = undefined // ... </script>
  • 弹窗模板语法
<div class="sv__popup" class:opened class:sv__popup-closed={closeCls} id={id} style="z-index: {zIndex}" bind:this={el}>
{#if bool(shade)}<div class="vui__overlay" on:click={shadeClicked} style:opacity></div>{/if}
<div class="vui__wrap">
<div class="vui__wrap-section">
<div class="vui__wrap-child {type&&'popupui__'+type} anim-{anim} {position}" class:round style="{popupStyle}">
{#if title}<div class="vui__wrap-tit">{@html title}</div>{/if}
{#if icon&&type=='toast'}<div class="vui__toast-icon">{@html toastIcon[icon]}</div>{/if}
{#if $$slots.content}
<div class="vui__wrap-cnt"><slot name="content" /></div>
{:else}
{#if content}<div class="vui__wrap-cnt">{@html content}</div>{/if}
{/if}
<slot />
{#if btns}
<div class="vui__wrap-btns">
{#each btns as btn,index}
<span class="btn"style="{btn.style}" on:click={e => btnClicked(e, index)}>{@html btn.text}</span>
{/each}
</div>
{/if}
{#if xclose}<span class="vui__xclose {xposition}" style="color: {xcolor}" on:click={hide}></span>{/if}
</div>
</div>
</div>
</div>
/**
* @Desc svelte自定义多功能弹框组件
* @Time andy by 2022/3/15
* @About Q:282310962 wx:xy190310
*/
<script>
// ... import { onMount, afterUpdate, createEventDispatcher, tick } from 'svelte'
const dispatch = createEventDispatcher() let opened = false
let closeCls = undefined
let toastIcon = {
loading: '',
success: '',
fail: '',
} const bool = (boolean) => JSON.parse(boolean) ? true : false onMount(() => {
console.log('监听弹窗开启...')
return () => {
console.log('监听弹窗关闭...')
}
}) afterUpdate(() => {
// console.log('监听弹窗更新...')
/* if(opened) {
if(!open) {
opened = false
dispatch('close')
}
}else if(open) {
opened = true
dispatch('open')
} */
}) $: if(open) {
show()
}else {
hide()
} /**
* 打开弹窗
*/
async function show() {
if(opened) return
opened = true
dispatch('open')
typeof onOpen == 'function' && onOpen() zIndex = getZIndex() + 1 // 倒计时关闭
if(time) {
index++
if(timer[index] != null) clearTimeout(timer[index])
timer[index] = setTimeout(() => {
hide()
}, parseInt(time)*1000)
} // 长按|右键菜单
if(follow) {
// ...
}
} /**
* 关闭弹窗
*/
function hide() {
if(!opened) return
closeCls = true
setTimeout(() => {
opened = false
closeCls = false
open = false
// ...
}, 200)
} // 点击遮罩层
function shadeClicked() {
if(bool(shadeClose)) {
hide()
}
} // ...// 临界坐标点
function getPos(x, y, ow, oh, winW, winH) {
let l = (x + ow) > winW ? x - ow : x
let t = (y + oh) > winH ? y - oh : y
return [l, t]
}
</script>

Svelte官网有介绍,可以通过 new Component 来实现挂载组件到body上。

const component = new Component(options)

import App from './App.svelte';

const app = new App({
target: document.body,
props: {
// assuming App.svelte contains something like
// `export let answer`:
answer: 42
}
});

https://svelte.dev/docs#run-time-client-side-component-api

import Popup from './Popup.svelte'

let uuid = function() {
return 'svpopup-' + Math.floor(Math.random() * 10000)
} export function svPopup(options = {}) {
options.id = uuid() const mountNode = document.createElement('div')
document.body.appendChild(mountNode) const app = new Popup({
target: mountNode,
props: {
...options,
open: true,
// 传入函数移除指令
remove() {
document.body.removeChild(mountNode)
}
}
})
return app
} export default Popup

通过如上写法,就可以导出一个 Popup 组件及 svPopup 函数调用。

OK,以上就是svelte实现自定义弹窗组件的一些分享,希望对大家有所帮助~~

svelte组件:Svelte自定义弹窗Popup组件|svelte移动端弹框组件的更多相关文章

  1. vue移动端弹框组件,vue-layer-mobile

    最近做一个移动端项目,弹框写的比较麻烦,查找资料,找到了这个组件,但是说明文档比较少,自己研究了下,把我碰到的错,和详细用法分享给大家!有疑问可以打开组件看一看,这个组件是仿layer-mobile的 ...

  2. vue移动端弹框组件

    最近做一个移动端项目,弹框写的比较麻烦,查找资料,找到了这个组件,但是说明文档比较少,自己研究了下,把我碰到的错,和详细用法分享给大家!有疑问可以打开组件看一看,这个组件是仿layer-mobile的 ...

  3. vue3系列:vue3.0自定义弹框组件V3Popup|vue3.x手机端弹框组件

    基于Vue3.0开发的轻量级手机端弹框组件V3Popup. 之前有分享一个vue2.x移动端弹框组件,今天给大家带来的是Vue3实现自定义弹框组件. V3Popup 基于vue3.x实现的移动端弹出框 ...

  4. 基于uni-app全端弹框组件uaPopup「兼容h5+小程序+app端|nvue」

    uniapp兼容多端自定义模态弹框组件UAPopup ua-popup 一款轻量级的uniapp自定义弹窗组件.汇集了android.ios和微信弹窗效果(msg消息.alert提示框.dialog对 ...

  5. 移动端(H5)弹框组件--简单--实用--不依赖jQuery

    俗话说的好,框架是服务与大家的,包含的功能比较多,代码多.在现在追求速度的年代.应该根据自己的需求去封装自己所需要的组件. 下边就给大家介绍一下自己封装的一个小弹框组件,不依赖与jQuery,代码少, ...

  6. VUE2.0增删改查附编辑添加model(弹框)组件共用

    Vue实战篇(增删改查附编辑添加model(弹框)组件共用) 前言 最近一直在学习Vue,发现一份crud不错的源码 预览链接 https://taylorchen709.github.io/vue- ...

  7. vue的通讯与传递props emit (简单的弹框组件)

    props父把信息传递给子组件 1父组件 <template> <div class="hello"> <div id="app-3&quo ...

  8. 关于微信小程序 modal弹框组件的介绍

    微信小程序 modal: 这里对微信小程序中 modal组件进行详细解析,我想开发微信小程序的小伙伴可以用到,这里小编就记录下modal的知识要点. modal modal类似于javascript中 ...

  9. 微信小程序之----弹框组件modal

    modal modal类似于javascript中的confirm弹框,默认情况下是一个带有确认取消的弹框,不过点击取消后弹框不会自动隐藏,需要通过触发事件调用函数来控制hidden属性. 官方文档 ...

随机推荐

  1. Android下数据库操作——增删改查

    Android下数据库第一种方式增删改查     1.创建一个帮助类的对象,调用getReadableDatabase方法,返回一个SqliteDatebase对象     2.使用SqliteDat ...

  2. Java线程--ThreadPoolExecutor使用

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871132.html Java线程--ThreadPoolExecutor使用 public ...

  3. PHP中的单引号跟双引号的区别

    不同点: 单引号只能解析转义字符"'"和"\",其他的原样输出.

  4. SpringAOP/切面编程示例

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11833954.html Spring AOP/切面编程实例和一些注意事项, 主要是利用注解来实 ...

  5. 网络层主要协议与arp欺骗

    网络层主要协议与arp欺骗 目录 网络层主要协议与arp欺骗 一.网络层(Network Layer) 1.网络层的功能 2.IP数据报(IP Datagram) 二.网络层的主要协议 1.ICMP协 ...

  6. MyBatis加强(1)~缓存机制(一级缓存、二级缓存、第三方缓存技术redis、ehcache)

    一.缓存机制 使用缓存可以使应用更快地获取数据,避免频繁的数据库交互操作,尤其是在查询越多,缓存命中率越高 的情况下,缓存的作用就越明显. 1.缓存原理:Map ■ 查询时,先从缓存区查询:找到,返回 ...

  7. 【Gym100837F】Controlled Tournament(状压Dp 搜索剪枝)

    题目链接 大意 现有\(N\)个人要打比赛,知道任意两个人间打比赛的胜负关系. 要求在 深度最小 的情况下,根为\(M\)的 竞赛树 的个数. 满足\(1\le M\le N\le 16\) 思路 虑 ...

  8. 用Java实现生成图片验证码

    通过代码实现生成一个随机验证码图片,且生成后自动打开: package day_12_17; import javax.imageio.ImageIO; import java.awt.*; impo ...

  9. 年前最后一次2022.1.28_RP++

    T1同昨(我看到题目就粘上昨天的代码,结果题还没发我就A了hhhhhh) T2一开始想用深搜,结果T掉了...只好改广搜,就挺令人头大 点击查看宽广对比 #include<bits/stdc++ ...

  10. 7、Linux基础--权限、查看用户信息

    笔记 1.晨考 1.Linux系统中的文件"身份证号"是什么 index node 号码 2.什么是硬链接,什么是软连接 硬链接是文件的入口,软连接是快捷方式. 3.硬链接中保存的 ...