angular版聊天室|仿微信界面IM聊天|NG2+Node聊天實例

来源:https://www.cnblogs.com/xiaoyan2017/archive/2019/07/16/11194828.html
-Advertisement-
Play Games

一、項目介紹 運用angular+angular-cli+angular-router+ngrx/store+rxjs+webpack+node+wcPop等技術實現開發的仿微信angular版聊天室angular-chatroom實例項目,實現了下拉刷新、聊天消息右鍵菜單、發送消息、表情(動圖), ...


一、項目介紹

運用angular+angular-cli+angular-router+ngrx/store+rxjs+webpack+node+wcPop等技術實現開發的仿微信angular版聊天室angular-chatroom實例項目,實現了下拉刷新、聊天消息右鍵菜單、發送消息、表情(動圖),圖片、視頻預覽,紅包打賞等功能。

二、技術實現

  • MVVM框架:angular8.0 / @angular/cli
  • 狀態管理:@ngrx/store / rxjs
  • 地址路由:@angular/router
  • 彈窗組件:wcPop
  • 打包工具:webpack 2.0
  • 環境配置:node.js + cnpm
  • 圖片預覽:previewImage
  • 輪播滑動:swiper
{
  "name": "angular-chatroom",
  "contact": "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",
    "tslib": "^1.9.0",
    "zone.js": "~0.9.1"
  },
  "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",
    "typescript": "~3.4.3"
  }
}

◆ App主頁面模板、app-routing路由地址配置

<div class="weChatIM__panel clearfix">
    <div class="we__chatIM-wrapper flexbox flex__direction-column">
        <!-- 頂部 -->
        <header-bar></header-bar>
        
        <!-- 主頁面 -->
        <div class="wcim__container flex1">
            <router-outlet></router-outlet>
        </div>

        <!-- 底部 -->
        <tab-bar></tab-bar>
    </div>
</div>
/*
 *  angular/router路由配置
 */

import { NgModule } from '@angular/core'
import { Routes, RouterModule } from '@angular/router'

// 引入路由驗證
import { Auth } from '../views/auth/auth'

// 引入頁面組件
import { NotFoundComponent } from '../components/404'
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'


export const routes: Routes = [
  {
    path: '', redirectTo: 'index', pathMatch: 'full',
    data: { showHeader: true, showTabBar: true },
  },

  // 登錄、註冊
  {
    path: 'login', component: LoginComponent,
  },
  {
    path: 'register', component: RegisterComponent,
  },

  // 首頁、聯繫人、我
  {
    path: 'index', component: IndexComponent, canActivate: [Auth],
    data: { showHeader: true, showTabBar: true },
  },
  {
    path: 'contact', component: ContactComponent, canActivate: [Auth],
    data: { showHeader: true, showTabBar: true },
  },
  {
    path: 'contact/uinfo', component: UinfoComponent
  },
  {
    path: 'ucenter', component: UcenterComponent, canActivate: [Auth],
    data: { showHeader: false, showTabBar: true },
  },

  // 聊天頁面
  {
    path: 'chat/group-chat', component: GroupChatComponent, canActivate: [Auth]
  },
  {
    path: 'chat/single-chat', component: SingleChatComponent, canActivate: [Auth]
  },
  {
    path: 'chat/group-info', component: GroupInfoComponent, canActivate: [Auth]
  },

  // 404
  {
    path: '**', component: NotFoundComponent,
  },

  // ...
];

@NgModule({
  // imports: [RouterModule.forRoot(routes)],
  imports: [RouterModule.forRoot(routes, { useHash: true })],  //開啟hash模式
  exports: [RouterModule],
  providers: [Auth]
})
export class AppRoutingModule {}

◆ angular + ngrx/store頁面狀態管理

◆ angular登錄、註冊驗證

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, "") == "";
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 什麼是Node? Node.js 是一個基於Chrome V8 引擎的JavaScript運行環境 Node.js使用了一個事件驅動、非阻塞式I/O的模型,使其輕量又高效 事件驅動: 任務執行,發佈者,訂閱者,事件驅動 ( on emit ) 非阻塞: 執行某一個任務的同時也可以執行其他任務 I/O ...
  • 【本文為原創,轉載請註明出處】 技術【HTML+CSS】 佈局【Div】 步驟1 劃分div佈局 步驟2 填充內容 超鏈接+圖片+文本 步驟3 知識點整理 1.清除瀏覽器樣式 https://www.cnblogs.com/Caixingmin/p/11196614.html 2.多個div併排不換 ...
  • 清除瀏覽器預設樣式的原因 一、 某些標簽的預設樣式不符合我們的設計要求。比如說a標簽,預設它是有一條下劃線,並且字體顏色也讓人覺得很難看,所以我們需要清除它預設的樣式,同時根據要求給它重新添加自定義樣式。如圖是a標簽的預設樣式。 二、各瀏覽器預設的樣式各不同,所以會影響到我們的開發,因為在每次開發之 ...
  • 先做個自我介紹,我13年考上一所很爛專科民辦的學校,學的是生物專業,具體的學校名稱我就不說出來獻醜了。13年我就輟學了,我在那樣的學校,一年學費要1萬多,但是根本沒有人學習,我實在看不到希望,我就退學了。退學後我也迷茫,大專都沒有畢業,我真的不知道我能幹什麼,我在糾結著我能做什麼。所以輟學後我一段時 ...
  • 本文主要講述我在做項目中使用裝飾器(decorator)來動態載入koa-router的路由的一個基礎架構。 目前JavaScript 對decorator 是不支持,但是可以用babel 來編譯 既然是koa2結合decorator 使用,首先是要起一個koa2 項目。 環境要求: node >7 ...
  • Layout 佈局 row 佈局組件中的父組件,用於控制子組件。很簡單的一個佈局標簽,主要通過 justify 和 align 控制子元素的對齊方式,使用 render 函數通過傳入的 tag 屬性控制生成的標簽。 在這裡推薦學習下 render 函數和 JSX 的寫法,因為之後比較複雜的組件都是通 ...
  • web前端開發要學的知識內容涉及的會很寬泛,雖然說主要是HTML、CSS和JavaScript這些基礎知識點,但學前端開發除了要學這些基礎知識外,學員還要在這之上進行延伸和深入的去學,而且互聯網時代不斷發展,掌握了這些新技術、新技能,在職場的競爭力必然會翻倍提升。 前端開發 一。零基礎學web前端開 ...
  • 當時遇見這個問題 是醫院手麻系統大批量數據展示,由於是舊項目系統沒有使用到前端的架構 只能使用JQ,JS, css完成 也謝謝給予我支持的同行們 固定首行數據: 採用函數的方式進行 JQ /** * 功能:固定表頭 * 參數 viewid 表格的id * scrollid 滾動條所在容器的id * ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...