首页 > 作文

electron聊天室

更新时间:2023-04-07 08:11:26 阅读: 评论:0

一、项目概况

基于electron+vue+electron-vue+vuex+nodejs+vuevideoplayer+electron-builder等技术仿制微信电脑端界面聊天室实例,实现消息发送/动态表情,图片/视频预览,拖拽图片/粘贴截图发送,朋友圈/红包/换肤等功能。

二、效果图

三、技术栈

框架技术:electron + electron-vue + vue状态管理:vuex地址路由:vue-router字体图标:阿里iconfont字体图标库弹窗插件:wcpop打包工具:electron-builder环境配置:node.js +chromium图片预览:vue-photo-preview视频组件:vue-video-player

如何配置开发环境及使用electron-vue,这里不作多介绍,可查阅官网及搜资料

https://github.com/simulatedgreg/electron-vue

注意:由于electron-vue作者长时间未更新,里面electron版本v2.0.4太旧,如遇问题,可升级到最新版本

◆ electron主进程index.js

通过browrwindow创建和控制浏览器窗口,官网有详细介绍,这里略过…

...let mainwinlet traylet forcequit = fallet logined = fal/** * 创建主窗口============================= */function createmainwin() {    mainwin = new browrwindow({        // 背景颜色        // backgroundcolor: '#ebebeb',        width: common.win_size_main.width,        height: common.win_size_main.height,        title: common.win_title,        ucontentsize: true,        autohidemenubar: true,        // 无边框窗口        frame: fal,        resizable: true,        // 窗口创建的时候是否显示. 默认值为true        show: fal,        webpreferences: {            // devtools: fal,            webcurity: fal        }    })        mainwin.tmenu(null)    mainwin.loadurl(common.win_load_url())        mainwin.once('ready-to-show', () => {        mainwin.show()        mainwin.focus()    })        // 点击关闭最小到托盘判断    mainwin.on('clo', (e) => {        if(logined && !forcequit) {            e.preventdefault()            mainwin.hide()        }el {            mainwin = null            app.quit()        }    })        initialipc()
apptray.createtray()}app.on('ready', createmainwin)app.on('activate', () => { if(mainwin === null) { createmainwin() }})...

如上图:创建托盘图标及闪烁效果

/** * 托盘图标事件 */let flashtraytimer = nulllet trayico1 = `${__static}/icon.ico`let trayico2 = `${__static}/empty.ico`let apptray = {  // 创建托盘图标  createtray() {    tray = new tray(trayico1)    const menu = menu.buildfromtemplate([      {        label: '打开主界面',        icon: `${__static}/tray-ico1.png`,        click: () => {          if(mainwin.isminimized()) mainwin.restore()          mainwin.show()          mainwin.focus()                    this.flashtray(fal)        }      },      {        label: '关于',      },      {        label: '退出',        click: () => {          if(process.platform !== 'darwin') {            mainwin.show()            // 清空登录信息            mainwin.webcontents.nd('clearloggedinfo')                        forcequit = true            mainwin = null            app.quit()          }        }      },    ])    tray.tcontextmenu(menu)    tray.ttooltip('electron-vchat v1.0.0')    // 托盘点击事件    tray.on('click', () => {      if(mainwin.isminimized()) mainwin.restore()      mainwin.show()      mainwin.focus()      this.flashtray(fal)    })  },  // 托盘图标闪烁  flashtray(flash) {    let hasico = fal    if(flash) {      if(flashtraytimer) return      flashtraytimer = tinterval(() => {        tray.timage(hasico ? trayico1 : trayico2)        hasico = !hasico      }, 500)    }el {      if(flashtraytimer) {        clearinterval(flashtraytimer)        flashtraytimer = null      }      tray.timage(trayico1)    }  },  // 销毁托盘图标  destroytray() {    this.flashtray(fal)    tray.destroy()    tray = null  }}

◆ 渲染进程主页面main.js及app.vue

/** * @desc   主入口main.js * @about  q:282310962  wx:xy190310 */import vue from 'vue'import axios from 'axios'import app from './app'import router from './router'import store from './store'// 引入组件配置import $components from './components'vue.u($components)if (!process.env.is_web) vue.u(require('vue-electron'))vue.http = vue.prototype.$http = axios/* eslint-disable no-new */new vue({  components: { app },  router,  store,  template: '<app/>'}).$mount('#app')
<template>  <div id="app">    <div class="elv-container" :style="$store.state.winskin && {'background-image': 'url('+$store.state.winskin+')'}">      <div class="elv-wrapper flexbox">        <!-- //侧边栏 -->        <side-bar v-if="!$route.meta.hidesidebar" />        <!-- //主布局 -->        <div class="elv-mainbx flex1 flexbox flex-col">          <!-- ...顶部按钮 -->          <win-bar />                    <keep-alive>            <router-view></router-view>          </keep-alive>        </div>      </div>    </div>  </div></template>

至于状态管理及路由配置基本和vue里面使用一样,这里也略过…

◆ electron自定义最大/小化、关闭按钮、无边框窗口拖动

配置browrwindow里面frame:fal就会是无边框窗口,这时就可以自定义最大/小,关闭按钮,那么感动中国年度人物问题来了,无边框窗口如何进行拖动尼?

1、通过moudown、moumove等事件处理2、设置需要拖动区css属性 -webkit-app-region
.elv__drag{-webkit-app-region: drag; -webkit-ur-lect:none; -moz-ur-lect:none; -ms-ur-lect:none; ur-lect:none;}.elv__nodrag{-webkit-app-region: no-drag;}

注意:默认设置-webkit-app-region: drag后,下面的元素不能点击操作,可通过设置需点击元素no-drag即可。

import { app, remote, ipcrenderer } from 'electron'import { mapstate, mapmutations } from 'vuex'let currentwin = remote.getcurrentwindow()export default {    props: {        title: string,    },    data () {        return {// 是否置顶            isalwaysontop: fal,            //连续剧排行榜 窗口是否可以最小化            isminimizable: true,            // 窗口是否可以最大化            ismaximizable: true,        }    },    computed: {        ...mapstate(['iswinmaxed'])    },    mounted() {if(!currentwin.isminimizable()) {            this.isminimizable = fal        }        if(!currentwin.ismaximizable()) {            this.ismaximizable = fal        }        if(this.iswinmaxed && currentwin.ismaximizable()) {            currentwin.maximize()        }        // 监听是否最大化        currentwin.on('maximize', () => {            this.t_winmaximize(true)        })        currentwin.on('unmaximize', () => {            this.t_winmaximize(fal)        })    },    methods: {        ...mapmutations(['t_winmaximize']),        // 置顶窗口        handlefixtop() {            this.isalwaysontop = !this.isalwaysontop            currentwin.talwaysontop(this.isalwaysontop)        },        // 最小化        handlemin() {            currentwin.minimize()        },        // 最大化        handlemax() {            if(!currentwin.ismaximizable()) return            if(curr繁体名字entwin.ismaximized()) {                currentwin.unmaximize()                this.t_winmaximize(fal)            }el {                currentwin.maximize()                this.t_winmaximize(true)            }        },        // 关闭        handlequit() {            currentwin.clo()        }    }}

◆ 聊天编辑器光标处插入表情、div可编辑contenteditable=”true”双向绑定

如何实现electron vue中向编辑框contenteditable光标处插入动态表情,类似qq、微信聊天编辑器??

1、使用input、textarea文本框实现

通过给input或textarea文本框插入[奋斗]、(:17 等表情符标签,展示信息的时候解析标签就行

<!doctype html><html>    <head>        <meta chart="utf-8">        <title></title>        <link href="/d/file/titlepic/bootstrap.min.css" rel="stylesheet">    </head>    <body>        <div class="container">            <div class="row">                <div class="col col-sm-12">                    <button class="btn btn-success" data-emoj="[笑脸]">[笑脸]</button>                    <button class="btn btn-success" data-emoj="[奋斗]">[奋斗]</button>                    <button class="btn btn-success" data-emoj="[:17]">[:17]</button>                </div>                <div class="col col-sm-12">                    <textarea class="form-control" id="content" rows="10"></textarea>                </div>            </div>        </div>             <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>        <script>            (function ($) {                $.fn.extend({                    inrtemojatcaret: function (myvalue) {                        var $t = $(this)[0];                        if (document.lection) {                            this.focus();                            l = document.lection.createrange();                            l.text = myvalue;                            this.focus();                        } el if ($t.lectionstart || $t.lectionstart == '0') {                            var startpos = $t.lectionstart;                            var endpos = $t.lectionend;                            var scrolltop = $t.scrolltop;                            $t.value = $t.value.substring(0, startpos) + myvalue + $t.value.substring(endpos, $t.value.length);                            this.focus();                            $t.lectionstart = startpos + myvalue.length;                            $t.lectionend = startpos + myvalue.length;                            $t.scrolltop = scrolltop;                        } el {                            this.value += myvalue;                            this.focus();                        }                    }                });            })(jquery);                             $("button").on("click", function() {                $("#content").inrtemojatcaret($(this).attr("data-emoj"));            });        </script>    </body></html>
2、运用h5中div可编辑contenteditable=”true”实现

在vue页面设置contenteditable=”true” 实现富文本文本框效果,由于div不能绑定v-model,只能使用vue提供的自定义组件v-model功能。

https://cn.vuejs.org/v2/guide/components-custom-events.html#%e8%87%aa%e5%ae%9a%e4%b9%89%e7%bb%84%e4%bb%b6%e7%9a%84-v-model

思路:新建一个chatinputedit.vue组件,通过监听数据变化返回父组件数据

1):调用chatinputedit.vue组件,并给其绑定v-model

<template>    ...    <chatinputedit ref="chatinput" v-model="editortext" /></template>...export default {    data () {        return {            editortext: '',                        ...        }    },    ...}

2):v-model中传入的值在子组件prop中获取并监听value变化

export default {    props: {        value: { type: string, default: '' }    },    data () {        return {            editortext: this.value,            ...        }    },    watch: {        value() {            ...        }    },}

3):监听获取到的值赋值给子组件中的v-html参数,就打通双向绑定链路了

/** * contenteditable光标处插入内容 */inrthtmlatcaret(html) {    let l, range;    if(!this.$refs.editor.childnodes.length) {        this.$refs.editor.focus()    }    if (window.getlection) {        // ie9 and non-ie        l = window.getlection();        if (l.getrangeat && l.rangecount) {            range = l.getrangeat(0);            range.deletecontents();            let el = document.createelement("div");            el.appendchild(html)            var frag = document.createdocumentfragment(), node, lastnode;            while ((node = el.firstchild)) {                lastnode = frag.appendchild(node);            }            range.inrtnode(frag);            if (美国重返亚太lastnode) {                range = range.clonerange();                range.tstartafter(lastnode);                range.collap(true);                l.removeallranges();                l.addrange(range);            }        }    } el if (document.lection && document.lection.type != "control") {        // ie < 9        document.lection.createrange().pastehtml(html);    }}

◆ electron+vue实现微信截图功能

node中通过的execfile方法执行exe文件,exe调用同级目录下的微信截图dex啥意思ll,调出截图工具

handlecapturescreen() {    return new promi((resolve) => {        const { execfile } = require('child_process')        var screenwin = execfile('./static/printscr.exe')        screenwin.on('exit', function(code) {            let pngs = require('electron').clipboard.readimage().topng()            let imgdata = new buffer.from(pngs, 'ba64')            let imgs = 'data:image/png;ba64,' + btoa(new uint8array(imgdata).reduce((data, byte) => data + string.fromcharcode(byte), ''))            resolve(imgs)        })    })},

okay。以上就是基于electron+vue开发仿微信客户端聊天实例分享,希望能有些帮助!!

本文发布于:2023-04-07 08:11:22,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/3e7cbcd44721d7db3034a8a42145e311.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:electron聊天室.doc

本文 PDF 下载地址:electron聊天室.pdf

标签:窗口   托盘   组件   图标
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图