vue + electron 实战,实现桌面端应用开发。(electron 中使用 vue、vue 中使用 electron)。项目实战是仿网易云音乐桌面端进行开发。
这个项目是我跟着官方文档的那个入门教程大致跑了一遍,了解了下流程之后就自己实战的项目(大概跟着打了小半天代码),所以中间应该是会有很多写法不是很规范,安全性有可能也没考虑到,可实现的各种api也不是很了解,所以只适合和我类似刚接触的萌新小白,至于为什么要写这篇文章,是因为在我跟着官网那个入门教程做完后,打算看视频跟着写写项目,发现网上完整的教程实在是太少了(主要是有点老了),虽然开源项目很多(但是我真心理解的不太容易)。看了github上面的项目,发现有网易云音乐的一个有接口的项目,觉得很适合自己练手,同类的开源项目也很多,所以打算记录下,就按这个可用的接口进行仿写一下,欢迎萌新大家一起研究。
必须感谢 https://github.com/Binaryify/NeteaseCloudMusicApi 作者大大提供的API,给上satr,这个项目直接拉下来跑在本地就是一个后台啦,很感谢!
使用文档:https://binaryify.github.io/NeteaseCloudMusicApi/#/
基本每天搬砖完会更新一点,进度会有点缓慢(并不会和当前的网易云音乐界面完全一样,因为会考虑到部分接口没有,所以会有略微调整,基本就是看能实现的功能进行实现,不能实现的功能就不实现了,反正对接口的调用就是业务逻辑,实现部分就差不多了)。
(本项目主要是记录electron的使用,所以对于html+js+css只会描述关键部分,如果有不懂的或者不知道怎么实现的建议是把代码拉取下来自己对应查看)
vue create electron-vue-cloud-music
cd electron-vue-cloud-music
npm run serve
npm config set registry=https://registry.npmmirror.com
npm config set disturl=https://registry.npmmirror.com/-/binary/node
npm config set electron_mirror=https://registry.npmmirror.com/-/binary/electron/
防止在打包的时候或者下载的时候由于网络原因失败。
使用 vue-cli-plugin-electron-builder 插件实现vue和electron的使用。
安装插件:
vue add electron-builder
我这里选择13版本。
出现 Successfully 表示安装成功。
可以看到主入口文件是 background.js ,运行命令是 electron:serve, 打包命令是 electron:build
npm run electron:serve
如果出现扩展失败,并不断尝试,请先等待4次,稍后项目会正常运行。
项目正常运行:
打开入口文件 background.js 文件,找到刚刚扩展失败的代码:
可以看到是由于在开发环境的时候 vue 的 devtools 工具安装失败导致,我这边直接注释这部分代码(主要是我也没研究怎么解决,暂时用不到,不然每次启动项目都要等待扩展有点浪费时间)
npm run electron:build
耐心等待,只要安装了我上面的镜像应该是没问题,出现 Build complete 表示打包成功。
可以看到打包完成的目录:dist_electron
点击.exe文件就可以安装,然后正常运行,这里是测试,后面会等项目最后进行讲更加具体的项目打包。
对于这部分的菜单栏需要隐藏,虽然这里有缩小、放大、关闭按钮,但是需要自定义菜单栏的话还是自己写吧(我这里是直接用vue组件实现的,如果electron这个框架有对这部分可以自定义的话麻烦也告知一下)
可以看到通过 frame:false 现在隐藏了标题栏,并且我还设置了窗口的最小宽度和高度,对于控制台的显示也做了控制,只有在开发环境下才能打开控制台,生产环境下不能打开。
控制台快捷键:Ctrl + Shift + I
标题栏样式差不多如下,先实现右上角缩小、放大、关闭按钮功能。 结构目录如下: 可以看到我是直接把各个页面放在App.vue文件里面了,想封装的自己封装,我这只为了实现功能和熟悉框架。 views目录下面的 TitleBar.vue 表示的是 标题栏的功能页面, SideBar.vue 表示的是侧边栏的功能页面, BottomBar.vue 表示的是底部播放栏的功能页面。这里我先把基本的结构给搭好,后面基本就是存业务操作,和electron相关的会重点记录下。
部分功能可能后面会再优化和实现,先实现放大、缩小、关闭按钮功能。
在渲染进程中引入ipcRenderer,注意这个时候需要安装个插件 node-polyfill-webpack-plugin 。 这是由于在webpack5中移除了nodejs核心模块的polyfill自动引入,所以需要手动引入。如果是用webpack4的小伙伴应该是不需要安装的,应该不会报错。
npm install node-polyfill-webpack-plugin
在vue.conifg.js中进行配置: 在 main.js 中引入 ipcRenderer: 注意在主入口 background.js 文件中要把node使用开启: 这样就引入成功了,如果有别的报错可能是别的原因。 ps:这里我是直接在渲染进程中就引入ipcRenderer,按照官方教程考虑安全性应该使用预加载脚本创建一个preload.js然后通过 contextBridge.exposeInMainWorld 抛出ipcRenderer的功能,但是这个方法我按照网上教程失败了,有了解的小伙伴可以告诉我下应该把preload.js文件放在哪里,我之前是放在public 目录下,但是没有生效,后面也没有继续尝试(后面我会继续研究下,除去安全性,确实进程间通信还是放在一个文件中好管理一下)。
因为渲染进程和主进程之间是隔离的,所以现在在渲染进程中的点击事件我需要通过ipcRenderer传递给主进程,在主进程中完成功能。 在 TitleBar.vue 文件下设置点击事件:
<i class="iconfont icon-suoxiao1" @click="minimizeClick" title="最小化"></i>
<i v-show="isMaximize" class="iconfont icon-fangda1" @click="maximizeClick" title="最大化"></i>
<i v-show="!isMaximize" class="iconfont icon-suoxiao" @click="maximizeClick" title="向下还原"></i>
<i class="iconfont icon-guanbi1" @click="closeAppClick" title="关闭"></i>
methods: {
// 最小化
minimizeClick() {
window.ipcRenderer.send('minimize-window');
},
// 最大化
maximizeClick() {
window.ipcRenderer.send('maximize-window')
this.isMaximize = !this.isMaximize
},
// 关闭
closeAppClick() {
window.ipcRenderer.send('close-app');
}
}
通过ipcRenderer.send()把点击事件发送给主进程监听。
在 background.js 文件中进行监听事件的发生,并进行事件的处理:
import { app, protocol, BrowserWindow, ipcMain } from 'electron'
// 最小化
ipcMain.on('minimize-window', () => {
const win = BrowserWindow.getFocusedWindow();
if (win) {
win.minimize();
}
})
// 最大化
ipcMain.on('maximize-window', () => {
const win = BrowserWindow.getFocusedWindow();
if (win) {
if (win.isMaximized()) {
win.unmaximize(); // 如果窗口已经最大化,则还原窗口大小
} else {
win.maximize(); // 否则最大化窗口
}
}
})
// 关闭
ipcMain.on('close-app', () => {
app.exit()
})
引入ipcMain,并通过ipcMain.on进行监听事件,然后进行事件处理。 这样就实现了应用放大、缩小、关闭的效果。
先安装aioxs:
npm install axios
这边是本地跑后端环境,对vue.config.js中的代理服务器设置我就不开了,直接设定环境变量使用公共的url。
.env.development表示开发环境的配置。 设置公共请求头(请根据自己的实际后端端口号,默认把后端项目拉下来应该是3000端口):
# 接口公共部分
VUE_APP_BASE_URL = 'http://localhost:9080'
.env.production 表示生产环境的配置。 设置公共请求头(请根据自己的实际后端端口号,默认把后端项目拉下来应该是3000端口):
# 接口公共部分
VUE_APP_BASE_URL = 'http://localhost:9080'
安装 js-cookie 用于存储token。
npm install js-cookie
在src/utils 文件下创建 auth.js 用于封装 cookie的相关使用:
import Cookies from "js-cookie";
const TokenKey = 'token'
// 获取token
export function getToken () {
return Cookies.get(TokenKey)
}
// 设置token
export function setToken (token) {
return Cookies.set(TokenKey, token)
}
// 移除token
export function removeToken () {
return Cookies.remove(TokenKey)
}
这里是用来做消息弹框。
npm install element-plus --save
在 src/utils 文件下新建 request.js 文件,用于封装axios。这里具体的封装方式就不具体写出来了,有兴趣自己看 request.js 文件。(主要是这个文件应该会不断改动,所以现在我也还不确定最后是怎么样)
封装完 axios 后在 src 下创建一个api文件,用于存储接口请求。
思路: 1.1.在views文件下面创建路由页面,对应左边侧边栏的页面; 1.2.在router.js文件中写入页面路由。
修改 views文件下的 SideBar.vue 文件样式,最终实现效果如下所示: 根据上面步骤创建的路由页面,实现点击的时候切换不同的页面,并设置样式。现在基本结构搭建好了,接下来就逐步写各个页面的接口和页面功能,丰富这个应用。
发现音乐页面还有6个子页面。如下所示: 所以要对路由和页面进行调整,思路: 1.给原本的/faxian路由后面添加上这6个子路由页面: 2.在/views/faxian文件下面创建一个children文件,用于存放子路由页面。
{
path: '/faxian',
name: 'faxian',
title: '发现音乐',
redirect: '/tuijian',
component: FaXian,
children: [{
path: '/tuijian',
title: '个性推荐',
component: () => import('../views/faxian/children/tuijian.vue')
},{
path: '/playList',
title: '歌单',
component: () => import('../views/faxian/children/playlist.vue')
},{
path: '/dj',
title: '主播电台',
component: () => import('../views/faxian/children/dj.vue')
},{
path: '/rank',
title: '排行榜',
component: () => import('../views/faxian/children/rank.vue')
},{
path: '/artist',
title: '歌手',
component: () => import('../views/faxian/children/artist.vue')
},{
path: '/newSong',
title: '最新音乐',
component: () => import('../views/faxian/children/newSong.vue')
}]
},
注意:把原本的/faxian路由页面现在重定向到/tuijian路由页面,确保点击“发现音乐”的时候“个性推荐”能自动显示。
在/views/faxian文件下面创建children文件,用于存储子路由页面。
安装 vue-lazyload 插件实现图片懒加载。
$ npm i vue-lazyload -S
网站:
https://github.com/hilongjw/vue-lazyload/tree/next
剩下的页面就是实现发现的各个子页面(这部分就是css 和 html 没有什么逻辑比较简单就直接放上效果图,在实现的过程中发现有的接口参数可能不能用了,建议还是自己实际修改下,或者不调用)
**实现效果图: **
个性推荐:
歌单:
主播电台:
排行榜:
最新音乐:
这些页面点进入的歌单现在还没有实现,还有和播放关联的部分,后面再去实现功能。并且 歌手
应该也是 发现音乐
的子页面,但是实现的时候好像有BUG,就暂时放侧边栏了。
歌手页面原本是在发现音乐页面的子页面中的,现在单独放在侧边栏,所以调整下路由结构和文件结构。
功能思路: 底边栏一般具有喜欢、列表循环、上一首/下一首、播放/暂停、显示/隐藏歌词、声音控制、播放列表。 这边主要就是播放列表的实现,把播放列表通过vuex进行全局管理。
样式效果如下所示:
现在基本的样式就已经完成了,剩下的就是实现功能。
基本思路: 因为这边播放的歌曲是任何页面都会相关联的,所以把当前播放的歌曲就直接放在vuex中进行管理,把歌单也是直接放在vuex中进行管理。
2023/06/26:后面这个项目不打算继续了写下去了,基本就是纯业务操作,花费时间有点大,所以打算暂停了,之后有时间再写吧。