2025最新版研发vite7.1+vue3.5+pinia3+element-plus
搭建仿微信界面web版聊天系统。
vite-webchat集合聊天、联系人、收藏、朋友圈、小视频、我的等模块。支持多行消息、光标位置插入gif动图、图片/视频预览、红包等功能。
基于最新vite7
构建工具创建项目模板。
使用全新的数字密码解锁登录方式。
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')
布局结构分为左侧菜单栏+侧边栏+右侧主内容区三部分。
<script setup>
import { useRoute } from 'vue-router'
import { appState } from '@/pinia/modules/app'
import MenuBar from './components/menubar/index.vue'
import SideBar from './components/sidebar/index.vue'
import Winbtn from './components/winbtn.vue'
const route = useRoute()
const appstate = appState()
</script>
<template>
<div class="vu__container" :class="{'fullscreen': appstate.config.fullscreen}" :style="{'--themeSkin': appstate.config.skin}">
<div class="vu__layout flexbox flex-col">
<div class="vu__layout-body flex1 flexbox" @contextmenu.prevent>
<!-- 菜单栏 -->
<slot v-if="!route?.meta?.hideMenuBar" name="menubar">
<MenuBar />
</slot>
<!-- 侧边栏 -->
<div v-if="route?.meta?.showSideBar" class="vu__layout-sidebar flexbox" :class="{'hidden': appstate.config.collapsed}">
<aside class="vu__layout-sidebar__body flexbox flex-col">
<slot name="sidebar">
<SideBar />
</slot>
</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>
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 })
console.log(modules)
const patchRouters = Object.keys(modules).map(key => modules[key].default).flat()
console.log(patchRouters)
/**
* 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) {
return {
path: '/login'
}
}
})
router.afterEach((to, from) => {
// 阻止浏览器回退
if(to?.meta?.canGoBack == false && from.path != null) {
history.pushState(history.state, '', document.URL)
}
})
router.onError(error => {
console.warn('[Router Error]', error)
})
export default router
采用Slider组件实现功能。支持实时显示当前播放进度、拖拽到指定位置。
<div class="vu__video-container">
<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>
<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>
最新原创flutter3.27+bitsdojo_window客户端聊天Exe
基于uni-app+vue3实战短视频+聊天+直播app商城
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。