基于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. Web标准和骨架

    Web 标准的好处 1.让Web的发展前景更广阔 2.内容能被更广泛的设备访问 3.更容易被搜寻引擎搜索 4.降低网站流量费用 5.使网站更易于维护 6.提高页面浏览速度 Web 标准构成 Web标准 ...

  2. cross-env 作用

    是什么 运行跨平台设置和使用环境变量的脚本 出现原因 当您使用NODE_ENV =production, 来设置环境变量时,大多数Windows命令提示将会阻塞(报错). (异常是Windows上的B ...

  3. JSP中的请求转发与重定向

    在说请求转发和重定向之前,得了解下JSP九大内置对象中的response和request response:将服务器端数据发送到客户端,可通过在客户端浏览器中显示,用户浏览页面的重定向以及在客户端创建 ...

  4. NSMutableString常用方法

    1.NSMutableString常用方法 - (void)appendString:(NSString *)aString; 拼接aString到最后面 NSMutableString *strM ...

  5. endl与\n的区别

    看C++Primer的时候看到的,然后去百度了一下: 比较明白的解释: 1.区别在于: \n只代表换行的转义字符 endl除了代表换行,还紧跟着清出缓冲槽 2.接下来我们看一下具体内容的辨析: 要明白 ...

  6. 一站式超全JavaScript数组方法大全

    一站式JavaScript数组方法大全(建议收藏) 方法一览表 详细操作 本人总结了JavaScript中有关数组的几乎所有方法(包含ES6之后新增的),并逐一用代码进行演示使用,希望可以帮助大家! ...

  7. 教你写Spring组件

    前言 原文地址:https://www.cnblogs.com/qnlcy/p/15905682.html 一.宗旨 在如日中天的 Spring 架构体系下,不管是什么样的组件,不管它采用的接入方式如 ...

  8. Solution -「洛谷 P5827」点双连通图计数

    \(\mathcal{Description}\)   link.   求有 \(n\) 个结点的点双连通图的个数,对 \(998244353\) 取模.   \(n\le10^5\). \(\mat ...

  9. Solution -「NOI 模拟赛」彩色挂饰

    \(\mathcal{Description}\)   给定一个含 \(n\) 个点 \(m\) 条边的简单无向图,设图中最大点双的大小为 \(s\),则保证 \(s\le6\).你将要用 \(k\) ...

  10. java运行原理、静态代理和动态代理区分

    1.java的编译和运行原理: ■ 编译:将源文件 .java 文件,通过编译器(javac 命令) 编译成 字节码文件 .class 文件. ■ 运行,通过类加载器(以二进制流形式)把字节码加载进J ...