electron制作仿制qq聊天界面的示例代码


Posted in Javascript onNovember 26, 2018

本文介绍了electron制作仿制qq聊天界面的示例代码,分享给大家,具体如下:

效果图:

electron制作仿制qq聊天界面的示例代码

样式使用scss和flex布局

这也是制作IM系统的最后一个界面了!

在制作之前参考了qq和千牛

需要注意的点

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

滚动条美化

::-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事件

<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 如果不加 在滚动条显示的时候页面会抖动

简单写法

@mouseenter="messageScroll = true" 
 @mouseleave="messageScroll = false"

页面滚动

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

this.$nextTick(function () {
        this.$refs.msgBox.scrollTop = this.$refs.msgBox.scrollHeight
})

消息发送滚动到底部

this.$refs.msgBox.scrollTop = this.$refs.msgBox.scrollHeight;

内容编辑

没有使用表单元素 直接使用的 contenteditable

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

代码

页面代码

<template>
  <div class="friend_window">
    <header>
      <div class="nickname">Lee</div>
      <div class="buttons">
        <i class="iconfont"></i>
        <i class="iconfont"></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" rel="external nofollow" ></use>
            </svg>
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-folder" rel="external nofollow" ></use>
            </svg>
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-tupian1" rel="external nofollow" ></use>
            </svg>
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-shuangsechangyongtubiao-" rel="external nofollow" ></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代码

<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>

样式代码

.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代码

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
最新优化收藏到网摘代码(digg,diigo)
Feb 07 Javascript
javascript 函数式编程
Aug 16 Javascript
Js 本页面传值实现代码
May 17 Javascript
Javascript var变量隐式声明方法
Oct 19 Javascript
浅析AngularJs HTTP响应拦截器
Dec 28 Javascript
浅谈JS中的三种字符串连接方式及其性能比较
Sep 02 Javascript
javascript判断回文数详解及实现代码
Feb 03 Javascript
js控制按钮,防止频繁点击响应的实例
Feb 15 Javascript
微信小程序使用image组件显示图片的方法【附源码下载】
Dec 08 Javascript
详解VUE2.X过滤器的使用方法
Jan 11 Javascript
vue项目中使用tinymce编辑器的步骤详解
Sep 11 Javascript
vue-cli项目中使用echarts图表实例
Oct 22 Javascript
Vuex的初探与实战小结
Nov 26 #Javascript
微信小程序页面间值传递的两种方法
Nov 26 #Javascript
Vue中的methods、watch、computed的区别
Nov 26 #Javascript
vue-router懒加载速度缓慢问题及解决方法
Nov 25 #Javascript
移动端滑动切换组件封装 vue-swiper-router实例详解
Nov 25 #Javascript
vue中选项卡点击切换且能滑动切换功能的实现代码
Nov 25 #Javascript
vue中tab选项卡的实现思路
Nov 25 #Javascript
You might like
php mysql Errcode: 28 终极解决方法
2009/07/01 PHP
php验证身份证号码正确性的函数
2016/07/20 PHP
PHP MYSQL简易交互式站点开发
2016/12/27 PHP
PHP使用星号替代用户名手机和邮箱的实现代码
2018/02/07 PHP
PHP命名空间与自动加载类详解
2018/09/04 PHP
对laravel的session获取与存取方法详解
2019/10/08 PHP
javascript:;与javascript:void(0)使用介绍
2013/06/05 Javascript
javascript实现验证身份证号的有效性并提示
2015/04/30 Javascript
jquery判断复选框选中状态以及区分attr和prop
2015/12/18 Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(一)
2016/02/16 Javascript
jQuery通过写入cookie实现更换网页背景的方法
2016/04/15 Javascript
浅析JavaScript中浏览器的兼容问题
2016/04/19 Javascript
Javascript中prototype的使用详解
2016/06/18 Javascript
Bootstrap的fileinput插件实现多文件上传的方法
2016/09/05 Javascript
JS正则替换去空格的方法
2017/03/24 Javascript
AngularJS实现自定义指令与控制器数据交互的方法示例
2017/06/19 Javascript
手把手教你vue-cli单页到多页应用的方法
2018/05/31 Javascript
vue项目中使用lib-flexible解决移动端适配的问题解决
2018/08/23 Javascript
Vue.js 时间转换代码及时间戳转时间字符串
2018/10/16 Javascript
关于vue组件事件属性穿透详解
2019/10/28 Javascript
JS实现时间校验的代码
2020/05/25 Javascript
jQuery 实现DOM元素拖拽交换位置的实例代码
2020/07/14 jQuery
[15:20]DOTA2亚洲邀请赛总决赛开幕式表演:羽泉献唱
2017/04/05 DOTA
Python的string模块中的Template类字符串模板用法
2016/06/27 Python
numpy中矩阵合并的实例
2018/06/15 Python
Python创建或生成列表的操作方法
2019/06/19 Python
win10子系统python开发环境准备及kenlm和nltk的使用教程
2019/10/14 Python
Python多进程multiprocessing、进程池用法实例分析
2020/03/24 Python
pygame实现弹球游戏
2020/04/14 Python
PyPDF2读取PDF文件内容保存到本地TXT实例
2020/05/12 Python
详解pandas apply 并行处理的几种方法
2021/02/24 Python
CSS3使用transition实现的鼠标悬停淡入淡出
2015/01/09 HTML / CSS
印度最大的酒店品牌网络:OYO Rooms
2016/07/24 全球购物
《邮票齿孔的故事》教学反思
2014/02/22 职场文书
教堂婚礼主持词
2014/03/14 职场文书
党的群众路线教育实践活动党员个人整改措施
2014/10/27 职场文书