0


vite5-webchat:基于vite5+vue3.x+element-plus网页版聊天系统

原创vite-vue3-wechat仿微信网页版界面聊天实例。

基于最新前端技术

vite5.x+vue3+vue-router+pinia+elementPlus

搭建网页端聊天室。实现了聊天、通讯录、朋友圈、短视频、我的等功能模块。支持侧边栏展开/收缩、动态主题壁纸、锁屏、最大化等功能。

在这里插入图片描述
vite-wechat实现了文字/emoj混排、图片/视频预览、红包、地图、语音播放等功能。

在这里插入图片描述

使用技术

  • 编辑器:vscode
  • 框架技术:vite5.2+vue3.4+vue-router4.3+pinia2
  • UI组件库:element-plus^2.7.5 (饿了么网页端vue3组件库)
  • 状态管理:pinia^2.1.7
  • 地图插件:@amap/amap-jsapi-loader(高德地图组件)
  • 视频滑动:swiper^11.1.4
  • 预编译样式:sass^1.77.4
  • 构建工具:vite^5.2.0

在这里插入图片描述
在这里插入图片描述

项目结构目录

vite-wechat使用

vite5.x

构建项目模板,采用

vue3 setup

语法糖编码开发模式。
在这里插入图片描述
在这里插入图片描述

main.js配置

import{ createApp }from'vue'import'./style.scss'import App from'./App.vue'// 引入组件库import ElementPlus from'element-plus'import'element-plus/dist/index.css'import VEPlus from've-plus'import've-plus/dist/ve-plus.css'// 引入路由/状态管理import Router from'./router'import Pinia from'./pinia'const app =createApp(App)

app
.use(ElementPlus).use(VEPlus).use(Router).use(Pinia).mount('#app')

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

vue3实现滑动解锁

在这里插入图片描述

<script setup>import{ ref, computed, inject, nextTick }from'vue'import{ useRouter }from'vue-router'import{ authState }from'@/pinia/modules/auth'import{ uuid, guid }from'@/utils'const authstate =authState()const router =useRouter()// 启动页const splashScreen =ref(true)const authPassed =ref(false)// 滑动距离const touchY =ref(0)const touchable =ref(false)// 数字键盘输入值const pwdValue =ref('')const keyNumbers =ref([{letter:'a'},{letter:'b'},{letter:'c'},{letter:'d'},{letter:'e'},{letter:'f'},{letter:'g'},{letter:'h'},{letter:'i'},{letter:'j'},{letter:'k'},{letter:'l'},{letter:'m'},{letter:'n'},{letter:'o'},{letter:'p'},{letter:'q'},{letter:'r'},{letter:'s'},{letter:'t'},{letter:'u'},{letter:'v'},{letter:'w'},{letter:'x'},{letter:'y'},{letter:'z'},{letter:'1'},{letter:'2'},{letter:'3'},{letter:'4'},{letter:'5'},{letter:'6'},{letter:'7'},{letter:'8'},{letter:'9'},{letter:'0'},{letter:'@'},{letter:'#'},{letter:'%'},{letter:'&'},{letter:'!'},{letter:'*'},])//...// 触摸事件(开始/更新)consthandleTouchStart=(e)=>{
    touchY.value = e.clientY
    touchable.value =true}consthandleTouchUpdate=(e)=>{let swipeY = touchY.value - e.clientY
    if(touchable.value && swipeY >100){
      splashScreen.value =false
      touchable.value =false}}consthandleTouchEnd=(e)=>{
    touchY.value =0
    touchable.value =false}// 点击数字键盘consthandleClickNum=(num)=>{let pwdLen = passwordArr.value.length
    if(pwdValue.value.length >= pwdLen)return
    pwdValue.value += num
    if(pwdValue.value.length == pwdLen){// 验证通过if(pwdValue.value == password.value){// ...}else{setTimeout(()=>{
          pwdValue.value =''},200)}}}// 删除consthandleDel=()=>{let num =Array.from(pwdValue.value)
    num.splice(-1,1)
    pwdValue.value = num.join('')}// 清空consthandleClear=()=>{
    pwdValue.value =''}// 返回consthandleBack=()=>{
    splashScreen.value =true}</script><template><div class="uv3__launch"><div
        v-if="splashScreen"class="uv3__launch-splash"@mousedown="handleTouchStart"@mousemove="handleTouchUpdate"@mouseup="handleTouchEnd"><div class="uv3__launch-splashwrap">...</div></div><div v-elseclass="uv3__launch-keyboard"><div class="uv3__launch-pwdwrap"><div class="text">密码解锁</div><div class="circle flexbox"><div v-for="(num, index) in passwordArr":key="index"class="dot":class="{'active': num <= pwdValue.length}"></div></div></div><div class="uv3__launch-numwrap"><div v-for="(item, index) in keyNumbers":key="index"class="numbox flex-c"@click="handleClickNum(item.letter)"><div class="num">{{item.letter}}</div></div></div><div class="foot flexbox"><Button round icon="ve-icon-clean"@click="handleClear">清空</Button><Button type="danger" v-if="pwdValue" round icon="ve-icon-backspace"@click="handleDel">删除</Button><Button v-else round icon="ve-icon-rollback"@click="handleBack">返回</Button></div></div></div></template>

vue3-wechat布局模板

在这里插入图片描述

<template><div class="vu__container":style="{'--themeSkin': appstate.config.skin}"><div class="vu__layout"><div class="vu__layout-body"><!-- 菜单栏 --><slot v-if="!route?.meta?.hideMenuBar" name="menubar"><MenuBar /></slot><!-- 侧边栏 --><div v-if="route?.meta?.showSideBar"class="vu__layout-sidebar":class="{'hidden': appstate.config.collapsed}"><aside class="vu__layout-sidebar__body flexbox flex-col"><slot name="sidebar"><SideBar /></slot><!-- 折叠 --><Collapse /></aside></div><!-- 内容区 --><div class="vu__layout-main flex1 flexbox flex-col"><Winbtn v-if="!route?.meta?.hideWinBar"/><router-view v-slot="{ Component, route }"><keep-alive><component :is="Component":key="route.path"/></keep-alive></router-view></div></div></div></div></template>

vue3路由管理

在这里插入图片描述

/**
 * 路由管理Router
 * @author andy
 */import{ createRouter, createWebHashHistory }from'vue-router'import{ authState }from'@/pinia/modules/auth'import Layout from'@/layouts/index.vue'// 批量导入路由const modules =import.meta.glob('./modules/*.js',{ eager:true})const patchRouters = Object.keys(modules).map(key => modules[key].default).flat()/**
 * meta配置
 * @param meta.requireAuth 需登录验证页面
 * @param meta.hideWinBar 隐藏右上角按钮组
 * @param meta.hideMenuBar 隐藏菜单栏
 * @param meta.showSideBar 显示侧边栏
 * @param meta.canGoBack 是否可回退上一页
 */const routes =[...patchRouters,// 错误模块{
    path:'/:pathMatch(.*)*',
    redirect:'/404',
    component: Layout,
    meta:{
      title:'404error',
      hideMenuBar:true,
      hideWinBar:true,},
    children:[{
        path:'404',component:()=>import('@/views/error/404.vue'),}]},]const router =createRouter({
  history:createWebHashHistory(),
  routes,})// 全局路由钩子拦截
router.beforeEach((to, from)=>{const authstate =authState()// 登录验证if(to?.meta?.requireAuth &&!authstate.authorization){console.log('你还未登录!')return{
      path:'/login'}}})

router.afterEach((to, from)=>{// 阻止浏览器回退if(to?.meta?.canGoBack ==false&& from.path !=null){
    history.pushState(history.state,'', document.URL)}})

vue3小视频模块

vite5-wechat项目加入了小视频模块。使用

swiper

组件实现上下滑动小视频。
在这里插入图片描述
视频底部mini播放进度条,采用

Slider

组件实现功能。支持拖拽到指定时间点。

在这里插入图片描述

<!-- 短视频模块 --><div class="vu__video-container"><!-- tabs操作栏 --><div class="vu__video-tabswrap flexbox"><el-tabs v-model="activeName"class="vu__video-tabs"><el-tab-pane label="关注" name="attention"/><el-tab-pane label="推荐" name="recommend"/></el-tabs></div><swiper-container
        class="vu__swiper"
        direction="vertical":speed="150":grabCursor="true":mousewheel="{invert: true}"@swiperslidechange="onSlideChange"><swiper-slide v-for="(item, index) in videoList":key="index"><!-- 视频层 --><video
                class="vu__player":id="'vuplayer-' + index":src="item.src":poster="item.poster"
                loop
                preload="auto":autoplay="index == currentVideo"
                webkit-playsinline="true" 
                x5-video-player-type="h5-page"
                x5-video-player-fullscreen="true"
                playsinline
                @click="handleVideoClicked"></video><div v-if="!isPlaying"class="vu__player-btn"@click="handleVideoClicked"></div><!-- 右侧操作栏 --><div class="vu__video-toolbar">...</div><!-- 底部信息区域 --><div class="vu__video-footinfo flexbox flex-col"><div class="name">@{{item.author}}</div><div class="content">{{item.desc}}</div></div></swiper-slide></swiper-container><!--///底部进度条 --><el-slider class="vu__video-progressbar" v-model="progressBar"@input="handleSlider"@change="handlePlay"/><div v-if="isDraging"class="vu__video-duration">{{videoTime}}/{{videoDuration}}</div></div>

vue3聊天模块

在这里插入图片描述

聊天输入框支持多行文本输入、光标处插入gif图片、粘贴截图发送图片等功能。

在这里插入图片描述
在这里插入图片描述

<template><!-- 顶部导航 -->...<!-- 内容区 --><div class="vu__layout-main__body"><Scrollbar ref="scrollRef" autohide gap="2"><!-- 渲染聊天内容 --><div class="vu__chatview"@dragenter="handleDragEnter"@dragover="handleDragOver"@drop="handleDrop">...</div></Scrollbar></div><!-- 底部操作栏 --><div class="vu__footview"><div class="vu__toolbar flexbox">...</div><div class="vu__editor"><Editor ref="editorRef" v-model="editorValue"@paste="handleEditorPaste"/></div><div class="vu__submit"><button @click="handleSubmit">发送(S)</button></div></div>...</template>

vue3使用高德地图。

// 拾取地图位置let map =nullconsthandlePickMapLocation=()=>{
  popoverChooseRef?.value?.hide()
  mapLocationVisible.value =true// 初始化地图
  AMapLoader.load({
    key:"af10789c28b6ef1929677bc5a2a3d443",// 申请好的Web端开发者Key,首次调用 load 时必填
    version:"2.0",// 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15}).then((AMap)=>{// JS API 加载完成后获取AMap对象
    map =newAMap.Map("vu__mapcontainer",{
      viewMode:"3D",// 默认使用 2D 模式
      zoom:10,// 初始化地图级别
      resizeEnable:true,})// 获取当前位置
    AMap.plugin('AMap.Geolocation',function(){var geolocation =newAMap.Geolocation({// 是否使用高精度定位,默认:true
        enableHighAccuracy:true,// 设置定位超时时间,默认:无穷大
        timeout:10000,// 定位按钮的停靠位置的偏移量,默认:Pixel(10, 20)
        buttonOffset:newAMap.Pixel(10,20),// 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
        zoomToAccuracy:true,// 定位按钮的排放位置, RB表示右下
        buttonPosition:'RB'})

      map.addControl(geolocation)
      geolocation.getCurrentPosition(function(status, result){if(status =='complete'){onComplete(result)}else{onError(result)}})})// 定位成功的回调函数functiononComplete(data){var str =['定位成功']
      str.push('经度:'+ data.position.getLng())
      str.push('纬度:'+ data.position.getLat())if(data.accuracy){
        str.push('精度:'+ data.accuracy +' 米')}// 可以将获取到的经纬度信息进行使用console.log(str.join('<br>'))}// 定位失败的回调函数functiononError(data){console.log('定位失败:'+ data.message)}}).catch((e)=>{// 加载错误提示console.log('amapinfo', e)})}// 打开预览地图位置consthandleOpenMapLocation=(data)=>{
  mapLocationVisible.value =true// 初始化地图
  AMapLoader.load({
    key:"af10789c28b6ef1929677bc5a2a3d443",// 申请好的Web端开发者Key,首次调用 load 时必填
    version:"2.0",// 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15}).then((AMap)=>{// JS API 加载完成后获取AMap对象
    map =newAMap.Map("vu__mapcontainer",{
      viewMode:"3D",// 默认使用 2D 模式
      zoom:13,// 初始化地图级别
      center:[data.longitude, data.latitude],// 初始化地图中心点位置})// 添加插件
    AMap.plugin(["AMap.ToolBar","AMap.Scale","AMap.HawkEye"],function(){//异步同时加载多个插件
      map.addControl(newAMap.ToolBar())// 缩放工具条
      map.addControl(newAMap.HawkEye())// 显示缩略图
      map.addControl(newAMap.Scale())// 显示当前地图中心的比例尺})

    mapPosition.value =[data.longitude, data.latitude]addMarker()// 实例化点标记functionaddMarker(){const marker =newAMap.Marker({
        icon:"//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
        position: mapPosition.value,
        offset:newAMap.Pixel(-26,-54),})
      marker.setMap(map)/* marker.setLabel({
        direction:'top',
        offset: new AMap.Pixel(0, -10),  //设置文本标注偏移量
        content: "<div class='info'>我是 marker 的 label 标签</div>", //设置文本标注内容
      }) *///鼠标点击marker弹出自定义的信息窗体
      marker.on('click',function(){
        infoWindow.open(map, marker.getPosition())})const infoWindow =newAMap.InfoWindow({
        offset:newAMap.Pixel(0,-60),
        content:`
          <div style="padding: 10px;">
            <p style="font-size: 14px;">${data.name}</p>
            <p style="color: #999; font-size: 12px;">${data.address}</p>
          </div>
        `})}}).catch((e)=>{// 加载错误提示console.log('amapinfo', e)})}// 关闭预览地图位置consthandleCloseMapLocation=()=>{
  map?.destroy()
  mapLocationVisible.value =false}

OK,以上就是vue3+vite5+element-plus开发网页聊天项目的一些分享。

https://blog.csdn.net/yanxinyun1990/article/details/139510447

https://blog.csdn.net/yanxinyun1990/article/details/138317354

https://blog.csdn.net/yanxinyun1990/article/details/136996521

在这里插入图片描述


本文转载自: https://blog.csdn.net/yanxinyun1990/article/details/139890070
版权归原作者 xiaoyan_2018 所有, 如有侵权,请联系我们删除。

“vite5-webchat:基于vite5+vue3.x+element-plus网页版聊天系统”的评论:

还没有评论