One was developed a long time ago using HTML5 technology
The web version imitates wechat, Micro-blog chatLater, I thought of using VUE technology to develop a version, but due to various things, I have not been able to settle. Recently I had some spare time and developed one using VUE
VueWechat chat room IMThe project. Based on the development of Vue2.5.6+Vuex+ VUE-Router + VUE-Gemini – Scrollbar + Swiper +elementUI and other technologies, it realizes the sending of messages, expressions (GIF), pictures and video preview, and can directly paste the fake wechat right menu and web screenshot to the editing box to send.


Vue technology selection

  • MVVM framework: Vue2.5.6
  • Status management: Vuex
  • Page routing: vue-router
  • Iconfont: Alibaba font icon library
  • Custom scrollbar: vue-gemini-scrollbar
  • Popover component: Element-UI
  • Environment configuration: Node.js + CNPM + webpack
  • Map of Amap: Vue-AMap
  • Image preview: Vue-photo-preview

Project Preview



























Home page app.vue template

<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"> <! -- // Top button (Max, min, close) --> <win-bar></win-bar> <! -- // Sidebar --> <side-bar></side-bar> <keep-alive> <router-view class="flex1 flexbox"></router-view>          </keep-alive>
        </div>      </div>    </div>  </div></template>Copy the code

Public module plug-ins introduced

/ * introduced in public and global components configuration Q: 282310962 https://www.cnblogs.com/xiaoyan2017 * / / / introduction of the sidebar and contact the import winBar the from'./components/winbar'import sideBar from './components/sidebar'import recordList from './components/recordList'import contactList from './components/contact'// Import jqueryImport $from'jquery'// Introduce wcPop plugin import wcPop from'./assets/js/wcPop/wcPop'import './assets/js/wcPop/skin/wcPop.css'// Import elementUI from PC UI library'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.component('win-bar', winBar)    Vue.component('side-bar', sideBar)    Vue.component('record-list', recordList)    Vue.component('contact-list'Use (elementUI) vue. use(photoPreview, {loop:false,        fullscreenEl: true, // Full screen arrowEl:true, // left and right buttons}); Vue.use(geminiScrollbar) Vue.use(infiniteLoading) Vue.use(vueAMap) vueAMap.initAMapApiLoader({ key:"e1dedc6bdd765d46693986ff7ff969f4",        plugin: [            "AMap.Autocomplete"// Enter the prompt plug-in"AMap.PlaceSearch"//POI search plugin"AMap.Scale", // Lower right thumbnail plug-in scale"AMap.OverView"// Map Hawk-eye plugin"AMap.ToolBar"// Map toolbar"AMap.MapType"// Class switch control, realize the default layer and satellite image, implementation of traffic layer switch control"AMap.PolyEditor"// Edit polyline, edge shape"AMap.CircleEditor"// Circular editor plugin"AMap.Geolocation"// location control, used to get and display the longitude and latitude location of the user host], uiVersion:"1.0"    });
}
export default installCopy the code

Vue screenshot text box paste send

// document.getelementByid ('J__wcEditor').addEventListener('paste'.function(e){ var cbd = e.clipboardData; var ua = window.navigator.userAgent; // There is no dataif(! (e.clipboardData && e.clipboardData.items)) {return; } // the following copy Finder Bug hacks are removed for Chrome49 on Macif(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 = [
                    '
  • + _img + '" preview="1" />\ \ \ ' ].join(""); $("#J__chatMsgList").append(_tpl); setTimeout(() => { $("#J__geminiScrollbar .gm-scroll-view").animate({ scrollTop: $("#J__chatMsgList").height() }, 0); $(".fixGeminiscrollHeight").show(); setTimeout(() => { $(".fixGeminiscrollHeight").hide(); }, 300); }, 17); }}}});Copy the code

    Emoticons swiper processing and video playback

    / / > > > 【 expression, dynamic figure swiper switching module 】 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 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(The '#' + _tmpl, {
            // loop: true,
            // autoplay: true, // pagination: {el:'.pagination-emotion', clickable: true,}}); } // Emoticons switch $("body").on("click"."#J__emotionFootTab ul li.swiperTmpl".function() {// Delete 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; }); // Exit full screen _video.adDeventListener ("x5videoexitfullscreen".function(){ wcPop.close(videoIdx); }}})); });Copy the code