优秀的编程知识分享平台

网站首页 > 技术文章 正文

svelte组件系列:svelte3.x自定义pc端弹窗组件svelteLayer

nanyue 2024-08-10 18:46:19 技术文章 7 ℃

之前有给大家分享一个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组件实例。

最近发表
标签列表