angular版聊天室|仿微信界面IM聊天|NG2+Node聊天实例
发布时间:2020-12-17 17:08:38 所属栏目:安全 来源:网络整理
导读:一、项目介绍 运用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实例项目,实现了下拉刷新、聊天消息右键菜单、发送消息、表情(动图),图片、视频预览,红包打赏等功能。 二、技术实现
{ "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],{ path: ‘contact‘,component: ContactComponent,{ path: ‘contact/uinfo‘,component: UinfoComponent },{ path: ‘ucenter‘,component: UcenterComponent,data: { showHeader: false,// 聊天页面 { path: ‘chat/group-chat‘,component: GroupChatComponent,canActivate: [Auth] },{ path: ‘chat/single-chat‘,component: SingleChatComponent,{ path: ‘chat/group-info‘,component: GroupInfoComponent,// 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: ‘手机号格式不正确!‘,time: 2 }); }else if(!this.formField.pwd){ wcPop({ content: ‘密码不能为空!‘,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,"rn"); html = html.replace(/<[^img].*?>/ig,""); html = html.replace(/ /ig,""); return html.replace(/rn|n|r/,"").replace(/(?:^[ tnr]+)|(?:[ tnr]+$)/g,"") == ""; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |