基于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. bom-对话框

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. AI模型运维——GPU性能监控NVML和DCGM

    最近一年负责运维的GPU主机越来越多,发现现有的监控项无法很好的了解GPU的性能和负载情况,研究了下官方文档,在此记录. 一.NVML和DCGM NVML:https://developer.nvid ...

  3. iframe父子页面相互调用方法,相互获取元素

    父页面获取子页面 var childWin = document.getElementById('setIframe').contentWindow;//获取子页面窗口对象 childWin.send ...

  4. Sublime Python3编译环境修改

    http://blog.csdn.net/qq_33304418/article/details/63337602     添加编译环境python3.6 Tools -> Build Syst ...

  5. 卡特兰数是我见过第二神奇的东西//下一个是stirling数列

    自从上次斐波那契的总结后,今天有一次遇上了正宗卡特兰数. 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, ...

  6. Solution -「NOIOL-S 2021」「洛谷 P7470」岛屿探险

    \(\mathcal{Description}\)   Link.   给定序列 \(\{(a,b)_n\}\),\(q\) 组形如 \((l,r,c,d)\) 的询问,求 \[\Big|\{i\in ...

  7. Dubbo基础二之架构及处理流程概述

    Dubbo基础一之实战初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中体验了Dubbo的使用,对于消费端对服务提供者的调用非常清晰明确.那么Dubbo是如何做到的呢?下面对Dub ...

  8. 面渣逆袭:二十二图、八千字、二十问,彻底搞定MyBatis!

    大家好,我是老三,面渣逆袭系列继续,这节我们的主角是MyBatis,作为当前国内最流行的ORM框架,是我们这些crud选手最趁手的工具,赶紧来看看面试都会问哪些问题吧. 基础 1.说说什么是MyBat ...

  9. 理解OAuth2.0协议和授权机制

    无论是自然资源还是互联网上的资源,需要控制使用权与被使用权,以保护资源的安全.合理的使用和有效的管控. 项目中,我们需要控制的是用户资源,既要保证有效用户的合理使用,又要防范非法用户的攻击.如此,如何 ...

  10. 『德不孤』Pytest框架 — 5、Pytest失败重试

    Pytest失败重试就是,在执行一次测试脚本时,如果一个测试用例执行结果失败了,则重新执行该测试用例. 前提: Pytest测试框架失败重试需要下载pytest-rerunfailures插件. 安装 ...