svelte3.x-webchat 仿微信PC版聊天实例|svelte.js聊天实战项目
svelte-webchat 基于svelte.js+svelteKit+scss+svelte-layer
等技术开发的网页版聊天实例。
支持发送消息+emoj表情、图片/视频查看、链接预览、粘贴截图发送图片、红包/朋友圈、全屏/主题换肤等功能。
使用技术
- 框架技术:svelte^3.46.5+svelteKit
- 状态管理:svelte/store
- 下拉刷新:mescroll.js
- iconfont图标:阿里巴巴字体图标库
- 自定义滚动条:svelte-scrollbar
- 自定义弹窗:svelte-layer
- sass/less预处理:sass^1.50.1+svelte-preprocess
目录结构
svelte.js公共模板
基于svelte-kit构建的项目,提供了layout.svelte公共模板及error.svelte错误页。
<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>
<!-- //Svelte错误页 -->
<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.js自定义组件
项目中随处可见的弹窗及滚动条均是svelte.js自定义组件实现功能。
svelte-layer基于svelte.js网页版弹窗组件
svelte-scrollbar基于svelte.js自定义美化滚动条组件
svelte登录拦截及表单验证
<script>
import { onMount } from 'svelte'
import { goto } from '$app/navigation'
import Layer, { svLayer } from '$lib/Layer'
import { userinfo } from '@/store'
import util from '@/utils'
let formObj = {}
let vcodeText = '获取验证码'
let disabled = false
let time = 0
let agree = false
let vcodeLG = true
let telEl
onMount(() => {
userinfo.useStorage()
telEl.focus()
})
function Message(content) {
svLayer.message({content, icon: 'warning', time: 0, xclose: true, shade: true})
}
// 60s倒计时
function getVcode() {
let { tel } = formObj
if(!tel) {
Message('手机号不能为空')
}else if(!util.checkTel(tel)) {
Message('手机号不正确')
}else {
time = 60
disabled = true
countDown()
}
}
function countDown() {
if(time > 0) {
vcodeText = '获取验证码('+ time +')'
time--
setTimeout(countDown, 1000)
}else {
vcodeText = '获取验证码'
time = 0
disabled = false
}
}
function handleSubmit() {
console.log('——+——+——表单数据:', formObj)
let { tel, vcode, pwd } = formObj
if(!tel) {
Message('手机号不能为空')
}else if(!util.checkTel(tel)) {
Message('手机号不正确')
}else if(vcodeLG && !vcode) {
Message('验证码不能为空')
}else if(!vcodeLG && !pwd) {
Message('密码不能为空')
}else {
svLayer({
type: 'toast',
icon: 'success',
content: '登录成功',
shadeClose: false,
time: 2,
onClose: () => {
userinfo.set({
user: tel,
token: util.setToken()
})
goto('/')
}
})
}
}
</script>
svelte.js粘贴截图/拖拽上传
如上图:聊天编辑框支持粘贴截图发送,拖拽上传功能。
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)
}
}
}
})
监听drop拖拽事件。
/**
* svelte拖拽上传图片
* author:andy Q:282310962
*/
function handleDragEnter(e) {
e.stopPropagation()
e.preventDefault()
}
function handleDragOver(e) {
e.stopPropagation()
e.preventDefault()
}
function handleDrop(e) {
e.stopPropagation()
e.preventDefault()
handleFileList(e.dataTransfer)
}
// 拖拽文件列表
function handleFileList(filelist) {
let files = filelist.files
if(files.length >= 2) {
svLayer.message({content: '暂时支持拖拽一张图片', icon: 'error', time: 0, xclose: true, shade: true})
return false
}
for(let i = 0; i < files.length; i++) {
if(files[i].type != '') {
handleFileAdd(files[i])
}else {
svLayer.message({content: '目前不支持文件夹拖拽功能', icon: 'error', time: 0, xclose: true, shade: true})
}
}
}
function handleFileAdd(file) {
let len = msgList.length
// 消息队列
let msgArr = {
id: `msg_${++len}`,
msgtype: 5,
isme: true,
avatar: '/uimg/img-avatar08.jpg',
author: 'Hison',
msg: '',
imgsrc: '',
videosrc: ''
}
if(file.type.indexOf('image') == -1) {
svLayer.message({content: '目前不支持非图片拖拽功能', icon: 'error', time: 0, xclose: true, shade: true})
}else {
let reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = async function() {
let img = this.result
msgArr.imgsrc = img
msgList = msgList.concat(msgArr)
await tick()
scrollBottom()
}
}
}
好了,以上就是svelte.js开发网页聊天实例的一些分享。
uniapp+uview仿抖音app实例
本作品采用《CC 协议》,转载必须注明作者和本文链接