前言
这个项目是我跟着官方文档的那个Electron入门教程大致跑了一遍,了解了下Electron开发流程之后的实战项目,所以中间应该是会有很多写法不是很规范,安全性有可能也没考虑到,可实现的各种api也不是很了解,适合初学者。
必须感谢 https://github.com/Binaryify/NeteaseCloudMusicApi 作者大大提供的API,给上satr,这个项目直接拉下来跑在本地就是一个后台啦,很感谢!
使用文档:https://binaryify.github.io/NeteaseCloudMusicApi/#/
一、创建vue项目
1.用vue-cli创建vue项目
vue create electron-vue-cloud-music
2.查看项目是否正常运行
cd electron-vue-cloud-music
npm run serve
3.设置electron的镜像
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/
防止在打包的时候或者下载的时候由于网络原因失败。
4.安装electron环境
使用 vue-cli-plugin-electron-builder 插件实现vue和electron的使用。
安装插件:
vue add electron-builder
我这里选择13版本。
出现 Successfully 表示安装成功。
5.查看运行命令
可以看到主入口文件是 background.js ,运行命令是 electron:serve, 打包命令是 electron:build
6.测试命令是否成功
6.1运行项目
npm run electron:serve
如果出现扩展失败,并不断尝试,请先等待4次,稍后项目会正常运行。
项目正常运行:
打开入口文件 background.js 文件,找到刚刚扩展失败的代码:
可以看到是由于在开发环境的时候 vue 的 devtools 工具安装失败导致,我这边直接注释这部分代码(主要是我也没研究怎么解决,暂时用不到,不然每次启动项目都要等待扩展有点浪费时间)
6.2打包项目
npm run electron:build
耐心等待,只要安装了我上面的镜像应该是没问题,出现 Build complete 表示打包成功。
可以看到打包完成的目录:dist_electron
点击.exe文件就可以安装,然后正常运行,这里是测试,后面会等项目最后进行讲更加具体的项目打包。
二、实现标题栏
1.隐藏标题栏
对于这部分的菜单栏需要隐藏,虽然这里有缩小、放大、关闭按钮,但是需要自定义菜单栏的话还是自己写吧(我这里是直接用vue组件实现的,如果electron这个框架有对这部分可以自定义的话麻烦也告知一下)
可以看到通过 frame:false 现在隐藏了标题栏,并且我还设置了窗口的最小宽度和高度,对于控制台的显示也做了控制,只有在开发环境下才能打开控制台,生产环境下不能打开。
控制台快捷键:Ctrl + Shift + I
2.实现标题栏样式
标题栏样式差不多如下,先实现右上角缩小、放大、关闭按钮功能。
结构目录如下:
可以看到我是直接把各个页面放在App.vue文件里面了,想封装的自己封装,我这只为了实现功能和熟悉框架。
views目录下面的 TitleBar.vue 表示的是 标题栏的功能页面, SideBar.vue 表示的是侧边栏的功能页面, BottomBar.vue 表示的是底部播放栏的功能页面。这里我先把基本的结构给搭好,后面基本就是存业务操作,和electron相关的会重点记录下。
3.实现放大、缩小、关闭
部分功能可能后面会再优化和实现,先实现放大、缩小、关闭按钮功能。
3.1引入ipcRenderer
在渲染进程中引入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 目录下,但是没有生效,后面也没有继续尝试(后面我会继续研究下,除去安全性,确实进程间通信还是放在一个文件中好管理一下)。
3.2点击按钮进程间通信实现
因为渲染进程和主进程之间是隔离的,所以现在在渲染进程中的点击事件我需要通过ipcRenderer传递给主进程,在主进程中完成功能。
在 TitleBar.vue 文件下设置点击事件:
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进行监听事件,然后进行事件处理。
这样就实现了应用放大、缩小、关闭的效果。
三、封装axios请求
1.安装axios
先安装aioxs:
npm install axios
2.创建公共请求头
这边是本地跑后端环境,对vue.config.js中的代理服务器设置我就不开了,直接设定环境变量使用公共的url。
2.1创建.env.development文件
.env.development表示开发环境的配置。
设置公共请求头(请根据自己的实际后端端口号,默认把后端项目拉下来应该是3000端口):
# 接口公共部分
VUE_APP_BASE_URL = 'http://localhost:9080'
2.2创建.env.production文件
.env.production 表示生产环境的配置。
设置公共请求头(请根据自己的实际后端端口号,默认把后端项目拉下来应该是3000端口):
# 接口公共部分
VUE_APP_BASE_URL = 'http://localhost:9080'
3.安装js-cookie
3.1安装
安装 js-cookie 用于存储token。
npm install js-cookie
3.2封装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)
}
4.安装element-plus
这里是用来做消息弹框。
npm install element-plus --save
5.封装axios
在 src/utils 文件下新建 request.js 文件,用于封装axios。这里具体的封装方式就不具体写出来了,有兴趣自己看 request.js 文件。(主要是这个文件应该会不断改动,所以现在我也还不确定最后是怎么样)
6.创建api文件
封装完 axios 后在 src 下创建一个api文件,用于存储接口请求。
四、实现侧边栏
1.创建路由页面
思路:
1.1.在views文件下面创建路由页面,对应左边侧边栏的页面;
1.2.在router.js文件中写入页面路由。
2.实现侧边栏样式
修改 views文件下的 SideBar.vue 文件样式,最终实现效果如下所示:
根据上面步骤创建的路由页面,实现点击的时候切换不同的页面,并设置样式。现在基本结构搭建好了,接下来就逐步写各个页面的接口和页面功能,丰富这个应用。
五、实现发现音乐
发现音乐页面还有6个子页面。如下所示:
所以要对路由和页面进行调整,思路:
1.给原本的/faxian路由后面添加上这6个子路由页面:
2.在/views/faxian文件下面创建一个children文件,用于存放子路由页面。
1.给/faxian添加子路由
{
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路由页面,确保点击“发现音乐”的时候“个性推荐”能自动显示。
2.创建子路由页面
在/views/faxian文件下面创建children文件,用于存储子路由页面。
3.实现页面
安装 vue-lazyload 插件实现图片懒加载。
$ npm i vue-lazyload -S
网站:
https://github.com/hilongjw/vue-lazyload/tree/next
剩下的页面就是实现发现的各个子页面(这部分就是css 和 html 没有什么逻辑比较简单就直接放上效果图,在实现的过程中发现有的接口参数可能不能用了,建议还是自己实际修改下,或者不调用)
实现效果图:
个性推荐:
歌单:
主播电台:
排行榜:
最新音乐:
这些页面点进入的歌单现在还没有实现,还有和播放关联的部分,后面再去实现功能。并且 歌手
应该也是 发现音乐
的子页面,但是实现的时候好像有BUG,就暂时放侧边栏了。
六、实现歌手页面
歌手页面原本是在发现音乐页面的子页面中的,现在单独放在侧边栏,所以调整下路由结构和文件结构。
创建歌手页面文件
添加路由
实现页面
七、创建底边栏播放音乐
功能思路:
底边栏一般具有喜欢、列表循环、上一首/下一首、播放/暂停、显示/隐藏歌词、声音控制、播放列表。
这边主要就是播放列表的实现,把播放列表通过vuex进行全局管理。
css样式实现
样式效果如下所示:
现在基本的样式就已经完成了,剩下的就是实现功能。
功能实现
基本思路:
因为这边播放的歌曲是任何页面都会相关联的,所以把当前播放的歌曲就直接放在vuex中进行管理,把歌单也是直接放在vuex中进行管理。