博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vue聊天室|h5+vue仿微信聊天界面|vue仿微信
阅读量:6693 次
发布时间:2019-06-25

本文共 10888 字,大约阅读时间需要 36 分钟。

一、项目简介

基于Vue2.0+Vuex+vue-router+webpack2.0+es6+vuePhotoPreview+wcPop等技术架构开发的仿微信界面聊天室——vueChatRoom,实现了微信聊天下拉刷新、发送消息、表情(动图),图片、视频预览,打赏、红包等功能。

二、技术栈

  • MVVM框架:Vue.js 2.0
  • 状态管理:Vuex
  • 页面路由:Vue-router
  • 弹窗插件:wcPop
  • 打包工具:webpack 2.0
  • 环境配置:node.js + cnpm
  • 图片插件:vue-photo-preview

◆ vue-router页面地址路由、vue钩子拦截登录状态:

/* *  页面地址路由js */ import Vue from 'vue'import _router from 'vue-router'import store from '../vuex'Vue.use(_router) //应用路由const router = new _router({    routes: [        // 登录、注册        {            path: '/login',            component: resolve => require(['../views/auth/login'], resolve),        },        {            path: '/register',            component: resolve => require(['../views/auth/register'], resolve),        },        // 首页、通讯录、我        {            path: '/',            component: resolve => require(['../views/index'], resolve),            meta: { showHeader: true, showTabBar: true, requireAuth: true }        },        {            path: '/contact',            component: resolve => require(['../views/contact'], resolve),            meta: { showHeader: true, showTabBar: true, requireAuth: true },        },        {            path: '/contact/uinfo',            component: resolve => require(['../views/contact/uinfo'], resolve),        },        {            path: '/ucenter',            component: resolve => require(['../views/ucenter'], resolve),            meta: { showHeader: true, showTabBar: true, requireAuth: true }        },        // 聊天页面        {            path: '/chat/group-chat',            component: resolve => require(['../views/chat/group-chat'], resolve),            meta: { requireAuth: true }        },        {            path: '/chat/single-chat',            component: resolve => require(['../views/chat/single-chat'], resolve),            meta: { requireAuth: true }        },        {            path: '/chat/group-info',            component: resolve => require(['../views/chat/group-info'], resolve),            meta: { requireAuth: true }        }        // ...    ]})// 注册全局钩子拦截登录状态const that = thisrouter.beforeEach((to, from, next) => {    const token = store.state.token    // 判断该路由地址是否需要登录权限    if(to.meta.requireAuth){        // 通过vuex state获取当前token是否存在        if(token){            next()        }else{            // console.log('还未登录授权!')            next()            wcPop({                content: '还未登录授权!', style: 'background:#e03b30;color:#fff;', time: 2,                end: function(){                    next({ path: '/login' })                }            });        }    }else{        next()    }})export default router

◆ 引入第三方组件库、插件:

// >>>引入jsimport $ from 'jquery'import fontsize from './assets/js/fontsize'// >>>引入弹窗插件import wcPop from './assets/js/wcPop/wcPop'import './assets/js/wcPop/skin/wcPop.css'// >>>引入饿了么移动端vue组件库import MintUI, { Loadmore } from 'mint-ui'import 'mint-ui/lib/style.css'Vue.component(Loadmore.name, Loadmore)Vue.use(MintUI)// >>>引入图片预览插件import photoPreview from 'vue-photo-preview'import 'vue-photo-preview/dist/skin.css'Vue.use(photoPreview, {  loop: false,  fullscreenEl: false, //是否全屏  arrowEl: false, //左右按钮})// >>>引入地址路由import router from './router'import store from './vuex'

◆ 登录、注册模块验证:

import { setToken, checkTel } from '../../utils/filters'export default {    data () {        return {            formObj: {},            vcodeText: '获取验证码',            tel: '',            disabled: false,            time: 0,        }    },    methods: {        handleSubmit(){            // console.log(this.formObj)            // console.log(JSON.stringify(this.formObj))            var that = this;            if(!this.formObj.tel){                wcPop({ content: '手机号不能为空!', style: 'background:#e03b30;color:#fff;', time: 2 });            }else if(!checkTel(this.formObj.tel)){                wcPop({ content: '手机号格式不正确!', style: 'background:#e03b30;color:#fff;', time: 2 });            }else if(!this.formObj.pwd){                wcPop({ content: '密码不能为空!', style: 'background:#e03b30;color:#fff;', time: 2 });            }else if(!this.formObj.vcode){                wcPop({ content: '验证码不能为空!', style: 'background:#e03b30;color:#fff;', time: 2 });            }else{                this.$store.commit('SET_TOKEN', setToken());                this.$store.commit('SET_USER', this.formObj.tel);                wcPop({                    content: '注册成功!', style: 'background:#41b883;color:#fff;', time: 2,                    end: function(){                        that.$router.push('/');                    }                });            }        },        // 60s倒计时        handleVcode(){            if(!this.formObj.tel){                wcPop({ content: '手机号不能为空!', style: 'background:#e03b30;color:#fff;', time: 2 });            }else if(!checkTel(this.formObj.tel)){                wcPop({ content: '手机号格式不正确!', style: 'background:#e03b30;color:#fff;', time: 2 });            }else{                this.time = 60;                this.disabled = true;                this.countDown();            }        },        countDown(){            if(this.time > 0){                this.time--;                this.vcodeText = '获取验证码('+this.time+')';                setTimeout(this.countDown, 1000);            }else{                this.time = 0;                this.vcodeText = '获取验证码';                this.disabled = false;            }        }    }}

◆ 聊天页面模块:

// >>> 【表情、动图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: '
', content: '
', 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); }) } });});// >>> 【编辑器+表情处理模块】------------------------------------------// ...处理编辑器信息function surrounds() { setTimeout(function () { //chrome var sel = window.getSelection(); var anchorNode = sel.anchorNode; if (!anchorNode) return; if (sel.anchorNode === $(".J__wcEditor")[0] || (sel.anchorNode.nodeType === 3 && sel.anchorNode.parentNode === $(".J__wcEditor")[0])) { var range = sel.getRangeAt(0); var p = document.createElement("p"); range.surroundContents(p); range.selectNodeContents(p); range.insertNode(document.createElement("br")); //chrome sel.collapse(p, 0); (function clearBr() { var elems = [].slice.call($(".J__wcEditor")[0].children); for (var i = 0, len = elems.length; i < len; i++) { var el = elems[i]; if (el.tagName.toLowerCase() == "br") { $(".J__wcEditor")[0].removeChild(el); } } elems.length = 0; })(); } }, 10);}// 定义最后光标位置var _lastRange = null, _sel = window.getSelection && window.getSelection();var _rng = { getRange: function () { if (_sel && _sel.rangeCount > 0) { return _sel.getRangeAt(0); } }, addRange: function () { if (_lastRange) { _sel.removeAllRanges(); _sel.addRange(_lastRange); } }}// 格式化编辑器包含标签$("body").on("click", ".J__wcEditor", function(){ $(".wc__choose-panel").hide();});$("body").on("focus", ".J__wcEditor", function(){ surrounds();});$("body").on("input", ".J__wcEditor", function(){ surrounds();});// 点击表情$("body").on("click", "#J__swiperEmotion .face-list span img", function () { var that = $(this), range; if (that.hasClass("face")) { //小表情 var img = that[0].cloneNode(true); if (!$(".J__wcEditor")[0].childNodes.length) { $(".J__wcEditor")[0].focus(); } $(".J__wcEditor")[0].blur(); //输入表情时禁止输入法 setTimeout(function () { if (document.selection && document.selection.createRange) { document.selection.createRange().pasteHTML(img); } else if (window.getSelection && window.getSelection().getRangeAt) { range = _rng.getRange(); range.insertNode(img); range.collapse(false); _lastRange = range; //记录当前光标位置 (否则光标会跑到表情前面) _rng.addRange(); } }, 10); } else if (that.hasClass("del")) { //删除 // _editor.focus(); $(".J__wcEditor")[0].blur(); //输入表情时禁止输入法 setTimeout(function () { range = _rng.getRange(); range.collapse(false); document.execCommand("delete"); _lastRange = range; _rng.addRange(); }, 10); } else if (that.hasClass("lg-face")) { //大表情 var _img = that.parent().html(); var _tpl = [ '
  • \
    \

    王梅(Fine)

    \
    '+ _img + '
    \
    \ \
  • ' ].join(""); $("#J__chatMsgList").append(_tpl); wchat_ToBottom(); }});

     

    转载于:https://www.cnblogs.com/xiaoyan2017/p/10657781.html

    你可能感兴趣的文章
    ASCII表
    查看>>
    idea之debug
    查看>>
    什么是真正的流程管理?流程管理的是与不是。
    查看>>
    SEO实践:SEO友好的URL结构
    查看>>
    洛谷P1613 跑路
    查看>>
    python各种模块,迭代器,生成器
    查看>>
    微信小程序 watch监听数据变化 类似vue中的watch
    查看>>
    u检验、t检验、F检验、X2检验 (转)
    查看>>
    不可不知的Python模块: collections
    查看>>
    PAT 1066. Root of AVL Tree (25)
    查看>>
    hdu1052
    查看>>
    服务器端推送技术
    查看>>
    python开发工具
    查看>>
    Home Assistant系列 -- 自动语音播报天气
    查看>>
    Hyberledger-Fabric 1.00 RPC学习(1)
    查看>>
    SDNU 1450.报时助手
    查看>>
    BZOJ 4144 Dijkstra+Kruskal+倍增LCA
    查看>>
    阻塞与非阻塞,同步与异步
    查看>>
    HTML段落自动换行的样式设置
    查看>>
    Android实现左右滑动指引效果
    查看>>