前面关于electron
打包可安装程序的准备工作已经基本完成了,除了Mac os
下没有环境,暂时无法测试打包情况,但是package.json
中既然支持Mac os
的打包,那就应该问题不大。
完成了前面的准备工作,现在终于开始着手开发的心心念念vue
。之前是获取到exe
文件返回的数据,需要根据返回信息来告诉用户启动成功或者失败。就需要将获取的信息通过message
组件,notification
组件等组件给出提示信息。
由于之前用惯了react+antd
的开发,所以索性在vue
项目中也使用antd
来做页面呈现,毕竟我比较喜欢马爸爸。话不多说,言归正传。
感兴趣的可以研究ant design of vue
根据官网给出的使用方式,很快便搞起来了
在main.js
中可以这么定义
import Antd, { notification } from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
// use Element UI component
Vue.use(Antd)
Vue.use(notification)
Vue.prototype.$notification = notification
然后在App.vue
中直接拿来使用
import { ipcRenderer } from "electron";
export default {
name: "egent",
data() {
return {
result: "",
};
},
created() {
console.log("初始化项目");
ipcRenderer.on("asynchronous-message", function (event, result) {
if (result && result.type === "err") {
this.$notification.error({
message: "Notification Title",
description: result.msg,
});
} else if (result && result.type === "success") {
this.$notification.success({
message: "Notification Title",
description: result.msg,
});
}
});
},
};
按照这么配置,不出意外的话就会出现成功信息。
看一下控制台,好家伙,真的是期望越高失望越大
。
好像发现了什么。熟悉的undefined
…
为什么会出现undefined
呢?我明明将$notification
绑定到Vue
的原型链上,讲道理应该是没有问题的。但是,它好像是不讲道理…
出现这种错误的原因就是没有定义的东西,你直接拿来用了
。那究竟是什么没有定义呢。
通过debug
模式,发现this.$message
确实是undefined
。而我又明明绑定了,那问题就只可能出现在this
上。
在使用this
的时候,我们经常会碰到很多指向的问题,也会伴随着很多undefined
,所以我们不妨先打印一下,看看这个this
到底是和何方神圣。
这…,虽然我不知道这是什么,但我知道这一定不是Vue
,可以看到_events
这个东西,里面全是ELECTRON
的东西,那这个this
应该是指向Electron
。
结论:
在electron-vue
架构中,vue
的web
项目会在外层包裹一层,导致此时的this
并不指向当前的vue
,而是指向窗口,导致我们通过prototype
注册的事件无法被使用。
那这种问题怎么解决呢?
既然this
指向的是外层窗口,那简单的办法应该是直接使用Vue.prototype.xxx
的方式去调用组件,因为我们在main.js
中就是通过prototype
去注册的,直接拿来用是没有什么问题的。
main.js
中的定义
import Antd, { notification } from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
// use Element UI component
Vue.use(Antd)
Vue.use(notification)
Vue.prototype.$notification = notification
App.vue
中使用
<script>
import { ipcRenderer } from "electron";
import Vue from 'vue'
export default {
name: "egent",
data() {
return {
result: "",
};
},
created() {
console.log("初始化项目");
ipcRenderer.on("asynchronous-message", function (event, result) {
if (result && result.type === "err") {
Vue.prototype.$notification.error({
message: "Notification Title",
description: result.msg,
});
} else if (result && result.type === "success") {
Vue.prototype.$notification.success({
message: "Notification Title",
description: result.msg,
});
}
});
},
};
</script>
每一次在vue文件中都需要引入
Vue
,否则会出现Vue未定义
,这简直是个灾难性的东西
vue
文件中单独引用组件另外一种解决办法就是需要在用到这种message
,notifacation
等类似的组件,需要在js代码块
中使用的地方,需要将该组件单独引入即可。
main.js
文件中删除关于notification
的代码
App.vue
中引入notification
<script>
import { ipcRenderer } from "electron";
import { notification } from 'ant-design-vue'
export default {
name: "egent",
data() {
return {
result: "",
};
},
created() {
console.log("初始化项目");
ipcRenderer.on("asynchronous-message", function (event, result) {
if (result && result.type === "err") {
notification.error({
message: "Notification Title",
description: result.msg,
});
} else if (result && result.type === "success") {
notification.success({
message: "Notification Title",
description: result.msg,
});
}
});
},
};
</script>
我觉得以上的两种方式都不太好,会引入过多的依赖组件,最关键的是this
这个东西就没法在vue
中正常使用,除非我们去改变this指向
,将其从窗口
指向vue
以便我们去更好的使用this
。
在这期间我还碰到一个问题,想把返回的是展示在页面上,而不是以通知的形式告知用户。然而,我在data
中定义了变量,并且在created
也可以打印出这个值,但是无论是通过{{}}
还是通过v-model
或者v-bind
的形式,都无法显示新赋予的值。
现在看来是能解释的通为什么值没有成功展示了,因为this指向了窗口,而我们通过this.xxx = value的时候,其实是绑定到窗口上了,我不是绑定到vue中,这就导致无法变更我们的视图
。
当前剩余的问题应该是
- 是不是能通过
改变this指向
的方式去做呢?如果能实现,那么就会像平常使用vue
一样,轻松自如了。关于这块,目前还在研究。- 如果能改变
this
指向,那么就需要在窗口
和vue
中来回切换。既然官方给出的指向是窗口,那么肯定会有它自己的用法,如果在用到的时候,就需要切换到窗口方式。这么切换会不会出现什么问题?