Svelte3高仿微信web版聊天实例|svelte+svelteKit网页聊天室

957 阅读2分钟

SvelteWebChat 一款精致的仿制微信网页桌面端聊天项目

基于前端新框架svelte.js+svelteKit+sass+svelte-scrollbar等技术开发构建。不一样的dock可拖拽滑动菜单。支持动态虚化换肤主题,可全屏界面。

32360截图20220514114311231.png

技术栈

  • 框架技术:svelte^3.46.5+svelteKit
  • 下拉刷新组件:mescroll.js
  • iconfont图标:阿里巴巴字体图标库
  • 自定义滚动条:svelte-scrollbar
  • 自定义弹窗:svelte-layer
  • sass预编译:sass^1.50.1+svelte-preprocess

p3.gif

svelte-webchat 支持发送消息+emoj表情、图片/视频查看、链接预览、粘贴截图+拖拽发送图片、红包/朋友圈、全屏/主题换肤等功能。

p4.gif

项目目录结构

使用最新的svelte.js+svelteKit技术开发,目录分层结构如下。

360截图20220514120136666.png

svelte-webchat内置了朋友圈功能。可下拉刷新、查看大图、发布弹窗功能。

p5.gif

svelte自定义弹窗+滚动条组件

整个项目使用的对话框及滚动条均是自定义组件实现效果。

19360截图20220514111642509.png svelte-layer自定义pc端弹窗组件

22360截图20220514111917258.png svelte-scrollbar自定义pc端美化系统滚动条组件

如果大家对svelte.js自定义组件感兴趣,可以看看上面两篇分享文章。

svelte.js公共模板

基于svelte-kit构建的项目,提供了__layout.svelte布局模板和__error.svelte错误页。

项目整体布局分为左侧+右侧主体内容+底部dock三个大模块。其中右侧又分为顶部winbar组件和headerTitle组件。

360截图20220515082632971.png

<div class="sv__container flexbox flex-alignc flex-justifyc" style="--themeSkin: {$skin}">
    <div class="sv__wrapper" class:maximize={$isWinMaximize}>
        {#if $userinfo}
        <div class="sv__board flexbox flex-col">
            <!-- <div class="sv__topbar">顶部模块</div> -->
            <div class="sv__mainwrap flex1 flexbox">
                <!-- <div class="sv__sidebar">侧边栏</div> -->
                <Middle />
                <div class="sv__mainbx flex1 flexbox flex-col">
                    <Winbar />
                    <slot />
                </div>
            </div>
            <Dock />
        </div>
        {:else}
        <div class="sv__board flexbox flex-col">
            <div class="sv__mainwrap flex1 flexbox">
                <slot />
            </div>
        </div>
        {/if}
    </div>
</div>

__error.svelte错误页

360截图20220515103113390.png

<script context="module">
    export function load({ error, status }) {
        return {
            props: { error, status }
        }
    }
</script>

<script>
    import { goto } from '$app/navigation'
    export let status
    export let error

    function goBack() {
        // history.go(-1)
        goto('/')
    }
</script>

<svelte:head>
    <title>{status} Error!</title>
</svelte:head>

<div class="sv__scrollview flex1">
    <div class="sv__page-error flexbox flex-col flex-alignc flex-justifyc">
        <div class="sv__page-error-img">
            <img src="404.png" alt="" />
        </div>
        <div class="sv__page-error-content">
            <div class="c-red fs-18">┗| {status} |┛  Page Error~~</div>
            <div class="c-999 mt-10">{error.message}</div>
            <div class="sv__btn sv__btn-default" style="color:#40b3ff;height:32px;width:120px;" on:click={goBack}><i class="iconfont icon-arrL"></i> 返回首页</div>
        </div>
    </div>
</div>

svelte实现dock菜单

p0.gif

dock菜单支持拖拽图标排序、滚轮左右滚动切换。自定义img图片/iconfont图标、红点提示。

<div class="sv__dockbar flexbox flex-justifyc">
	<div class="sv__dock-scroll" style="background: {bgcolor};">
		<Scrollbar autohide size={2} mousewheel>
			<div class="sv__dock-wrap" bind:this={dockEl}>
				<!-- dock菜单项 -->
				{#each menu as item,index}
					{#if item.type == 'divider'}
						<div class="sv__dock-divider"></div>
					{:else}
						<div class="sv__dock-item flexbox" class:cur={currentTabIndex == index} id={item.id || 'dock'+index} role="{item.title}" style="color: {currentTabIndex == index ? activeColor : color}" on:click={changeTab(index, item)}>
							{#if item.icon}<span class="iconfont {item.icon}" style="color: {item.color}; font-size: {item.iconSize}">{item.icon.charAt(1) == '' ? item.icon : ''}</span>{/if}
							{#if item.img}<img class="iconimg" src={item.img} alt="" style="font-size: {item.iconSize};" />{/if}
							{#if item.badge}<span class="sv__badge sv__dock-badge">{item.badge}</span>{/if}
							{#if item.dot}<span class="sv__badge-dot sv__dock-badgeDot"></span>{/if}
						</div>
					{/if}
				{/each}
			</div>
		</Scrollbar>
	</div>
</div>

p7-2.gif

聊天编辑框支持光标位置插入emoj表情、换行文本、粘贴截图及拖拽发送图片功能。

p7.gif

编辑器监听paste事件,并获取粘贴的图片,通过自定义事件传给聊天页面。

editorEl.addEventListener('paste', function(e) {
	e.preventDefault()

	let cbd = e.clipboardData
	let ua = window.navigator.userAgent
	if(!(e.clipboardData && e.clipboardData.items)) return

	if(cbd.items && cbd.items.length === 2 && cbd.items[0].kind === "string" && cbd.items[1].kind === "file" &&
		cbd.types && cbd.types.length === 2 && cbd.types[0] === "text/plain" && cbd.types[1] === "Files" &&
		ua.match(/Macintosh/i) && Number(ua.match(/Chrome\/(\d{2})/i)[1]) < 49){
		return;
	}
	for(var i = 0; i < cbd.items.length; i++) {
		var item = cbd.items[i]
		// console.log(item)
		// console.log(item.kind)
		if(item.kind == 'file') {
			var blob = item.getAsFile()
			if(blob.size === 0) return
			// 读取图片记录
			var reader = new FileReader()
			reader.readAsDataURL(blob)
			reader.onload = function() {
				var imgpath = this.result

				// 返回图片给父组件
				dispatch('paste', imgpath)
			}
		}
	}
})

好了,基于svelte.js开发网页聊天就分享到这里。希望大家能喜欢哈~~

最后附上一个vite2+vue3+electron跨端后台管理系统

juejin.cn/post/696331…

a8a5dc63jw1falkc05snfg206q046gli.gif