专栏首页h5angular聊天IM实例|仿微信angular版|NG2案例
原创

angular聊天IM实例|仿微信angular版|NG2案例

angular8.0仿微信聊天室|angular即时聊天IM系统|仿微信界面angular

运用angular+@angular/cli+@angular/router+@ngrx/store等技术实现开发的移动端聊天室angular版,实现了下拉刷新、长按右键菜单、发送消息、表情(动图),图片、视频预览,打赏、红包等功能。

react版聊天室:https://blog.csdn.net/yanxinyun1990/article/details/94143575

技术架构:

  • MVVM框架:angular8 + @angular/cli + @angular/router
  • 状态管理:@ngrx/store + rxjs
  • 地址路由:@angular/router
  • 弹窗组件:wcPop
  • 打包工具:webpack 2.0
  • 环境配置:node.js + cnpm
  • 图片预览:previewImage
  • 轮播滑动:swiper
{
  "name": "angular-chatroom",
  "aboutMe": "QQ:282310962   wx:xy190310",

  "dependencies": {
    "@angular/animations": "~8.0.1",
    "@angular/common": "~8.0.1",
    "@angular/compiler": "~8.0.1",
    "@angular/core": "~8.0.1",
    "@angular/forms": "~8.0.1",
    "@angular/platform-browser": "~8.0.1",
    "@angular/platform-browser-dynamic": "~8.0.1",
    "@angular/router": "~8.0.1",
    "rxjs": "~6.4.0",
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.800.0",
    "@angular/cli": "~8.0.3",
    "@angular/compiler-cli": "~8.0.1",
    "@angular/language-service": "~8.0.1",
    "@ngrx/store": "^8.0.1",
    "@types/jasmine": "~3.3.8",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "~8.9.4",
    "@types/swiper": "^4.4.3",
    "codelyzer": "^5.0.0",
    "jasmine-core": "~3.4.0",
    "jasmine-spec-reporter": "~4.2.1",
    "jquery": "^2.2.3",
    "karma": "~4.1.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.0",
    "swiper": "^4.5.0",
  }
}
/*
 *  angular主模块配置
 */ 

import { BrowserModule } from '@angular/platform-browser'
import { NgModule } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { AppRoutingModule } from './app-routing.module'

// 引入状态管理
import { StoreModule } from '@ngrx/store'
import { reducer } from '../ngrx'

// 载入公共组件(component)
import { HeaderComponent } from '../components/header'
import { TabBarComponent } from '../components/tabbar'
import { XtnScroll } from '../components/xtnScroll/Scroll'
import { NotFoundComponent } from '../components/404'
// 载入页面组件(view)
import { AppComponent } from './app.component'
import { LoginComponent } from '../views/auth/login'
import { RegisterComponent } from '../views/auth/register'
import { IndexComponent } from '../views/index'
import { ContactComponent } from '../views/contact'
import { UinfoComponent } from '../views/contact/uinfo'
import { UcenterComponent } from '../views/ucenter'
import { GroupChatComponent } from '../views/chat/group-chat'
import { GroupInfoComponent } from '../views/chat/group-info'
import { SingleChatComponent } from '../views/chat/single-chat'

@NgModule({
  declarations: [
    // 公共组件
    HeaderComponent,
    TabBarComponent,
    XtnScroll,
    NotFoundComponent,

    // 页面组件
    AppComponent,
    LoginComponent,
    RegisterComponent,
    IndexComponent,
    ContactComponent,
    UinfoComponent,
    UcenterComponent,
    GroupChatComponent,
    GroupInfoComponent,
    SingleChatComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,

    StoreModule.forRoot(reducer)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
/*
 *  angular路由守卫(验证token)
 */

import { Router, CanActivate } from '@angular/router'

declare var wcPop: any;

export class Auth implements CanActivate{
    constructor(private router: Router){}

    canActivate(){
        let that = this
        // 验证token
        const token: boolean = window.sessionStorage.getItem('token') ? true : false

        if(!token){
            // 未登录授权
            /*
            wcPop({
                content: '还未登录授权!', anim: 'shake', style: 'background:#e03b30;color:#fff;', time: 2,
                end: function () {
                    that.router.navigate(['/login']);
                }
            });
            */
            that.router.navigate(['/login']);
        }
        return token
    }
}
export class LoginComponent implements OnInit {
    private formField = {
        tel: '',
        pwd: ''
    }
    
    private auth: any
    constructor(
        private router: Router,
        private store: Store<{}>
    ) {
        let that = this
        this.store.select('auth').subscribe(v => {
            console.log(v)
            that.auth = v;
        })
    }

    ngOnInit(): void {
        if(this.auth.token){
            this.router.navigate(['/index'])
        }
    }

    handleSubmit(){
        let that = this

        if(!this.formField.tel){
            wcPop({ content: '手机号不能为空!', style: 'background:#eb5a5c;color:#fff;', time: 2 });
        }else if(!checkTel(this.formField.tel)){
            wcPop({ content: '手机号格式不正确!', style: 'background:#eb5a5c;color:#fff;', time: 2 });
        }else if(!this.formField.pwd){
            wcPop({ content: '密码不能为空!', style: 'background:#eb5a5c;color:#fff;', time: 2 });
        }else{
            this.store.dispatch(new actions.setToken(getToken(64)))
            this.store.dispatch(new actions.setUser(this.formField.tel))

            wcPop({
                content: '登录成功,跳转中...', style: 'background:#378fe7;color:#fff;', time: 2, shadeClose: false,
                end: function () {
                    that.router.navigate(['/index'])
                }
            });
        }
    }
}
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);
        }
    }
}

// 消息处理
function isEmpty() {
    // var html = $editor.html();
    var html = $(".J__wcEditor").html();
    html = html.replace(/<br[\s\/]{0,2}>/ig, "\r\n");
    html = html.replace(/<[^img].*?>/ig, "");
    html = html.replace(/&nbsp;/ig, "");
    return html.replace(/\r\n|\n|\r/, "").replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, "") == "";
}

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • uniapp仿抖音App界面|uni-app小视频

    Uni-liveshow直播室是一个基于vue+Nvue+uniapp技术开发的集仿制抖音小视频/App聊天/直播功能混合项目。可实现类似抖音上下滑动切换视频播...

    andy2018
  • Vue.js|Nuxt仿制探探堆叠滑动|vue仿Tinder卡片效果

    点击右上角筛选按钮,在侧边会出现弹窗。里面的范围滑块、switch开关、Rate评分等组件则是使用Vant组件库。

    andy2018
  • 小程序聊天室|聊天对话小程序|仿微信界面

    基于微信小程序开发的聊天室实战案例。很早之前就有开发过一个h5版聊天室,最近又开发了个小程序版聊天室,功能效果非常接近微信聊天,实现了消息、表情发送,小程序表情...

    andy2018
  • Angular2 :从 beta 到 release4.0 版本升级总结

    Angular是用于构建移动应用和桌面Web应用的开发平台.,本文记录Angular2框架升级的一些总结、遇到的问题以及解决办法。

    王贝珊
  • webpack+es6+angular1.x项目构建

    版权声明:本文为博主原创文章,未经博主允许不得转载。 ...

    j_bleach
  • Webpack 打包优化之体积篇

    谈及如今欣欣向荣的前端圈,不仅有各类框架百花齐放,如Vue, React, Angular等等,就打包工具而言,发展也是如火如荼,百家争鸣;从早期的王者Brow...

    晚晴幽草轩轩主
  • Fortinet FortiClient的Windows系统提权登录漏洞(附PoC)

    近期,Fortinet(飞塔)主机终端安全防护软件FortiClient,被曝在Windows登录界面处存在权限提升漏洞(CVE-2017-7344 ),可被攻...

    FB客服
  • 投融资汇总|本周(12.1-12.7),国内AI领域“准独角兽”添新人

    本周硬科技领域投融资事件一共45起,人工智能领域发生24起融资事件和1起收购事件,占比56%;生物医药领域发生10起融资事件和1起收购事件,占比25%;区块链领...

    镁客网
  • 什么样的公司值得我们托付一辈子?

    过年了,先祝各位程序员新年快乐。想必年后肯定有一批人要换工作,到底什么样的环境好呢。看一下年前程序员对公司的对比或许对你有所帮助。 1、谁是2B 这是一致认可的...

    程序员互动联盟
  • 2020,金融机构们就搞的出“中台”吗?

    2019年,也许算是我国金融界的“中台元年”,“中台”这个概念现在是又时髦又“潮”,数据中台、业务中台、中台战略、中台部门…  各种云山雾罩的,层出不穷。反正每...

    凡泰极客

扫码关注云+社区

领取腾讯云代金券