vue仿微信网页版|vue+web端聊天室|仿微信客户端vue版
一、项目介绍
基于Vue2.5.6+Vuex+vue-cli+vue-router+vue-gemini-scrollbar+swiper+elementUI等技术混合架构开发的仿微信web端聊天室——vueWebChat,实现了发送消息、表情(动图),图片、视频预览,右键菜单、截屏、截图可直接粘贴至文本框进行发送。
二、技术框架
- MVVM框架:Vue2.5.6
- 状态管理:Vuex
- 页面路由:Vue-router
- iconfont图标:阿里巴巴字体图标库
- 自定义滚动条:vue-gemini-scrollbar
- 弹窗组件:element-ui(饿了么前端UI库)
- 环境配置:node.js + cnpm + webpack
- 高德地图:vue-amap
- 图片预览:vue-photo-preview
◆ 点击右上角最大化按钮,可以进行全屏切换
◆ 引入公共及全局组件配置components.js
/* 引入公共及全局组件配置 */ // 引入侧边栏及联系人 import winBar from \'./components/winbar\' import sideBar from \'./components/sidebar\' import recordList from \'./components/recordList\' import contactList from \'./components/contact\' // 引入jquery import $ from \'jquery\' // 引入wcPop弹窗插件 import wcPop from \'./assets/js/wcPop/wcPop\' import \'./assets/js/wcPop/skin/wcPop.css\' // 引入饿了么pc端UI库 import elementUI from \'element-ui\' import \'element-ui/lib/theme-chalk/index.css\' // 引入图片预览插件 import photoPreview from \'vue-photo-preview\' import \'vue-photo-preview/dist/skin.css\' // 引入自定义滚动条插件 import geminiScrollbar from \'vue-gemini-scrollbar\' // 引入加载更多插件 import infiniteLoading from \'vue-infinite-scroll\' // 引入高德地图 import vueAMap from \'vue-amap\' const install = Vue => { // 注册组件 Vue.component(\'win-bar\', winBar) Vue.component(\'side-bar\', sideBar) Vue.component(\'record-list\', recordList) Vue.component(\'contact-list\', contactList) // 应用实例 Vue.use(elementUI) Vue.use(photoPreview, { loop: false, fullscreenEl: true, //是否全屏 arrowEl: true, //左右按钮 }); Vue.use(geminiScrollbar) Vue.use(infiniteLoading) Vue.use(vueAMap) vueAMap.initAMapApiLoader({ key: "e1dedc6bdd765d46693986ff7ff969f4", plugin: [ "AMap.Autocomplete", //输入提示插件 "AMap.PlaceSearch", //POI搜索插件 "AMap.Scale", //右下角缩略图插件 比例尺 "AMap.OverView", //地图鹰眼插件 "AMap.ToolBar", //地图工具条 "AMap.MapType", //类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制 "AMap.PolyEditor", //编辑 折线多,边形 "AMap.CircleEditor", //圆形编辑器插件 "AMap.Geolocation" //定位控件,用来获取和展示用户主机所在的经纬度位置 ], uiVersion: "1.0" }); } export default install
◆ 主页面模板
<template> <div id="app"> <div class="vChat-wrapper flexbox flex-alignc"> <div class="vChat-panel" style="background-image: url(src/assets/img/placeholder/vchat__panel-bg01.jpg);"> <div class="vChat-inner flexbox"> <!-- //顶部按钮(最大、最小、关闭) --> <win-bar></win-bar> <!-- //侧边栏 --> <side-bar></side-bar> <keep-alive> <router-view class="flex1 flexbox"></router-view> </keep-alive> </div> </div> </div> </div> </template> <script> export default { name: \'app\', data () { return { } }, methods: { }, } </script> <style> /* 引入公共样式 */ @import \'./assets/fonts/iconfont.css\'; @import \'./assets/css/reset.css\'; @import \'./assets/css/layout.css\'; </style>
◆ vue文本框实现截图粘贴发送图片:
// 【截图粘贴图片】 document.getElementById(\'J__wcEditor\').addEventListener(\'paste\',function(e){ var cbd = e.clipboardData; var ua = window.navigator.userAgent; // 没有数据 if (!(e.clipboardData && e.clipboardData.items)) { return; } // Mac平台下Chrome49版本以下 复制Finder中的文件的Bug Hack掉 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 _img = this.result; var _tpl = [ \'<li class="me">\ <div class="content">\ <p class="author">王梅(Fine)</p>\ <div class="msg picture"><img class="img__pic" src="\'+ _img + \'" preview="1" /></div>\ </div>\ <a class="avatar" href="/contact/uinfo"><img src="src/assets/img/uimg/u__chat-img11.jpg" /></a>\ </li>\' ].join(""); $("#J__chatMsgList").append(_tpl); setTimeout(() => { $("#J__geminiScrollbar .gm-scroll-view").animate({ scrollTop: $("#J__chatMsgList").height() }, 0); $(".fixGeminiscrollHeight").show(); setTimeout(() => { $(".fixGeminiscrollHeight").hide();}, 300); }, 17); } } } });
◆ 表情处理及视频预览:
// >>> 【表情、动图swiper切换模块】-------------------------- var emotionSwiper; function setEmotionSwiper(tmpl) { var _tmpl = tmpl ? tmpl : $("#J__emotionFootTab ul li.cur").attr("tmpl"); $("#J__swiperEmotion .swiper-container").attr("id", _tmpl); $("#J__swiperEmotion .swiper-wrapper").html($("." + _tmpl).html()); emotionSwiper = new Swiper(\'#\' + _tmpl, { // loop: true, // autoplay: true, // 分页器 pagination: { el: \'.pagination-emotion\', clickable: true, }, }); } // 表情模板切换 $("body").on("click", "#J__emotionFootTab ul li.swiperTmpl", function () { // 先销毁swiper emotionSwiper && emotionSwiper.destroy(true, true); var _tmpl = $(this).attr("tmpl"); $(this).addClass("cur").siblings().removeClass("cur"); setEmotionSwiper(_tmpl); }); // >>> 【视频预览模块】-------------------------- $("body").on("click", "#J__chatMsgList li .video", function () { var _src = $(this).find("img").attr("videoUrl"), _video; var videoIdx = wcPop({ id: \'wc__previewVideo\', skin: \'fullscreen\', // content: \'<video id="J__videoPreview" width="100%" height="100%" controls="controls" x5-video-player-type="h5" x5-video-player-fullscreen="true" webkit-playsinline preload="auto"></video>\', content: \'<video id="J__videoPreview" width="100%" height="100%" controls="controls" preload="auto"></video>\', shade: false, xclose: true, style: \'background: #000;padding-top:48px;\', anim: \'scaleIn\', show: function(){ _video = document.getElementById("J__videoPreview"); _video.src = _src; if (_video.paused) { _video.play(); } else { _video.pause(); } // 播放结束 _video.addEventListener("ended", function(){ _video.currentTime = 0; }); // 退出全屏 _video.addEventListener("x5videoexitfullscreen", function(){ wcPop.close(videoIdx); }) } }); });