一、项目介绍

基于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);
            })
        }
    });
});

 

版权声明:本文为xiaoyan2017原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xiaoyan2017/p/10793728.html