经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » HTML5 » 查看文章
angular版聊天室|仿微信界面IM聊天|NG2+Node聊天实例
来源:cnblogs  作者:xiaoyan2017  时间:2019/7/17 10:51:10  对本文有异议

一、项目介绍

运用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
  1. {
  2. "name": "angular-chatroom",
  3. "contact": "QQ:282310962 、 wx:xy190310",
  4. "dependencies": {
  5. "@angular/animations": "~8.0.1",
  6. "@angular/common": "~8.0.1",
  7. "@angular/compiler": "~8.0.1",
  8. "@angular/core": "~8.0.1",
  9. "@angular/forms": "~8.0.1",
  10. "@angular/platform-browser": "~8.0.1",
  11. "@angular/platform-browser-dynamic": "~8.0.1",
  12. "@angular/router": "~8.0.1",
  13. "rxjs": "~6.4.0",
  14. "tslib": "^1.9.0",
  15. "zone.js": "~0.9.1"
  16. },
  17. "devDependencies": {
  18. "@angular-devkit/build-angular": "~0.800.0",
  19. "@angular/cli": "~8.0.3",
  20. "@angular/compiler-cli": "~8.0.1",
  21. "@angular/language-service": "~8.0.1",
  22. "@ngrx/store": "^8.0.1",
  23. "@types/jasmine": "~3.3.8",
  24. "@types/jasminewd2": "~2.0.3",
  25. "@types/node": "~8.9.4",
  26. "@types/swiper": "^4.4.3",
  27. "codelyzer": "^5.0.0",
  28. "jasmine-core": "~3.4.0",
  29. "jasmine-spec-reporter": "~4.2.1",
  30. "jquery": "^2.2.3",
  31. "karma": "~4.1.0",
  32. "karma-chrome-launcher": "~2.2.0",
  33. "karma-coverage-istanbul-reporter": "~2.0.1",
  34. "karma-jasmine": "~2.0.1",
  35. "karma-jasmine-html-reporter": "^1.4.0",
  36. "swiper": "^4.5.0",
  37. "typescript": "~3.4.3"
  38. }
  39. }

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

  1. <div class="weChatIM__panel clearfix">
  2. <div class="we__chatIM-wrapper flexbox flex__direction-column">
  3. <!-- 顶部 -->
  4. <header-bar></header-bar>
  5. <!-- 主页面 -->
  6. <div class="wcim__container flex1">
  7. <router-outlet></router-outlet>
  8. </div>
  9.  
  10. <!-- 底部 -->
  11. <tab-bar></tab-bar>
  12. </div>
  13. </div>
  1. /*
  2. * angular/router路由配置
  3. */
  4. import { NgModule } from '@angular/core'
  5. import { Routes, RouterModule } from '@angular/router'
  6.  
  7. // 引入路由验证
  8. import { Auth } from '../views/auth/auth'
  9.  
  10. // 引入页面组件
  11. import { NotFoundComponent } from '../components/404'
  12. import { LoginComponent } from '../views/auth/login'
  13. import { RegisterComponent } from '../views/auth/register'
  14. import { IndexComponent } from '../views/index'
  15. import { ContactComponent } from '../views/contact'
  16. import { UinfoComponent } from '../views/contact/uinfo'
  17. import { UcenterComponent } from '../views/ucenter'
  18. import { GroupChatComponent } from '../views/chat/group-chat'
  19. import { GroupInfoComponent } from '../views/chat/group-info'
  20. import { SingleChatComponent } from '../views/chat/single-chat'
  21. export const routes: Routes = [
  22. {
  23. path: '', redirectTo: 'index', pathMatch: 'full',
  24. data: { showHeader: true, showTabBar: true },
  25. },
  26. // 登录、注册
  27. {
  28. path: 'login', component: LoginComponent,
  29. },
  30. {
  31. path: 'register', component: RegisterComponent,
  32. },
  33. // 首页、联系人、我
  34. {
  35. path: 'index', component: IndexComponent, canActivate: [Auth],
  36. data: { showHeader: true, showTabBar: true },
  37. },
  38. {
  39. path: 'contact', component: ContactComponent, canActivate: [Auth],
  40. data: { showHeader: true, showTabBar: true },
  41. },
  42. {
  43. path: 'contact/uinfo', component: UinfoComponent
  44. },
  45. {
  46. path: 'ucenter', component: UcenterComponent, canActivate: [Auth],
  47. data: { showHeader: false, showTabBar: true },
  48. },
  49. // 聊天页面
  50. {
  51. path: 'chat/group-chat', component: GroupChatComponent, canActivate: [Auth]
  52. },
  53. {
  54. path: 'chat/single-chat', component: SingleChatComponent, canActivate: [Auth]
  55. },
  56. {
  57. path: 'chat/group-info', component: GroupInfoComponent, canActivate: [Auth]
  58. },
  59. // 404
  60. {
  61. path: '**', component: NotFoundComponent,
  62. },
  63. // ...
  64. ];
  65. @NgModule({
  66. // imports: [RouterModule.forRoot(routes)],
  67. imports: [RouterModule.forRoot(routes, { useHash: true })], //开启hash模式
  68. exports: [RouterModule],
  69. providers: [Auth]
  70. })
  71. export class AppRoutingModule {}

◆ angular + ngrx/store页面状态管理

◆ angular登录、注册验证

  1. export class LoginComponent implements OnInit {
  2. private formField = {
  3. tel: '',
  4. pwd: ''
  5. }
  6. private auth: any
  7. constructor(
  8. private router: Router,
  9. private store: Store<{}>
  10. ) {
  11. let that = this
  12. this.store.select('auth').subscribe(v => {
  13. console.log(v)
  14. that.auth = v;
  15. })
  16. }
  17. ngOnInit(): void {
  18. if(this.auth.token){
  19. this.router.navigate(['/index'])
  20. }
  21. }
  22. handleSubmit(){
  23. let that = this
  24.  
  25. if(!this.formField.tel){
  26. wcPop({ content: '手机号不能为空!', style: 'background:#eb5a5c;color:#fff;', time: 2 });
  27. }else if(!checkTel(this.formField.tel)){
  28. wcPop({ content: '手机号格式不正确!', style: 'background:#eb5a5c;color:#fff;', time: 2 });
  29. }else if(!this.formField.pwd){
  30. wcPop({ content: '密码不能为空!', style: 'background:#eb5a5c;color:#fff;', time: 2 });
  31. }else{
  32. this.store.dispatch(new actions.setToken(getToken(64)))
  33. this.store.dispatch(new actions.setUser(this.formField.tel))
  34. wcPop({
  35. content: '登录成功,跳转中...', style: 'background:#378fe7;color:#fff;', time: 2, shadeClose: false,
  36. end: function () {
  37. that.router.navigate(['/index'])
  38. }
  39. });
  40. }
  41. }
  42. }

◆ 编辑器核心消息处理

  1. function surrounds() {
  2. setTimeout(function () { //chrome
  3. var sel = window.getSelection();
  4. var anchorNode = sel.anchorNode;
  5. if (!anchorNode) return;
  6. if (sel.anchorNode === $(".J__wcEditor")[0] ||
  7. (sel.anchorNode.nodeType === 3 && sel.anchorNode.parentNode === $(".J__wcEditor")[0])) {
  8. var range = sel.getRangeAt(0);
  9. var p = document.createElement("p");
  10. range.surroundContents(p);
  11. range.selectNodeContents(p);
  12. range.insertNode(document.createElement("br")); //chrome
  13. sel.collapse(p, 0);
  14. (function clearBr() {
  15. var elems = [].slice.call($(".J__wcEditor")[0].children);
  16. for (var i = 0, len = elems.length; i < len; i++) {
  17. var el = elems[i];
  18. if (el.tagName.toLowerCase() == "br") {
  19. $(".J__wcEditor")[0].removeChild(el);
  20. }
  21. }
  22. elems.length = 0;
  23. })();
  24. }
  25. }, 10);
  26. }
  27. // 定义最后光标位置
  28. var _lastRange = null, _sel = window.getSelection && window.getSelection();
  29. var _rng = {
  30. getRange: function () {
  31. if (_sel && _sel.rangeCount > 0) {
  32. return _sel.getRangeAt(0);
  33. }
  34. },
  35. addRange: function () {
  36. if (_lastRange) {
  37. _sel.removeAllRanges();
  38. _sel.addRange(_lastRange);
  39. }
  40. }
  41. }
  42. // 消息处理
  43. function isEmpty() {
  44. // var html = $editor.html();
  45. var html = $(".J__wcEditor").html();
  46. html = html.replace(/<br[\s\/]{0,2}>/ig, "\r\n");
  47. html = html.replace(/<[^img].*?>/ig, "");
  48. html = html.replace(/&nbsp;/ig, "");
  49. return html.replace(/\r\n|\n|\r/, "").replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, "") == "";
  50. }

 

原文链接:http://www.cnblogs.com/xiaoyan2017/p/11194828.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号