Coder Social home page Coder Social logo

myhelper's People

Contributors

wsqy182 avatar

Stargazers

 avatar

Watchers

 avatar

myhelper's Issues

数据删除成功但是视图刷新失败

这个问题出现的场景是,我在调用菜单的删除功能,菜单首先会删除一条数据,然后再从数据库中读取最新的数据,然后ipcMain同步消息给渲染层说删除成功.渲染层在读取最新的数据进行视图的更新。
但是我发现,视图的自动刷新有时成功,有时失败。
首先分析这个问题,删除数据,这个功能既然成功一次,说明后面每次调用都是成功的,问题就在于,数据的读取是异步的,也就是说在命令还没有删除成功的时候,代码不阻塞,继续往下执行,又从数据库中读取出了脏数据,然后刷新视图。
后面我查了下sqlite3这个模块的说明,说是这个模块最大的特点就是异步执行。
要想避免脏数据的产生,只能传递回调函数。
参考文档:https://blog.csdn.net/chuanqi305/article/details/17930179

在研究了sqlite3的异步之后,我改变了部分代码,利用sqlite3模块的回调,来调用下一个函数。也就是我引入了Promise.每一个dao层需要同步的方法,我都会返回Promise,外部执行完第一个方法后,可以根据需要传入下一个要调用的函数。

使用promise需要注意的是this的指针的作用域。

目前这个bug已经通过引入promise并修改代码从线性执行为promise形式的链式调用,成功解决

快捷键失效问题

按照electron-vue中文教程中的教程设置了快捷键,说是要给菜单项传入一个字符串。
于是我传入了这个字符串,但是这种方法,快捷键并没有生效。
于是我又找问题所在,发现这个中文网的教程有歧义。
官方的文档中,描述electron中菜单的快捷键,通常是两种设置方式,
1.app内全局注册.
2.利用web页面的window去注册快捷键.

我之前开发的易语言里面,也有这样的设置。易语言的菜单设计是有一个专门的管理工具的,这个管理工具也是说可以设置快捷键,但其实就是在菜单上显示一些字符串,按下对应的快捷键并没有卵用!
注册快捷键要用全局监听的方式,这就导致了即使不在app的窗口内按下快捷键,也会被监听到。
我之前写的易语言的cmdHelper里面就遇到了这个问题,就是快捷键冲突。我定义的快捷键,确实可以触发某个菜单,但是我这个app只要挂在后台,其他app(比如chrome),就无法监听到我的快捷键,这就是快捷键冲突。

所以我认为electron中,自然也无法避免这个问题。不过electron这个还是和易语言有些区别,即使你指定了菜单快捷键的字符串,但是这个字符串没有再全局快捷键中注册,菜单是不会显示这个字符串来产生歧义的,这就导致另外一个现象,看起来就是设置菜单项快捷键的设置不生效,但其实是没有注册快捷键。

所以,我修改了代码,先全局注册快捷键,再给菜单指定相应的快捷键。

但是我想这样可能会衍生出跟易语言一样的问题,就是快捷键冲突。所以我决定实验一下。易语言中快捷键冲突我暂时没有解决方案,因为找不到局部注册快捷键的方式,所以的组件对键盘按下,都没有反应。这也是我很不爽易语言的原因,因为碰到问题了,解决不了,连个替代方案你可能都找不到,要么开发代价很大,要么就只能开发出有bug的代码。而electron不同,他没有组件的概念,他的渲染是由浏览器负责的,我可以很方便的修改页面的形式,也可以衍生出很多解决方案,比如快捷键冲突,我可以把快捷键局部绑定到页面上去。

先试一下快捷键,然后把冲突了快捷键改掉。

在修改代码的过程中,还碰到了一个恼火的问题,代码的执行顺序和this指针的引用。
我发现自定义的对象,只要对象所处的环境变化,this也会发生改变,比如指向顶层undefied目前我是解决了。但是还是搞不懂this的使用。

然后我发现,即使全局注册了快捷键,也并不管把菜单和这个快捷键自动关联起来。这也就是说,写入快捷键提示是可以的,全局绑定快捷键也是可以的。但是electron不会自动关联两者,这就跟我前面描述的有冲突,但是还是不知道为什么写个快捷键提示也会不成功。

element-ui input无法获取焦点

做了个查找功能,想在按下快捷键打开查找框后,查找框自动获取焦点。

我调用了element-ui提供的api,使用this.$refs去调用这个组件来获取焦点。但是element-ui没有鸟我。

我还纠结是不是this.$refs有问题,又去官网查vue.js的api,发现人家用的是this.$ref,然后我又换成this.$ref调用,还是没有鸟我,我把this.$ref打印出来一看,undefind。

然后又把this打印出来一看,只挂在了$refs。

我瞬间无语了,官网说$ref是在当前组件掉的,$refs是在父组件调的,官网的文档都靠不住?

于是我又改成this.$refs来调,组件是找到了,但是还是没有获取焦点。

我就想,这他么不会又被element-ui给忽悠了,文档告诉你这么个API,不管用?

于是我又写了个原生的input去获取焦点,成功了。

我人就不好了。

可能跟组件的可视化有关,因为我是先改变element-ui input的可视再获取焦点的,可能element-ui有动画,所以导致先获取焦点,再可视化导致焦点的丢失也是有可能的,就跟之前脏数据的读取bug一样。

经过一系列的资料查找,终于有了解决方案,使用vue的.$nextTick,在组件全部刷新完毕后,在nextTick的回调中去获取焦点就可以了

下面给出参考的资料

正确理解使用Vue里的nextTick方法
https://segmentfault.com/q/1010000011481239
http://www.flowerboys.cn/VueJs/2017/0614/99.html

Menu is not a constructor

在之前的代码中,我已经通过MenuFunc.js文件创建了窗口的上下文菜单,菜单事件触发后也成功的将主进程读的数据显示到渲染进程。
但是刚才写着写着再运行,页面就发白了,什么也加载不出来,electron自动加载的开发人员工具也就是F12就抛出了一个错误,说MenuFunc.js中Menu is not a constructor。
这我就很郁闷了,菜单在之前的代码里都创建成功了,
下面就是代码

// 定义菜单项的功能
const menu = new Menu()

为何突然说Menu不是构造函数呢?

我想着太奇怪了,之前都可以拿构造函数创建菜单,突然又说不行了。

于是我检查了代码的历史记录,发现并没有改动什么东西。
只是加了一些用于菜单被点击后发送事件的事件名常量,常量应该不会影响我的代码运行啊

检查了许久,我看着F12的控制台错误发愣,突然意识到了某种东西。

我为了保证渲染层和主进程的事件名一致,把在MenuFunc中定义的事件名常量用import的形式导入到了渲染层。

而import对导入的js是使用单例模式的,这也就是说,在渲染层加载页面的时候,就会调用MenuFunc中创建菜单的Menu构造函数创建菜单。而很明显,Menu模块是不能在渲染层调用的,这也就直接导致了渲染的失败。
而之前的代码没有这样做,只是在主进程中创建菜单。

也就是说,我尝试着在渲染层导入一个js,这个js本来是在主进程中加载的,创建菜单和定义常量都不会报错,但是渲染层又加载了一次这个js,渲染层也尝试着创建这个menu对象,然后就在开发人员工具中抛出了Menu is not a constructor这个错误。

我将渲染层引入MenuFunc.js文件改了名字,再启动,代码没有再报错。

这个bug其实是代码逻辑引起的,这也证实了主进程的模块是不能在渲染层调用的申明。

这个逻辑引起的bug这很好解决,只要把在MenuFunc定义的事件常量移到一个普通的js文件,然后渲染层和主进程各自引用这个js或者将这个常量共享就行了。

keyup事件不生效

大致情况是这样,想让输入框中按下回车后对数据库进行模糊查找。于是使用了element-ui中的输入框。庵后使用v-on绑定key-up事件,但是发现事件并没有被触发。

首先想到的是是否是语法写错了,毕竟有很长时间没有玩vue了,不知道是否会有语法的更新。经过查找,语法确实有更新,但是我使用的electron-vue脚手架搭建的vue环境版本是可以对上的。也就是说并不是语法问题。

于是我又去查找electron-vue的相关问题,想看看是不是有这类问题的解决方案。electron-vue推荐了在渲染层绑定快捷键的方法,是使用window对象添加事件监听器。

我尝试了以下,发现页面是可以接收keyup事件的,但是element-ui的相关组件上依旧没有事件的触发,触发的是window上绑定的keyup事件。于是我又尝试着绑定了click事件,发现依旧不触发。

这是只剩下几种可能性,
1.keyup事件被electron拦截去处理了,但没有处理事件的冒泡,所以webContents上没有接收到keyup事件。
2.webContents上接收到keyup事件,但是被element-ui拦截了。

第二种问题是比较麻烦的,因为我element-ui文档并没有找到相关的事件是如何触发的,只是element-ui为了实现一个提示输入的功能,已经使用了key-up事件。

我使用了一个普通的input标签,绑定了keyup事件,发现这个input是可以接收到keyup事件的,所以问题就确定了,keyup事件被这个element-ui的组件给拦截了。

这个时候的解决方案也只有两种,1,放弃使用element-ui的组件,使用自定义的组件。2.使用window监听键盘按下事件.

第一种方案代价太大,我使用第二种方案,用原生js手动绑定一个事件监听器就可以了。

主进程和渲染进程通讯

先说下大致的问题吧。
主要功能是在启动后读取完sqlite3的数据后,显示到vue的页面。

按照最初的设想,vue是双向绑定的,通常用的最多的就是改变数据后就改变了视图,不需要我们去操作dom。

不用想,vue是属于渲染进程,要读取主进程的数据,就涉及到主进程和渲染进程通讯。

一开始看到了一个electron提供了一个简单的方案,是多进程读取同一块全局变量。于是我就用vue直接绑定了这个全局变量,然后当主进程的菜单被点击后,主进程的菜单点击事件将数据读取出来,塞到这个全局变量里,理论上vue就会刷新视图。

但是并不顺利,vue并没有如我想象的去刷新视图。

于是又参考了下electron进程之间通讯的api,最后决定绕一圈,用事件发射的方式,让主进程读取完数据后,将数据塞到全局变量里,再发送一个事件,渲染进程接收到该事件后将调用某个函数,再把数据读取出来,绑到vue的组件上。这次成功了,但前提这个vue组件的属性在初始化时,不能直接绑定全局变量。

中间还除了一些小bug,比如主进程中弹出的警告框后只有强制退出才能中断程序,不退出不管你的逻辑如何,都会直接走完正常程序,这个bug我到现在也没有想通,是怎么出现的。鉴于我学习的特性,这个问题,恐怕很久都得不到答案。

electron安装sqllite3失败

从目前找到的资料来看,node.js下运行的第三方模块是可以直接运行在electron上。但是也有很多模块需要进行安装才可以。找了很多资料,都没有解决electron使用sqlite3的问题。
直到后来按照下面这偏博客的指导,才有了方向。
第二种方法,前面两步都成功,第三步报错提示没有python。于是我又重新审视了整篇博客,准备安装一个python,再尝试一下.

需要注意的是从官网下载的python2.7的安装包默认不会配置环境变量,但是这个是可选的.

而且,你从cmd中可以看到python安装成功后,idea中的命令行工具并不能识别到这个python命令。
因此我选择重启idea

很明显重启了idea之后也没用。

然后我又重试着使用管理员权限打开idea。终于在idea的命令行端进入了python。

然后我又重新尝试着编译sqlite3的electron版本的dll,但是报了一个错误。

这个错误很常见,连接超时,很明显是在预编译的时候从美国的服务器上下载文件,然后由于网速问题,这个服务又他娘的挂掉了。这种情况下,基本不要慌,重试几次就ok了。

然而重试了好几次,都会中断这个编译过程。我意识到这样不行。

在查询资料后使用如下命令解决了问题.
npm config set ELECTRON_MIRROR http://npm.taobao.org/mirrors/electron/

设置electron镜像指向淘宝.

并关闭了sockwindow(一个全局的http代理翻墙软件)。

再尝试编译,就成功了。

以下是相关的资料.
https://newsn.net/say/electron-install-sqlite3.html

项目中修改src/main/index.js内容不生效

刚开始用这个vue-electron 的模版开始编写APP的时候,
是跟着官方的教程,使用vue-cli工具下载的一个vue-electron模版。

在构建项目初始结构的时候,一路都使用了默认设置,然默认的项目模版是使用eslint的。

这个eslint就是问题所在,如果我们确认我们编写的JS代码语法没问题,然而修改仍然不生效。请先尝试在这个js文件中关闭eslint的检查。
这个做法很简单,加上/* eslint-disable */这个注释就可以了
(我通常加载头部,因为这样可以让eslint 跳过对头部的空变量或者空引用检查)。

查看项目的目录结构和源码,可以知道src/main/index.js下是根据运行/开发环境决定是加载远程的vue页面还是加载本地已经打包好的vue页面。

也就是说我们开发时,如果修改了vue的某个页面/组件,只需要electron刷新或者reload就可以看到修改的效果了。

即使这刷新/reload的动作,vue-electron也不需要你动手,基于node 的 热更新 已经被大神们移植为到electron上面了,因此,当我们修改web页面,我们并不需要重启整个项目,跟在node上开发vue的流程是一样的。这也是我使用vue-electron的愿景之一。

而src/main/index.js 是运行在electron 主进程中的,这与vue+node采取的热更新开发不同,他的开发类似于热部署。对主进程的每次修改都要重启整个electron。

因此eslint的语法检查所引发的错误可能会中断整个打包js的过程。electron的启动后很有可能因为文件不完整而导致加载不起来,或者加载的仍是上一个打包成功的主进程的js文件。

因此,关闭eslint 可能会给予我们一个更好的开发体验。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.