Electron+Vue实现连接本地mysql(思路-简单实现)

5,338 阅读2分钟

效果展示:

屏幕录制 2021-08-19 时间 13.00.46.gif

实现原理:

  • electron基于原生node可以与本地的数据库相连接
  • electron通过ipc通信机制,可以让主进程与渲染进程进行通信
  • 通过通信机制进行数据传递在页面控制台打印

实现步骤

  1. 通过脚手架生成基础的vue框架代码,生成基本项目
$ yarn create vite <project-name> --template vue
$ cd <project-name>
$ yarn
$ yarn dev

具体安装教程,请访问vue的官网:v3.cn.vuejs.org/guide/insta…

  1. 进入项目工程安装electron和mysql工具
$ yarn add electron 
$ yarn add mysql
// 如果用到ts的话建议安装
$ yarn add -D @types/mysql
  1. 在根目录下创建一个目录electron和一个入口的index.js文件

  2. 在electron下创建一个utils目录,编写一个工具类sql.js,作为mysql的连接工具

const mysql = require('mysql');
const pool = mysql.createPool({
    host: '域名或IP',
    port: "端口",
    user: '账号',
    password: '密码',
    database: '数据库名字'
});
//导出查询相关  
var query=function(sql,callback){  
      
    pool.getConnection(function(err,conn){
        if(err){    
            callback(err,null,null);    
        }else{    
            conn.query(sql,function(qerr,vals,fields){    
                //释放连接    
                // conn.release();    
                pool.releaseConnection(conn);
                //事件驱动回调    
                callback(qerr,vals,fields);    
            });    
        }    
    });    
};
//向外暴露方法
module.exports = {
    pool,
    query
}
  1. 编写入口index.js文件
// electron基础引入
const { app, BrowserWindow } = require('electron')
// 创建electron窗体函数
function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences:{
      // 在vue里面要引入electron里面的内容需要用到这俩
      nodeIntegration:true,
      contextIsolation: false
    }
  })
  // 在electron页面中打开调试工具
  win.webContents.openDevTools()
  // 连接到Vue页面
  win.loadURL("http://localhost:3000")
}
// 初始化窗体
app.whenReady().then(() => {
  createWindow()
})

具体可以参考electron的官方文档www.electronjs.org/docs/tutori…

  1. package.json添加一个可执行脚本
"main":"./index.js", // 根据你指定的index.js文件的位置进行配置
"scripts": {
    "dev": "vite",
    "build": "vite build",
    "serve": "vite preview",
    "electron": "electron ." // 主要是这个
},
  1. 启动两个终端,分别执行两个命令
$ yarn dev // 一个终端启动这个(这个优先启动)
$ yarn electron // 另一个终端启动这个

就能看到这个 image.png 即表示基础环境配置成功

  1. 实现业务部分
// index.js
// 引入添加ipcMain(通信主进程)
const { app, BrowserWindow,ipcMain } = require('electron')
// 引入mysql工具类
const conn = require('./electron/utils/sql');

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences:{
      // 在vue里面要引入electron里面的内容需要用到这俩
      nodeIntegration:true,
      contextIsolation: false
    }
  })
  win.webContents.openDevTools()
  win.loadURL("http://localhost:3000")
}
app.whenReady().then(() => {
  createWindow()
})
// 添加一个进程时间监听,监听来自send的事件
ipcMain.on('send',(event, arg) => {
  console.log('connect mysql sql:',arg)  // prints "sql"
  // 接收一个args 此处args是一条sql语句
  conn.query(arg,(qerr,vals,fields)=>{
   // 通过conn.query进行查询,查询结果是vals
   // 发起消息回调事件,发起reply,将vals传递回去
    event.sender.send('reply', vals);
  })
});

// HelloWorld.vue
<template>
  <h1>{{ msg }}</h1>
  <p>
    <a href="https://vitejs.dev/guide/features.html" target="_blank">
      Vite Documentation
    </a>
    |
    <a href="https://v3.vuejs.org/" target="_blank">Vue 3 Documentation</a>
  </p>

  <button type="button" @click="test()"> // 将默认的点击事件改成test()
    count is: {{ state.count }}
  </button>
  <p v-for="item in state.data" v-bind:key="item.id">{{item.subtitle}}</p>
  <p>
    Edit
    <code>components/HelloWorld.vue</code> to test hot module replacement.
  </p>
</template>
<script setup>
import { defineProps, reactive } from 'vue'
// 从 electron 引入 ipcRenderer
// 此处有个点要注意 不能直接用require,要用window.require 
// 而且需要在index.js的webPreferences部分添加下面两个才行
// nodeIntegration:true,
// contextIsolation: false
const { ipcRenderer} = window.require('electron');
defineProps({
  msg: String
})
const state = reactive({ count: 0,data:[] })
// 实现一个test()的方法
function test(){
  if(state.data.length>0){
    state.data=[]
    state.count = 0
  }else{
    // 通过ipcRenderer.send发起一个send请求,将sql语句作为args传递过去
    ipcRenderer.send('send','select * from t_banner');
    // 渲染进程监听reply
    ipcRenderer.on('reply',(event,args)=>{
        // 获取的args就是sql中查询出来的数据
      state.count=args.length
      console.log(args)
    })
  }
}
</script>
<style scoped>
a {
  color: #42b983;
}
</style>

最终重新运行两个终端的两个命令,就能达到顶部图片的效果

总结

上次有人问了这个问题,我就蛮去尝试了一下,仅仅只是作为一个实现的思路,也算是个人一个学习的一个记录。欢迎大家有什么想法都可以讨论。

我是觉得有了这个,是不是以后的毕业设计什么图书管理系统就能更简单了~~ 哈哈哈