很早之前就有使用html5技術開發過一個web版仿微信、微博聊天,後來想著用vue技術開發一版,後面由於各種事情,一直沒能落定。最近有些空閒就使用vue開發了一個vueWechat聊天室IM專案。
基於Vue2.5.6+Vuex+vue-router+vue-gemini-scrollbar+swiper+elementUI等技術開發,實現了傳送訊息、表情(動圖),圖片、視訊預覽,仿微信右鍵選單、網頁截圖可直接貼上至編輯框傳送。
vue技術選型
- MVVM框架:Vue2.5.6
- 狀態管理:Vuex
- 頁面路由:Vue-router
- iconfont圖示:阿里巴巴字型圖示庫
- 自定義滾動條:vue-gemini-scrollbar
- 彈窗元件:element-ui(餓了麼前端UI庫)
- 環境配置:node.js + cnpm + webpack
- 高德地圖:vue-amap
- 圖片預覽:vue-photo-preview
專案預覽圖
主頁面app.vue模板
<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>複製程式碼
公共模組外掛引入
/* 引入公共及全域性元件配置 Q:282310962 https://www.cnblogs.com/xiaoyan2017*/
// 引入側邊欄及聯絡人import winBar from './components/winbar'import sideBar from './components/sidebar'import recordList from './components/recordList'import contactList from './components/contact'
// 引入jqueryimport $ 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複製程式碼
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處理及視訊播放
// >>> 【表情、動圖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);
})
}
});
});
複製程式碼