前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >electron制作聊天界面(仿制qq)

electron制作聊天界面(仿制qq)

作者头像
李昊天
发布于 2019-05-26 00:43:14
发布于 2019-05-26 00:43:14
2.5K00
代码可运行
举报
运行总次数:0
代码可运行

效果图:

样式使用scss和flex布局

这也是制作IM系统的最后一个界面了! 在制作之前参考了qq和千牛

需要注意的点

qq将滚动条美化了 而且在无操作的情况下是不会显示的

滚动条美化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
::-webkit-scrollbar { /*滚动条整体样式*/
    width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
    height: 1px;
}

::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
    border-radius: 10px;
    -webkit-box-shadow: inset 0 0 5px rgba(228, 57, 60, 0.2);
    background: rgba(20, 20, 50, 0.6);
    position: absolute;
}

::-webkit-scrollbar-track { /*滚动条里面轨道*/
    -webkit-box-shadow: inset 0 0 5px rgba(228, 57, 60, 0.2);
    border-radius: 10px;
    background: #EDEDED;
    position: absolute;
}

滚动条根据时机显示

其实这个也很简单 用的mouseentermouseleave事件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<div
    :style="{overflowY:messageScroll? 'auto' : 'hidden',paddingRight: messageScroll ? '0': '5px' }"
    @mouseenter="showMessageScrolls" 
    @mouseleave="hideMessageScrolls">
</div>

# script
 showMessageScrolls(){
     this.messageScroll = true;
},
hideMessageScrolls(){
    this.messageScroll = false;
},

这里解释一下为什么有一个paddingRight 因为我们的滚动条是5px 如果不加 在滚动条显示的时候页面会抖动

简单写法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    @mouseenter="messageScroll = true" 
    @mouseleave="messageScroll = false"

页面滚动

页面打开时消息列表滚动到底部

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
this.$nextTick(function () {
                this.$refs.msgBox.scrollTop = this.$refs.msgBox.scrollHeight
})

消息发送滚动到底部

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 this.$refs.msgBox.scrollTop = this.$refs.msgBox.scrollHeight;

内容编辑

没有使用表单元素 直接使用的 contenteditable 因为contenteditable 没法用双向数据绑定 不过 可以用数据侦听器 有很多办法 但是有很简单的 使用input事件就行了

代码

页面代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
    <div class="friend_window">
        <header>
            <div class="nickname">Lee</div>
            <div class="buttons">
                <i class="iconfont">&#xe669;</i>
                <i class="iconfont">&#xe601;</i>
            </div>
        </header>
        <aside>
            <nav>
                <ul>
                    <li >
                        <div class="avatar"><img src="@/assets/img/1.jpg" alt=""></div>
                        <div class="msg_box">
                            <div class="nickname">李昊天-</div>
                            <div class="messages">最近还好吗</div>
                        </div>
                        <div class="push_right">
                            <div class="time">12:50</div>
                            <div class="number">1</div>
                        </div>
                    </li>
                    <li >
                        <div class="avatar"><img src="@/assets/img/2.jpg" alt=""></div>
                        <div class="msg_box">
                            <div class="nickname">李昊天-</div>
                            <div class="messages">最近还好吗</div>
                        </div>
                        <div class="push_right">
                            <div class="time">12:50</div>
                            <div class="number">1</div>
                        </div>
                    </li>
                    <li >
                        <div class="avatar"><img src="@/assets/img/3.jpg" alt=""></div>
                        <div class="msg_box">
                            <div class="nickname">李昊天-</div>
                            <div class="messages">最近还好吗</div>
                        </div>
                        <div class="push_right">
                            <div class="time">12:50</div>
                            <div class="number">1</div>
                        </div>
                    </li>
                    <li >
                        <div class="avatar"><img src="@/assets/img/4.jpg" alt=""></div>
                        <div class="msg_box">
                            <div class="nickname">李昊天-</div>
                            <div class="messages">最近还好吗</div>
                        </div>
                        <div class="push_right">
                            <div class="time">12:50</div>
                            <div class="number">1</div>
                        </div>
                    </li>
                    <li class="active">
                        <div class="avatar"><img src="@/assets/img/5.jpg" alt=""></div>
                        <div class="msg_box">
                            <div class="nickname">李昊天1-</div>
                            <div class="messages">最近还好吗</div>
                        </div>
                        <div class="push_right">
                            <div class="time">12:50</div>
                            <div class="number">1</div>
                        </div>
                    </li>
                    <li >
                        <div class="avatar"><img src="@/assets/img/6.jpg" alt=""></div>
                        <div class="msg_box">
                            <div class="nickname">李昊天-</div>
                            <div class="messages">最近还好吗</div>
                        </div>
                        <div class="push_right">
                            <div class="time">12:50</div>
                            <div class="number">1</div>
                        </div>
                    </li>
                    <li >
                        <div class="avatar"><img src="@/assets/img/7.jpg" alt=""></div>
                        <div class="msg_box">
                            <div class="nickname">李昊天</div>
                            <div class="messages">最近还好吗</div>
                        </div>
                        <div class="push_right">
                            <div class="time">12:50</div>
                            <div class="number">1</div>
                        </div>
                    </li>
                    <li >
                        <div class="avatar"><img src="@/assets/img/8.jpg" alt=""></div>
                        <div class="msg_box">
                            <div class="nickname">李昊天-</div>
                            <div class="messages">最近还好吗</div>
                        </div>
                        <div class="push_right">
                            <div class="time">12:50</div>
                            <div class="number">1</div>
                        </div>
                    </li>
                </ul>
            </nav>
            <main>
                <div
                        class="message_main"
                        ref="ele"
                        :style="{overflowY:messageScroll? 'auto' : 'hidden',paddingRight: messageScroll ? '0': '5px' }"
                        @mouseenter="showMessageScrolls" @mouseleave="hideMessageScrolls"
                >
                    <div class="mes_box" v-for="(item,index) in list" :class="{'me' : index % 2 === 0}">
                        <div class="avatar">
                            <img src="@/assets/img/5.jpg" alt="">
                        </div>
                        <div class="message_box">
                            {{item.msg}}
                        </div>
                    </div>
                </div>
                <div class="input_box">
                    <div class="menubar">
                        <svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-biaoqing-weixiao"></use>
                        </svg>
                        <svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-folder"></use>
                        </svg>
                        <svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-tupian1"></use>
                        </svg>
                        <svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-shuangsechangyongtubiao-"></use>
                        </svg>
                    </div>
                    <div class="input" ref="input" contenteditable="true" @keydown.enter="sendMsg" @change="inputMsg"
                         @input="inputMsg"></div>
                    <div class="footerbar">
                        <Button>关闭</Button>
                        <Button type="primary">发送</Button>
                    </div>
                </div>
            </main>
        </aside>
    </div>
</template>

script代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script>
    import '@/assets/css/scrool.css'
    import '@/assets/fonts/iconfont.js';

    export default {
        name: "friend",
        data() {
            return {
                list: [
                    {msg: '赵客缦胡缨,吴钩霜雪明'},
                    {msg: '银鞍照白马,飒沓如流星'},
                    {msg: '十步杀一人,千里不留行'},
                    {msg: '事了拂衣去,深藏身与名'},
                    {msg: '闲过信陵饮,脱剑膝前横。'},
                    {msg: '将炙啖朱亥,持觞劝侯嬴。'},
                    {msg: '三杯吐然诺,五岳倒为轻'},
                    {msg: '眼花耳热后,意气素霓生。'},
                    {msg: '救赵挥金槌,邯郸先震惊。'},
                    {msg: '千秋二壮士,烜赫大梁城。'},
                    {msg: '纵死侠骨香,不惭世上英。'},
                    {msg: '谁能书阁下,白首太玄经。'},
                    {msg: '是唐代大诗人李白借乐府古题创作的一首诗。此诗开头四句从侠客的装束、兵刃、坐骑刻画侠客的形象;第二个四句描写侠客高超的武术和淡泊名利的行藏;第三个四句引入信'},
                ],
                msg: '',
                number:8,
                messageScroll:false
            }
        },
        mounted() {
            this.$nextTick(function () {
                this.$refs.ele.scrollTop = this.$refs.ele.scrollHeight
            })
        },

        methods: {
            showMessageScrolls(){
                this.messageScroll = true;
            },
            hideMessageScrolls(){
                this.messageScroll = false;
            },
            inputMsg(e) {
                this.msg = e.target.innerHTML;
            },
            sendMsg(e) {
                this.list.push({msg: this.msg});
                this.msg = '';
                this.$refs.input.innerHTML = '';
                setTimeout(() => {
                    this.$refs.ele.scrollTop = this.$refs.ele.scrollHeight;
                }, 200);
                e.preventDefault();
            }
        }
    }
</script>

样式代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.friend_window {
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url("../img/main_1.jpg");
  border-radius: 4px;
  -webkit-user-select: none;
  background-size: 100% 100%;

  header {
    height: 40px;
    background-color: rgba(0, 0, 0, 0.3);
    -webkit-app-region: drag;
    border-radius: 4px 4px 0 0;
    display: flex;
    justify-content: space-between;

    .nickname {
      color: #FFF;
      line-height: 40px;
      font-size: 20px;
      margin: auto;
      padding-left: 40px
    }

    .buttons {
      i {
        display: inline-block;
        color: #FFF;
        width: 40px;
        height: 40px;
        line-height: 40px;
        text-align: center;
        cursor: pointer;
        -webkit-app-region: no-drag;

        &:hover {
          background-color: rgba(255, 255, 255, 0.3);
        }
      }
    }
  }

  aside {
    height: calc(100% - 40px);
    border-radius: 0 0 4px 4px;
    display: flex;
  }

  nav {
    width: 240px;
    position: relative;

    background-size: 100% 100%;
    overflow-y: auto;

    &:after {
      display: inline-block;
      content: '';
      width: 5px;
      cursor: e-resize;
      position: absolute;
      right: -2px;
      top: 0;
      height: 100%;
    }

    ul {
      li.active {
        background-color: rgba(255, 255, 255, 0.2);
      }
      li {
        list-style: none;
        height: 60px;
        padding-left: 10px;
        cursor: pointer;
        display: flex;
        overflow: hidden;
        align-items: flex-start;

        &:hover {
          background-color: rgba(255, 255, 255, 0.2);
        }

        .push_right {
          padding-right: 10px;
          text-align: center;
          align-self: center;

          .time {
            font-size: 13px;
            color: #CFD3DA;
          }

          .number {
            display: inline-block;
            background-color: #e4393c;
            color: #fff;
            min-width: 15px;
            min-height: 15px;
            padding: 0 2px;
            line-height: 15px;
            border-radius: 50%;
            text-align: center;
            font-size: 12px;
          }
        }

        .msg_box {
          align-self: center;
          flex: 1;
          color: #EFF1F3;

          .messages {
            color: #CFD3DA;
          }
        }

        .avatar {
          width: 45px;
          height: 45px;
          align-self: center;
          margin-right: 10px;

          img {
            width: 100%;
            height: 100%;
            border-radius: 50%;
          }
        }
      }
    }
  }

  main {
    background-color: #fff;
    width: calc(100% - 240px);
    border-radius: 0 0 4px 0;

    .message_main {
      height: calc(100% - 35%);
      overflow-y: auto;

      &::-webkit-scrollbar {
        display: block !important;
      }

      .mes_box {
        display: flex;
        margin-bottom: 10px;
        margin-top: 10px;
        padding: 10px;

        .avatar {
          width: 40px;
          height: 40px;
          margin-right: 10px;

          img {
            width: 100%;
            height: 100%;
            border-radius: 50%;
          }
        }

        .message_box {
          background-color: #FFFFFF;
          color: #333;
          padding: 10px;
          border-radius: 5px;
          max-width: 72%;
          position: relative;
          border: 1px solid #D4D4D4;

          &::before {
            content: '';
            display: block;
            position: absolute;
            width: 10px;
            height: 10px;
            border: 1px solid #D4D4D4;
            border-right: none;
            border-top: none;
            background-color: #FFFFFF;
            border-radius: 3px;
            transform: rotate(44deg);
            left: -6px;
            top: 14px;
          }
        }
      }

      .me {
        display: flex;
        justify-content: flex-end;

        .message_box {
          background-color: #A0E759;
          color: #333;
          border: 1px solid #77BF41;

          &::before {
            display: none;
          }

          &::after {
            content: '';
            display: block;
            position: absolute;
            width: 10px;
            height: 10px;
            border: 1px solid #77BF41;
            border-bottom: none;
            border-left: none;
            border-radius: 3px;
            background-color: #A0E759;
            transform: rotate(45deg);
            right: -6px;
            top: 14px;
          }
        }

        .avatar {
          order: 2;
          margin-left: 10px;
        }
      }
    }

    .input_box {
      border-top: 1px solid #ccc;
      height: calc(100% - 65%);

      .menubar {
        height: 30px;
        width: 100%;
        display: flex;
        align-items: center;

        .icon {
          display: inline-block;
          padding: 2px;
          width: 25px;
          height: 25px;
          cursor: pointer;
          margin-right: 5px;
          margin-left: 5px;

          &:hover {
            background-color: rgba(0, 0, 0, 0.1);
          }
        }
      }

      .footerbar {
        display: flex;
        height: 70px;
        align-items: center;
        justify-content: flex-end;
        padding-right: 20px;

        button {
          margin: 0 10px;
          padding-left: 30px;
          padding-right: 30px;
        }
      }

      .input {
        font-size: 16px;
        padding: 4px 8px;
        overflow-y: auto;
        height: calc(100% - 70px - 30px);

        background-color: #fff;

        &::-webkit-scrollbar {
          display: block !important;
        }
      }
    }
  }
}

.icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}

声明

代码只为学习使用,如果有个人或者机构使用该代码带来的侵权行为,与本人无关 如果代码有不合理之处请大家提出

遗留问题

有一个问题就是左侧的列表是没法拉伸的 不过已经做了样式了 如果不想要的可以去掉这个css代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    &:after {
      display: inline-block;
      content: '';
      width: 5px;
      cursor: e-resize;
      position: absolute;
      right: -2px;
      top: 0;
      height: 100%;
    }

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/dev...

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
ectron仿制qq(3) 主界面制作(2)
这里解释下 -顶部header的高度(140) 底部的高度(40) 写法很多 不过达到效果就行了 在窗口拉伸的时候可以自适应高度
李昊天
2019/05/26
7240
electron仿制qq(2) 主界面制作
制作从头开始 最后会将写好的组件放到一起的! 之前写了好几天的纯css 有点累 本章中将使用sass 如果代码太长 会分两个或多个章节写 代码中会有详细的注释 以便于大家阅读and理解 界面可能会有部分偏差 比较是仿制的
李昊天
2019/05/26
1.5K0
electron仿制百度网盘客户端2(登录界面制作)
百度网盘客户端的尺寸是: 主界面 w:662px h:442px 顶部header h:75px bg:#EFF2F6
李昊天
2019/05/26
1.4K0
electron 仿制QQ登录界面
注意 不要使用内置的拖动 我们要自己实现! 在页面中加入以下代码就可以实现拖动了!
李昊天
2019/05/26
7.6K0
vue.js客服系统实时聊天项目开发(三)实现对话框聊天界面
.chatRow 中的 align-items: flex-end; 让其子元素在底部对齐,实现头像垂直方向靠下对齐
唯一Chat
2023/01/15
4.8K0
使用SpringBoot + WebSocket实现单人聊天
在做之前,不管在界面布局,还是功能实现方面都下了一点功夫,最终还是一点点实现了,现在就记录一下。
全栈开发Dream
2021/06/08
2.2K0
使用SpringBoot + WebSocket实现单人聊天
为在线客服系统接入chatGPT(四):chatGPT接口vue网页版,可以联系上下文语境,可以实现自己的chatGPT,附代码
如果想实现chatGPT的网页版,调用接口就可以了,但是如果需要联系上下文语境,就需要在传递的数据的时候进行下拼接
唯一Chat
2023/02/17
2.7K1
为在线客服系统接入chatGPT(四):chatGPT接口vue网页版,可以联系上下文语境,可以实现自己的chatGPT,附代码
对话框外挂标签
新建[Blogroot]\themes\butterfly\scripts\tag\msgbox.js,注意外挂标签是内部函数,必须放在scripts目录下才会生效,不要自作聪明放到别的目录去再inject。
Akilar
2023/01/30
8540
9. CMDB前端开发(上)
目前虽然已经实现登录功能,即使没有登录情况下直接访问任何页面都还可以访问的,我们希望如果用户没有登录情况下,访问任何页面都重新导航到登录页面
alexhuiwang
2023/05/07
1.9K0
9. CMDB前端开发(上)
html组合css实现音乐排行版播放器
菜菜有点菜
2024/05/30
2170
html组合css实现音乐排行版播放器
Vue之Mixin【一种代码重用机制】
在 Vue 中,Mixin 是一种用于代码复用的特性。它允许你将一个组件中的部分功能提取出来,并在其他组件中重复使用。
HelloWorldZ
2024/03/20
2241
Vue之Mixin【一种代码重用机制】
html+css+js+python(QtWebEngineWidgets) 实现微信聊天界面-包括时间,文件,纯文本等
PyQt5 和 html 双向通信 python负责网络通信和API(html没有python照样可以)
zmh-program
2023/02/06
1.5K0
Python项目49-用户验证短信接口(可劲撸)
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
DriverZeng
2022/09/26
1.9K0
Vue电商后台管理系统(1)
在components文件夹下创建登录组件,Login.vue,并快速生成template、script和style骨架。
全栈程序员站长
2022/08/25
6910
Vue电商后台管理系统(1)
衔接-玩转AI新声态 | 玩转TTS/ASR/YuanQI 打造自己的AI助手
衔接上一篇 玩转AI新声态 | 玩转TTS/ASR/YuanQI 打造自己的AI助手 页面数据渲染篇
杨不易呀
2024/06/24
3601
衔接-玩转AI新声态 | 玩转TTS/ASR/YuanQI 打造自己的AI助手
WordPress网站B2主题会员展示模块
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
小狐狸说事
2022/11/17
1K0
WordPress网站B2主题会员展示模块
Python项目47-前后端分离登录注册页(继续撸)
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
DriverZeng
2022/09/26
4350
Python项目47-前后端分离登录注册页(继续撸)
7b2美化-首页添加导航会员区块
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
小狐狸说事
2022/11/17
7760
使用HTML制作静态网站作业——我的校园运动会(HTML+CSS)
✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (1000套) 】 🧡 程序员有趣的告白方式:【💌HTML七夕情人节表白网页制作 (110套) 】 🌎超炫酷的Echarts大屏可视化源码:【🔰 echarts大屏展示大数据平台可视化(150套) 】 🎁 免费且实用的WEB前端学习指南: 【📂web前端零基础到高级学习视频教程 120G干货分享】 🥇 关于作者
IT司马青衫
2022/08/23
1.4K0
使用HTML制作静态网站作业——我的校园运动会(HTML+CSS)
7b2主题评论气泡
这个功能来自于https://github.com/515184405/barrage,版权归他所有。
小狐狸说事
2022/11/17
3980
7b2主题评论气泡
相关推荐
ectron仿制qq(3) 主界面制作(2)
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文