之前有给大家分享一个svelte.js移动端弹框组件sveltePopup。
svelte-popup: 适用于svelte.js自定义弹窗组件
今天给大家分享的是Svelte3系列之自定义PC端对话框组件svelteLayer。
svelte-layer 基于svelte3.x开发的轻量级pc端对话框组件。30+参数自定义配置、多种弹窗类型,支持拖拽/四角缩放/最大化/全屏及自定义弹窗层级等功能。
引入使用
在需要使用弹窗功能的页面引入组件。
import Layer, {svLayer} from '$lib/Layer'
svelteLayer 支持组件式+函数式两种混合调用方式。
- 组件式
<!-- msg提示 -->
<Layer bind:open={showMsg} anim="fadeIn" content="msg提示框测试(3s后窗口关闭)" shadeClose="false" time="3" />
<!-- 询问框 -->
<Layer bind:open={showConfirm} shadeClose="false" title="警告信息" xclose zIndex="2001" lockScroll={false} resize dragOut
content="<div style='color:#00e0a1;padding:20px 40px;'>确认框(这里是确认框提示信息,这里确认框提示信息,这里是确认框提示信息)</div>"
btns={[
{text: '取消', click: () => showConfirm=false},
{text: '确定', style: 'color:#e63d23;', click: handleInfo},
]}
/>
- 函数式
function handleInfo(e) {
let el = svLayer({
title: '标题',
content: `<div style="padding:20px;">
<p>函数式调用:<em style="color:#999;">svLayer({...})</em></p>
</div>`,
resize: true,
btns: [
{
text: '取消',
click: () => {
// 关闭弹窗
el.$set({open: false})
}
},
{
text: '确认',
style: 'color:#09f;',
click: () => {
svLayer({
type: 'toast',
icon: 'loading',
content: '加载中...',
opacity: .2,
time: 2
})
}
},
]
})
}
svelteLayer参数配置
支持如下30+种参数随意搭配,实现各种弹窗应用场景。
<script context="module">
let index = 0 // 用于控制倒计时临时索引
let lockNum = 0 // 用于控制锁定屏幕临时索引
</script>
<script>
// 是否打开弹窗bind:open={showDialog}
export let open = false
// 弹窗标识
export let id = undefined
// 标题
export let title = ''
// 内容
export let content = ''
// 弹窗类型
export let type = ''
// 自定义样式
export let layerStyle = undefined
// 自定义类名
export let customClass = ''
// toast图标
export let icon = ''
// 是否显示遮罩层
export let shade = true
// 点击遮罩层关闭
export let shadeClose = true
// 锁定屏幕
export let lockScroll = true
// 遮罩层透明度
export let opacity = ''
// 是否显示关闭图标
export let xclose = false
// 关闭图标位置
export let xposition = 'right'
// 关闭图标颜色
export let xcolor = '#000'
// 弹窗动画
export let anim = 'scaleIn'
// 弹出位置(auto | ['100px','50px'] | t | r | b | l | lt | rt | lb | rb)
export let position = 'auto'
// 抽屉弹窗
export let drawer = ''
// 右键弹窗定位
export let follow = null
// 弹窗自动关闭时间
export let time = 0
// 弹窗层级
export let zIndex = 202204
// 置顶弹窗
export let topmost = false
// 弹窗大小
export let area = 'auto'
// 弹窗最大宽度
export let maxWidth = 375
// 弹窗是否最大化
export let maximize = false
// 弹窗是否全屏
export let fullscreen = false
// 是否固定
export let fixed = true
// 是否拖拽
export let drag = '.vlayer__wrap-tit'
// 是否拖拽屏幕外
export let dragOut = false
// 限制拖拽方向 vertical|horizontal
export let dragDir = ''
// 拖拽结束回调 {width: 120, height: 120, x: 100, y: 100}
export let dragEnd = undefined
// 是否缩放
export let resize = false
// 弹窗按钮事件
export let btns = null
/*export let btns = [
{text: '取消', style: 'color:red', disabled: true, click: null},
{text: '确定', style: 'color:blue', click: null}
]*/
// 函数式打开|关闭回调
export let onOpen = undefined
export let onClose = undefined
export let beforeClose = undefined
// ...
</script>
弹窗模板
<div class="vui__layer" class:opened class:vui__layer-closed={closeCls} id={id} bind:this={el}>
<!-- 遮罩层 -->
{#if bool(shade)}<div class="vlayer__overlay" on:click={shadeClicked} style:opacity></div>{/if}
<!-- 主体 -->
<div class="vlayer__wrap {type&&'popui__'+type} anim-{anim}" style="{layerStyle}">
{#if title}<div class="vlayer__wrap-tit">{@html title}</div>{/if}
{#if icon&&type=='toast'}<div class="vlayer__toast-icon vlayer__toast-{icon}">{@html toastIcon[icon]}</div>{/if}
<div class="vlayer__wrap-cntbox">
<!-- 判断content插槽是否存在 -->
{#if $slots.content}
<div class="vlayer__wrap-cnt"><slot name="content" /></div>
{:else}
{#if content}
<!-- iframe -->
{#if type=='iframe'}
<div class="vlayer__wrap-iframe">
<iframe scrolling="auto" allowtransparency="true" frameborder="0" src={content}></iframe>
</div>
<!-- message|notify|popover -->
{:else if type=='message' || type=='notify' || type=='popover'}
<div class="vlayer__wrap-cnt">
{#if icon}<i class="vlayer-msg__icon {icon}">{@html messageIcon[icon]}</i>{/if}
<div class="vlayer-msg__group">
{#if title}<div class="vlayer-msg__title">{@html title}</div>{/if}
<div class="vlayer-msg__content">{@html content}</div>
</div>
</div>
<!-- 加载动态组件 -->
{:else if type == 'component'}
<svelte:component this={content}/>
{:else}
<div class="vlayer__wrap-cnt">{@html content}</div>
{/if}
{/if}
{/if}
<slot />
</div>
<!-- 按钮组 -->
{#if btns}
<div class="vlayer__wrap-btns">
{#each btns as btn,index}
<span class="btn" class:btn-disabled={btn.disabled} style="{btn.style}">{@html btn.text}</span>
{/each}
</div>
{/if}
{#if xclose}
<span class="vlayer__xclose" style="color: {xcolor}" on:click={hide}></span>
{/if}
{#if maximize}<span class="vlayer__maximize" on:click={maximizeClicked}></span>{/if}
<!-- 缩放 -->
{#if resize}
<span class="vlayer__groupresize">
<i class="vlayer__resize LT"></i>
<i class="vlayer__resize RT"></i>
<i class="vlayer__resize LB"></i>
<i class="vlayer__resize RB"></i>
</span>
{/if}
</div>
<!-- 优化拖拽卡顿 -->
<div class="vlayer__dragfix"></div>
</div>
当弹窗类型为message|notify|popover,则调用方式如下:
svLayer.message({})
svLayer.notify({})
svLayer.popover({})
ok,基于svelte.js自定义pc端弹窗组件就分享到这里。后续还会分享一些svelte组件实例。