简单地使用电子创建一个标记编辑器的方法
降价是每个开发人员的基本技能。在撰写Markdown的过程中,我们总是寻找各种各样的编辑,但每个编辑只能满足一个方面的需求,但并不是所有的编辑都能满足日常写作的需求。
因此,我想出了自己试试的主意,用Electron抛一个Markdown编辑器。
以下是我理想中的Markdown编辑器的痛点列表:
你必须有图片床功能,也可以直接上传到自己的图片背景,比如齐牛;样式必须是可定制的;导出的HTML内容可以直接粘贴到微信官方账号编辑器中,直接发布,没有格式问题;您可以自定义固定模块,例如文章的头部或尾部。你可以自定义功能,比如自动加载随机图片来丰富我们的文章。肯定是跨平台的。其他人。环境建设
目前使用Electron作为跨平台开发框架是最好的选择。此外,还基于电子技术开发了VS Code、Atom等大等级应用。
电子
用JavaScript、HTML和CSS搭建一个跨平台的桌面应用https://electronjs.org/
第一次使用Electron时,让我们下载并运行它:
#克隆样本项目的仓库$ git clone https://github.com/electron/electron-quick-start#进入这个仓库$ cd电子-快速启动#安装依赖项并运行$ NPM安装NPM启动
VUE
VUE是目前最好的前端框架,是我们的人开发的,我们不得不拒绝接受。我也是VUE的忠实粉丝,从1.0版本就开始用VUE了。
电子真空
将两者结合起来,这就是本文推荐的模拟reg/electron-vue:
vue init模拟reg/electron-vue fan ymd
安装插件并运行:
npm安装npm运行开发
选择插件
1.王牌编辑
选择一个好的编辑非常重要:
https://github.com/chairuosen/vue2-ace-editornpm安装buefy vue 2-ace-editor vue-素材-设计-图标-保存2。减价出售
我可以快速解析Markdown内容,我选择使用插件:markdown-it
npm安装降价保存3。电子商店
由于是编辑器应用,所以需要在本地存储很多个性化的设置和内容,比如编辑器需要的样式文件、自定义头尾内容等等。这里我选择:电子商店
集成npm安装-电子商店-保存
一切准备就绪,接下来我们开始实现Markdown的简单编辑和预览功能。
首先看src文件夹结构:readme.mdapp-screenshot.jpgappveyor.yml建 图标 256x256.png 图标. icns icon.ico区 电子m . ain . jswebpackage.jsonsrcindex . ejsmainindex . dev . jsindex . jsmain menu . js main . js 商店 content.js store.js 静态页面视图主要由渲染器渲染,因此我们首先在渲染器/组件/: EditorPage.vue下创建vue页面:
div id=' wrapper ' div id=' editor ' class=' columns is-gap less is-mobile ' editor id=' ace editor ' ref=' ace editor ' class=' column ' v-model=' input ' @ init=' editor init ' lang=' markdown '主题='黄昏'宽度='500px '高度=' 100% '/编辑器预览id=' preview '或' class=' column ' ref=' preview '或'/preview/div/div编辑区
左侧使用插件:必选(' vue2-ace-editor '),处理实时监听编者编辑输入减价内容,将内容传出去。
watch: { input:函数(新内容,旧内容){ messagebus。新内容播放器(新内容);}},其中这里的消息总线就是把某视频剪辑软件和ipcRenderer相关逻辑事件放在一起的main.js:
从“Vue”导入Vue从""导入应用程序/App ';导入" buefy/dist/buefy。CSS”;从“util”导入util从“电子”导入{ ipcRenderer };if(!过程。环境。is _ WEB)Vue。使用(需要(' Vue-e ')Vue。配置。production tip=false export const messageBus=new Vue({ methods : { new contenttorender(新内容){ ipcrenderer })。send(' new contenttorender ',新内容);},SaveCurrentFile(){ } } });//监听新内容回顾,将网址2评论传递给某视频剪辑软件的newContentToPreview事件//即,传给试映组件获取ipcrenderer。on(' new contenttopreview ',(event,URL 2preview)={ console。log(` ipcrenderer。在新的contenttopreview $ { util。inspect(event)} $ { URL 2preview } `);消息总线.$emit('newContentToPreview ',URL 2 preview);});/* ESL int-禁用无新*/新Vue({组件3360 { App },模板: 'App/'}).$mount('#app ')编辑器的内容,将实时由ipcrenderer。send(' new contenttorender ',新内容);下发出去,即由主要的进程的ipcMain.on('newContentToRender ',函数(事件,内容)事件获取。
一个电子应用只有一个主要的主进程,很多和本地化东西(如:本地存储,文件读写等)更多的交由主要的进程来处理。
如本案例中,想要实现的第一个功能就是,「可以自定义固定模块,如文章的头部,或者尾部」
我们使用一个插件:电子商店,用于存储头部和尾部内容,创建类别:
从“电子”导入{ app}从"路径"导入路径从" fs "导入满量程从“电子商店”类导入EStore Content { constructor(){ this。EStore=new EStore()。这个。EStore。set(' header Content ',' img src=' http 3360http://bimage。编码01。cn/徽标。JPEG ' class=' logo '部分class=' text word ' span class=' text '本文span id='word'111/span字,需要span id='time'/span 1分钟/span/section `)这个。埃斯托雷。设置('页脚内容',` hr strongcoding01期待您继续关注/strong img src=' http :http://BIM age。编码01。cn/coding 01 _ me .GIF' alt='qrcode'`) } //这将只返回数据对象get(键,val)上的属性{退回这个。埃斯托雷。get(' windowBounds,val) } //.这将设置它set(key,val) { this.estore.set(key,val)} getContent(Content){ return this。标题内容内容。footer Content } getheader Content(){返回此。埃斯托雷。get(' header Content ',' ')} getFooterContent(){返回此。埃斯托雷。get(' footercontent ',' ')}//暴露classexport默认内容注:这里只是写死的头部和尾部内容。有了头尾部内容,和编辑器的减价内容,我们就可以将这些内容整合,然后输出给我们的右侧试映组件了。
ipcMain.on('newContentToRender ',函数(事件,内容){ const render render content=render content(标题内容、footerContent、内容、cssContent、' layout 1。html ');const previewURL=newContent(已呈现);主窗口。网络内容。发送(' newContentToPreview ',previewURL);});其中,呈现内容(标题内容,脚注内容,内容,内容,layout1.html)方法就是将我们的头部、尾部、降价内容、css样式和我们的模板layout1.html载入。这个就比较简单了,直接看代码:
从"降价"导入多维索引树从“ejs”导入ejsconst mditConfig={ html: true,//在源XHTML lout :中启用超文本标记语言标记true,//使用'/'关闭单个标记(br/)break 3360 false,//将段落中的\n '转换为br///langprefix 3360 ' language-',//隔离块的半铸钢钢性铸铁(Cast Semi-Steel)语言前缀linkify: true,//自动转换链接到版式的类似全球资源定位器(Uniform Resource Locator)的文本3360假,//启用自作聪明的裤子和其他甜蜜转换//荧光笔函数。如果输入没有更改highlight:函数(/*str,lang*/) { return " ",则应返回转义的html,//或"";}};const MD=mdit(mditConfig);const layout=[];导出函数renderContent(headerContent、footerContent、Content、cssContent、layout file){ const text=MD . render(Content);const layout=布局文件[layout file];const rendered=ejs.render(布局,{ title: 'Page Title ',content: text,cssContent: cssContent,页眉内容:页眉内容,页脚内容:页脚内容,});已呈现的返回;}布局['布局1。html ']=' html head meta charset=' utf-8 ' title %=title %/title style %-CSS content %/style/head body div class=' markdown-body ' section class=' body _ header ' %-head content %/section div id=' content %-content %/div section class=' body _ footer content %/section/div/body/html `;这里,使用插件减价出售来解析减价内容,然后使用ejs.render()来填充模板的各个位置内容。这里,同时也为我们的目标:样式必须是可以自定义的和封装各种不同情况下,使用不同的头部、尾部、模板、和样式提供了伏笔当有了内容后,我们还需要把它放到「服务器」上,const previewURL=newContent(已呈现);
从" http "导入http从" url "导入网址;定义变量服务器;定义变量内容;导出函数createServer() { if(服务器)抛出新错误('服务器已经启动');服务器=http。CreateServer(request handler);server.listen(0,' 127。0 .0 .1 ');}导出函数新内容(文本){内容=文本;返回属R1(“内容”);}导出函数currentContent(){ 0返回内容;}函数属rl(pathname){ const URL 2 preview=URL。格式({协议: ' http ',主机名: server.address().地址,端口:服务器.地址().端口,路径名:路径名});返回url2preview}函数requestHandler(req,RES){ 0尝试{ res.writeHead(200,{ 'Content-Type': 'text/html ',' Content-Length ' : Content。length });res.end(内容);} catch(err) { res.writeHead(500,{ ' Content-Type ' : ' text/plain ' });结束(错误。堆栈);}}最终得到统一资源定位器对象,转给我们右侧的试映组件,即通过主窗口。网络内容。发送(' newContentToPreview ',previewURL);
注:在主要的和渲染器进程间通信,使用的是ipcMain和ipcRenderer。ipcMain无法主动发消息给ipcRenderer。因为ipcMain只有。打开()方法没有。发送()的方法。所以只能用网络内容。预览区
右侧使用的时间上就是一个内联框架控件,具体做成一个组件预览:
模板iframe src=' http : '/template script import { messageBus } from './main。js ';导出默认{ methods : { reload(previewSrcURL)}这个.$ el.src=previewSrcURL} },created:函数(){ messageBus .$on('newContentToPreview ',(URL 2preview)={ console。日志(` newContentToPreview $ { URL 2preview } `));这个。重新加载(网址2preview);});} }/脚本样式范围diframe { height : 100%;}/样式在试映组件我们使用某视频剪辑软件的$on监听newContentToPreview事件,实时载入统一资源定位器对象。
消息总线.$on('newContentToPreview ',(URL 2preview)={ this。重新加载(网址2preview);});到此为止,我们基本实现了最基础版的减价编辑器功能纱线运行开发运行看看效果:
总结
第一次使用电子,很肤浅,但至少学到了一些知识:
每个电子应用程序只有一个Main进程,主要用于处理系统和创建应用程序窗口。在主进程中,ipcMain用于监视来自ipcRenderer的事件,但没有send方法,只能使用BrowserWindow。webContents.send().每个页面都有一个相应的渲染器进程,用于渲染页面。还有一个相应的ipcRenderer用于接收和发送事件。在vue页面组件中,我们仍然使用vue的$on和`$emit来发送和接收消息。接下来一步一步完善应用,目标是满足自己的需求,然后:也许有一天会开源。
解决中文编码问题
当我们使用iframe时,我们需要向内嵌在iframe中的html/html添加metacarset=' utf-8 '
复制代码如下:以上是本文的全部内容。希望对大家的学习有帮助,支持我们。
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。
版权声明:简单地使用电子创建一个标记编辑器的方法是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。