vue-electron

先來講一個 vue-electron 的報錯

C:\Users\user\Desktop\dome\my-im\node_modules\_electron-localshortcut@3.2.0@electron-localshortcut\index.js:20
                } catch {
  SyntaxError: Unexpected token {
      at createScript (vm.js:80:10)
      at Object.runInThisContext (vm.js:139:10)
      at Module._compile (module.js:606:28)
      at Object.Module._extensions..js (module.js:653:10)
      at Module.load (module.js:561:32)
      at tryModuleLoad (module.js:504:12)
      at Function.Module._load (module.js:496:3)
      at Module.require (module.js:586:17)
      at require (internal/module.js:11:18)
      at eval (webpack:///external_%22electron-localshortcut%22?:1:18)
//這個錯誤是由於electron-localshortcut 升級致使的,降級到electron-localshortcut@3.0.0便可 
複製代碼

前言注意

<!-- 一、組件內,打開外部連接 -->
<script> this.$electron.shell.openExternal(link) </script>
<!-- 引入CSS -->
<style> @import url('https://www.baidu.com/index.css') </style>
複製代碼

全局安裝

npm install -g electron

npm install -g electron-forge
複製代碼

建立 項目

electron-forge init my-app
複製代碼

運行 項目

npm start
複製代碼

結合vue建立項目

vue cerate app
vue add vue-cli-plugin-electron-builder

//啓動
yarn electron:serve
//打包
yarn electron:build
複製代碼

主進程

import { app, BrowserWindow, Menu} from 'electron'

/** * Set `__static` path to static files in production * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html */
if (process.env.NODE_ENV !== 'development') {
  global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}

let mainWindow
const winURL = process.env.NODE_ENV === 'development'
  ? `http://localhost:9080`
  : `file://${__dirname}/index.html`

function createWindow () {
  /** * Initial window options */
  mainWindow = new BrowserWindow({
    height: 763,
    useContentSize: true,
    fullscreenable: true,  //是否容許全屏
    width: 1200,
    frame: true,   //是否顯示 菜單欄
    center: true ,  //是否在屏幕中間顯示
    title: '雲筆記',
    titleBarStyle: 'hidden',
    webPreferences: {
      backgroundThrottling: false // 當頁面被置於非激活窗口的時候是否中止動畫和計時器
    }
    
  })

  mainWindow.loadURL(winURL)

  mainWindow.on('closed', () => {
    mainWindow = null
  })

  // 開啓渲染進程中的調試模式
  mainWindow.webContents.openDevTools()
}
// 當electron完成初始化後觸發
app.on('ready', createWindow)


//全部窗口都關閉的時候觸發,在windows和linux裏,全部窗口都退出的時候一般是應用退出的時候
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

//
app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})

複製代碼

小試牛刀——讀取本地文件

const fs = require('fs')
export default {
    methods:{
        btn:function(){
            //這裏的路徑 爲根路徑
            fs.readFile('package.json',(err,data)=>{
                console.log(data)   
                this.$refs.texts.innerHTML=data
            })
        }
    }
}
複製代碼

開啓初始化的調試模式

// 開啓渲染進程中的調試模式
  mainWindow.webContents.openDevTools()
複製代碼

拖拽

<div v-on:drop.prevent="drop" v-on:dragenter="dragenter" v-on:dragover="dragenter" v-on:dragleave="dragenter" class="box" id="box" >
</div>
   
<script> const fs = require('fs') export default { methods:{ dragenter:function(){ return false; }, drop:function(e){ console.log(e) } } } </script>
複製代碼

隱藏菜單

//隱藏 頂部 菜單
  mainWindow.setMenu(null)
複製代碼

去掉頂部 最大化、最下化

mainWindow = new BrowserWindow({
    height: 763,
    useContentSize: true,
    fullscreen: false,  //是否容許全屏
    width: 1200,
    frame: false,   //是否顯示 菜單欄 最大化、最小化
    center: true ,  //是否在屏幕中間顯示
    title: '雲筆記',
    titleBarStyle: 'hidden',
    webPreferences: {
      backgroundThrottling: false // 當頁面被置於非激活窗口的時候是否中止動畫和計時器
    }
    
  })
複製代碼

能夠拖動 的CSS

.box{
	webkit-app-region: drag
}
複製代碼

自定義 最小化、最大化、關閉

min:function(){
           this.$electron.ipcRenderer.send('window-min') 

        /*** * 獲取mainWindow(既:win) BrowserWindow.getFocusedWindow() * 在主進程 執行操做 * var {ipcMain,BrowserWindow} = require('election') * ipcMain.on('window-min',()=>{ * 最大化 win.maximize() * 最小化 win.minimize() * 恢復 win.restore() * 關閉 win.close() * * 最大化 和 恢復原狀的判斷 * if(win.isMaximized()){ * win.restore() //還原 * }else{ * win.maximize() //最大化 * } * * }) * * */   
        },
        max:function(){
             this.$electron.ipcRenderer.send('window-max') 
        },
        close:function(){
             this.$electron.ipcRenderer.send('window-close') 
        }
複製代碼

註冊全局快捷鍵

const {app,globalShortcut,BrowserWindow} = require('electron')
let win=BrowserWindow.getFocusedWindow();

app.on('ready',function(){
    // 註冊快捷鍵
    globalShortcut.register('ctrl+e',function(){
       // win.hide();
       console.log('123')
    })
    // 檢測註冊是否成功
    let glos=globalShortcut.isRegistered('ctrl+e')
    console.log(glos)
})

app.on('will-quit',function(){
    // 取消 全局快捷鍵
    globalShortcut.unregister('ctrl+e')
})
複製代碼

註冊剪切板

// 複製
clipboard.writeText('機器碼')
複製代碼

webview

//和應用運行的是不一樣的進程,無渲染進程
<webview src='http://www.baidu.com'></webview>
複製代碼

通知 window.Notification

//通知 採用的是H5的 通知API

// 通知
let options={
    title: '通知',
    body: '你有新短消息,請注意查收',
    // icon: path.join('../static/imgs/app2.ico')
}

let defaults=window.Notification.permission
// "denied" --- 爲用戶點擊了禁用(拒絕打開推送功能)

// "default" ----推送功能默認關閉

// "granted" ----推送功能爲開啓狀態(用戶點擊容許後的狀態)


console.log(defaults)


var myNotification= new Notification(options.title,options);

myNotification.onclick=function(){
    console.log('點擊了')
}

let bons =document.getElementById('bons')
//點擊之後 發佈通知
bons.onclick=function(){
    console.log('123')
    let myNotifications= new window.Notification(options.title,options);
    console.log(myNotifications)
    //點擊通知欄的事件
        myNotifications.onclick=function(){
            console.log('點擊了')
        }
}


// 監聽 網絡變化,最好在APP.vue 的mounted函數中
window.addEventListener('online',function(){
    console.log('有網絡')
})
window.addEventListener("offline",function(){
    console.log('網絡斷開')
})

複製代碼

實踐

<body>
		<button id="btn">按鈕</button>
	</body>

<script> let btn=document.getElementById('btn') let options={ title: '通知', body: '你有新短消息,請注意查收' } btn.onclick=function(){ //console.log('123') let notifications=null if (!window.Notification) { alert("瀏覽器不支持通知!"); } if(window.Notification.permission != 'granted'){ window.Notification.requestPermission(function(stauts){ console.log(stauts) if(stauts=='granted'){ notifications=new window.Notification(options.title,options); }else{ alert('您爲容許開啓消息通知,將接收不到 本站的消息推送') } }) } notifications=new window.Notification(options.title,options); //推送窗口 關閉時 notifications.onclose=function(){ } //推送窗口顯示時 notifications.onshow=function(){ } } </script>
複製代碼

dialog 窗口提示和打開、保存文件

<template>
<!-- 雲筆記 主頁 -->
    <div class="notebook">
        <button v-on:click="btn">點擊l</button>
        <webview id="webs" src='http://www.bbaidu.com'></webview>

        <button v-on:click="btna">錯誤提示</button>
        <button v-on:click="btnb">選擇提示</button>
        <button v-on:click="btnc">打開文件</button>
        <button v-on:click="btnd">另存爲</button>
    </div>
</template>

<script> //  const {shell,ipcRenderer,remote} = require('electron') export default { methods:{ btn:function(){ console.log('123') shell.openExternal('https://www.baidu.com/') }, btna:function(){ remote.dialog.showErrorBox('錯誤提示','錯誤了') }, btnb:function(){ remote.dialog.showMessageBox({ title: '提示信息', message: '內容', type: 'info', buttons: ['肯定','取消'] },function(index){ //index 爲buttons的索引 console.log(index) }) }, btnc:function(){ //打開文件 remote.dialog.showOpenDialog({ properties:['openFile'] },function(data){ //可使用 node.js讀取文件內容 console.log(data) }) /*** * properties: openFile 只容許選擇文件 * openDirectory 只容許選擇文件夾 * * * */ }, btnd:function(){ //保存文件 remote.dialog.showSaveDialog({ title: 'save file', //保存窗口的 title defaultPath: 'abs.gif',//默認路徑 filters:[ { name: 'Images', extensions:['jpg','png','gif'] }, { name: 'Movies', extensions:['mkv','avi','mp4'] }, { name: 'Custom File Type', extensions:['as'] }, { name: 'All Files', extensions:['*'] } ] },function(data){ //保存之後,返回保存路徑,可是 沒有真正保存文件,須要node.js保存文件 console.log(data) }) } }, mounted:function(){ console.log('hhahha') ipcRenderer.on('webs',function(event,data){ // 在軟件內部 打開外部網頁 let webs=document.getElementById('webs') webs.src=data }) } } </script>
複製代碼

shell模塊

//在外部瀏覽器打開鏈接地址,也能夠打開本地目錄
<template>
<!-- 雲筆記 主頁 -->
    <div class="notebook">
        <button v-on:click="btn">點擊l</button>
    </div>
</template>

<script>

// 
const {shell} = require('electron')

export default {
    methods:{
        btn:function(){
            console.log('123')  //打開外部瀏覽器
            this.$electron.shell.openExternal('https://www.baidu.com/')
            
        }
    }
}
</script>
複製代碼

在頁面嵌套頁面,相似iframe

<webview src='https://www.baidu.com/'></webview>
複製代碼

主進程:ipcMain,渲染進程:ipcRenderer 通信

/** * 一、ipcMain :在主進程中使用,他處理從渲染進程發送出來的異步消息,和同步消息 * 固然也有可能處理從主進程向渲染進程發送消息 * 二、ipcRenderer: 使用它提供的一些方法從渲染進程 發送同步或異步消息到主進程, * 也能夠接收主進程的回覆消息 */ 
//主進程主動給渲染進程廣播數據
var win= BrowserWindow.getFocusedWindow()
win.webContents.send('opens',data)
複製代碼

渲染進程 向主進程 發送數據

// 渲染進程
<template>
<!-- 雲筆記 主頁 -->
    <div class="notebook">
        <button v-on:click="btn">點擊</button>
    </div>
</template>

<script> const fs = require('fs') // 讓渲染進程 給主進程發消息 const {ipcRenderer} = require('electron') export default { methods:{ btn:function(){ // console.log('123') //渲染進程給主進程廣播數據 ipcRenderer.send('sendM','this is home') } } } </script>

<scripr>
//  主進程
import { ipcMain} from 'electron'

ipcMain.on('sendM',function(event,data){
    console.log(data)
})
/*  在下面生命週期中執行
* 當electron完成初始化後觸發
*   app.on('ready', createWindow)
*/
</scripr>
複製代碼

渲染進程 向主進程 發送數據,並返回處理結果給渲染進程

<template>
<!-- 雲筆記 主頁 -->
    <div class="notebook">
        <button v-on:click="btn">點擊</button>
    </div>
</template>

<script> const fs = require('fs') // 讓渲染進程 給主進程發消息,主進程 返回處理結果給渲染 const {ipcRenderer} = require('electron') export default { methods:{ btn:function(){ // console.log('123') //渲染進程給主進程廣播數據 ipcRenderer.send('sendM','this is home') } }, mounted:function(){ ipcRenderer.on('replay',(event,data)=>{ console.log(data) }) } } </script>

<!-- 主進程 -->
<script> import { ipcMain} from 'electron' //接收 渲染進程數據,而且返回處理數據 ipcMain.on('sendM',function(event,data){ //console.log(data) // 返回處理結果 event.sender.send('replay','ok hello') }) </script>
複製代碼

同步廣播

<template>
<!-- 雲筆記 主頁 -->
    <div class="notebook">
        <button v-on:click="btn">點擊</button>
    </div>
</template>

<script> const fs = require('fs') // 讓渲染進程 給主進程發消息,主進程 返回處理結果給渲染 const {ipcRenderer} = require('electron') export default { methods:{ btn:function(){ // console.log('123') //渲染進程給主進程廣播數據(同步模式) let src=ipcRenderer.sendSync('sendM','this is home') console.log(src) } }, mounted:function(){ } } </script>

<!-- 主進程 -->
<script> import { ipcMain} from 'electron' //接收 渲染進程數據,而且返回處理數據(同步) ipcMain.on('sendM',function(event,data){ //console.log(data) // 返回處理結果 event.returnValue='this is sync main' }) </script>
複製代碼

實例

// 在渲染進程,通信到主進程 打開新窗口
import { ipcMain, BrowserWindow} from 'electron'
var win;

//接收 渲染進程數據,而且返回處理數據
ipcMain.on('sendM',function(event,data){
    //console.log(data)
    // 返回處理結果
   // event.returnValue='this is sync main'

    win= new BrowserWindow({
        width:300,
        height: 400
    })
    win.loadURL('https://www.baidu.com/')
    win.webContents.openDevTools()
    win.on('closed',()=>{
        win=null
    })
})
複製代碼

渲染進程 與 渲染進程 單項通信

/* * 一、首先 第一個渲染進程 發送數據 到主進程, * 二、主進程 保存 第一個渲染進程,並打開新的渲染進程 * 三、 傳遞數據 和 第一個 渲染進程 到新的渲染進程 * 四、 新的 渲染進程 拿到 第一個 渲染進程 後 發送數據 給第一個渲染進程 * */


// 首先 接收到 前一個頁面傳遞的數據,並打開新的 頁面,再把數據發送到 新頁面

import { ipcMain, BrowserWindow} from 'electron'
var win;

//接收 渲染進程數據,而且返回處理數據
ipcMain.on('sendM',function(event,data){
    //console.log(data)
    // 返回處理結果
   // event.returnValue='this is sync main'

    win= new BrowserWindow({
        width:300,
        height: 400
    })
    win.loadURL('https://www.baidu.com/')
    win.webContents.openDevTools()
    
    //在頁面渲染完成之後傳遞數據
    win.webContents.on('did-finish-load',function(){
        win.webContents.send('Load','ha ha hehe')
    })

    win.on('closed',()=>{
        win=null
    })
})
複製代碼
//新頁面接收數據
 ipcRenderer.on('Load',function(event,data){
                console.log(data)
    })
複製代碼

渲染進程 與渲染 進程 相互通信

ipcMain.on('sendM',function(event,data){
    // 保存 發送數據的窗口
    var winId = BrowserWindow.getFocusedWindow().id

    win= new BrowserWindow({
        width:300,
        height: 400
    })
    win.loadURL('https://www.baidu.com/')
    win.webContents.openDevTools()

    //在頁面渲染完成之後傳遞數據, 並把 winId 傳遞過去
    win.webContents.on('did-finish-load',function(){
        win.webContents.send('Load','ha ha hehe',winId)
    })

    win.on('closed',()=>{
        win=null
    })
})
複製代碼
const fs = require('fs')

// 讓渲染進程 給主進程發消息,主進程 返回處理結果給渲染
const {ipcRenderer} = require('electron')
const BrowserWindow =require('electron').remote.BrowserWindow
export default {
  
    mounted:function(evemt,data,winId){
        // 獲取上一個窗口的winId
         let firstWinid=  BrowserWindow.fromId(winId)
        // 向上一個窗口發送消息
        firstWinid.webContents.send('toIndex', 'this is news');
    }
}
複製代碼

Tray 模塊

let {app,Menu,Tray,shell,ipcMain,BrowserWindow} = require('electron');
// 托盤圖標設置
// console.log(__dirname)
var iconTray=new Tray(path.join(__dirname,'../static/imgs/app2.png'));

// 綁定托盤的右鍵菜單
var tpl=[
    {
        label: '設置',
        click:function(){
            console.log('123')
        }
    },
    {
        label: '退出',
        click:function(){
            console.log('123')
        }
    }
]

let rightIcon=Menu.buildFromTemplate(tpl)

iconTray.setContextMenu(rightIcon)

// 托盤圖標 提示文字
iconTray.setToolTip('雲應用')

// 點擊關閉按鈕,讓應該保存在托盤裏,雙擊托盤,打開應用
let win=BrowserWindow.getFocusedWindow();
// console.log(win)

win.on('close',(e)=>{
    /**** * 如 是點擊 托盤的 退出,須要直接退出, * win.isFocused() //判斷窗口 當前是否激活顯示 * */
    if(!win.isFocused()){
       win=null
    }else{
         // 阻止窗口關閉
         e.preventDefault();
         // 隱藏窗口
         win.hide();
    }
    
})

// 雙擊 托盤圖標 打開窗口
iconTray.on('double-click',function(){
    win.show()
})


// 閃爍圖標
/*** * 定時器 設置圖標 * iconTray.setImage(path.join(__dirname,'../static/imgs/app1.png')) * */
複製代碼

在渲染進程 打開 另一個 渲染進程,remote模塊

/** *渲染進程,沒法直接調用主進程中的模塊, *可是咱們能夠經過 electron中的remove模塊,間接的調用主進程中的模塊 */
//監聽渲染進程的 某個點擊事件
let BrowserWindow = require('electron').remote.BrowserWindow

let win=null
	win=new BrowserWindow({
    		height: 763,
    		useContentSize: true,
    		fullscreen: true,  //是否容許全屏
    		width: 1200,
    		frame: true,   //是否顯示 菜單欄
    		center: true ,  //是否在屏幕中間顯示
    		title: '雲筆記',
    		titleBarStyle: 'hidden',
		    autoHideMenuBar : true,  //隱藏菜單
    		webPreferences: {
      			backgroundThrottling: false // 當頁面被置於非激活窗口的時候是否中止動畫和計時器
    		}    
  })
//加載頁面
let winURL=path.join("file:",__dirname,'news.html')
mainWindow.loadURL(winURL)

//關閉頁面
mainWindow.on('closed'.()=>{
	win=null
})
複製代碼

自定義 頂部菜單 menu 模塊,在主進程

menus.js
import { Menu} from 'electron'

//定義菜單
let template=[
    {
      label: '文件',  //主菜單
      submenu:[       //子菜單
        {
          label: '新建窗口',
          click:function(){  //綁定事件
              console.log('新建窗口')
          },
          accelerator: 'ctrl+n'  //綁定快捷鍵,PS : 必須 單引號
        },
        {
          type: 'separator'   //分割線
        },
        {
          label: '打開文件',
          accelerator: 'ctrl+x',
          click:()=>{
            console.log('打開文件')
          }
        }
      ]
    },
    {
      label: '編輯',
      submenu:[
        {
          role: 'cut',  //綁定角色(內置)
          label: '剪切'
        },
        {
          rele: 'copy', //綁定角色
          label: '複製'
        }
      ]
    }
  ]


  //註冊菜單
  let m= Menu.buildFromTemplate(template)
  //掛載菜單
  Menu.setApplicationMenu(m)


//須要在主進程中執行
// 當electron完成初始化後觸發
app.on('ready', {
	//建立菜單
  	require('./menu')
})
複製代碼

自定義 頂部菜單 menu模塊,在渲染進程中

const {Menu} = require('electron').remote;

//定義菜單
let template=[
    {
      label: '文件',  //主菜單
      submenu:[       //子菜單
        {
          label: '新建窗口',
          click:function(){  //綁定事件
              console.log('新建窗口')
          },
          accelerator: 'ctrl+n'  //綁定快捷鍵,PS : 必須 單引號
        },
        {
          type: 'separator'   //分割線
        },
        {
          label: '打開文件',
          accelerator: 'ctrl+x',
          click:()=>{
            console.log('打開文件')
          }
        }
      ]
    },
    {
      label: '編輯',
      submenu:[
        {
          role: 'cut',  //綁定角色(內置)
          label: '剪切'
        },
        {
          rele: 'copy', //綁定角色
          label: '複製'
        }
      ]
    }
  ]


  //註冊菜單
  let m= Menu.buildFromTemplate(template)
  //掛載菜單
  Menu.setApplicationMenu(m)


//在須要 引入菜單的 渲染進程中 執行 便可
複製代碼

渲染進程的 右鍵菜單

const remote= require('electron').remote;
const Menu = remote.Menu
//定義菜單
let template=[
    {
      label: '文件',  //主菜單
      submenu:[       //子菜單
        {
          label: '新建窗口',
          click:function(){  //綁定事件
              console.log('新建窗口')
          },
          accelerator: 'ctrl+n'  //綁定快捷鍵,PS : 必須 單引號
        },
        {
          type: 'separator'   //分割線
        },
        {
          label: '打開文件',
          accelerator: 'ctrl+x',
          click:()=>{
            console.log('打開文件')
          }
        }
      ]
    },
    {
      label: '編輯',
      submenu:[
        {
          role: 'cut',  //綁定角色(內置)
          label: '剪切'
        },
        {
          rele: 'copy', //綁定角色
          label: '複製'
        }
      ]
    }
  ]


  //註冊菜單
  let m= Menu.buildFromTemplate(template)
  //掛載菜單
  Menu.setApplicationMenu(m)

  
// 右鍵菜單
window.addEventListener('contextmenu',function(e){
    e.preventDefault()
    m.popup({
        window:remote.getCurrentWindow()
    })
},false)

//remote.getCurrentWindow()//表示獲取當前窗口

複製代碼

主進程 右鍵菜單

//渲染進程 給主進程廣播事件
window.addEventListener('contextmenu',(e)=>{
    <!--this.$electron.ipcRenderder.emit('contextmenu')-->
    //給主進程廣播事件
    this.$electron.ipcRenderer.send('contextmenu');
},false)

//主進程 
//新建 menu.js
const { Menu, ipcMain, BrowserWindow } = require('electron');
//右鍵菜單
const contextMenuTemplate=[
    {
        label: '複製',
        role: 'copy'
    },
    {
        label: '粘貼',
        role: 'paste'
    },
    {
        type: "separstor" //分割線
    },
    {
        label: '其餘功能',
        click:()=>{
            console.log('自定義功能')
        }
    }
]
//建立菜單
const contextMenu = Menu.buildFromTemplate(contextMenuTemplate)

//監聽渲染進程contextmenu事件,顯示菜單
ipcMain.on('contextmenu',function(){
    //獲取當前窗口
    contextMenu.popup(BrowserWindow.getFocusedWindow())
})

//在主進程引入menu.js (ready函數內)
require('./menu.js')
複製代碼

點擊菜單欄 在 軟件內部 或者 外部默認瀏覽器 打開網頁

import { Menu,shell,BrowserWindow} from 'electron'
//定義菜單
let template=[
    {
      label: '加載網頁',
      submenu: [
        {
          label: '優酷',
          click: function(){
            // 在 默認瀏覽器 打開
            shell.openExternal('http://www.baidu.com')
          }
        },
        {
          type: 'separator'
        },
        {
          label: '百度',
          click: function(){

            let win= BrowserWindow.getFocusedWindow();
			//通知 渲染進程 在軟件內 打開特定網頁
                win.webContents.send('webs','http://www.youku.com')
                
          }
        }
      ]
    },
    {
      label: '幫助',
      submenu: [
        {
          label:'關於咱們',
          click:function(){

          }
         
        }
      ]
    }
  ]
複製代碼
<template>
<!-- 雲筆記 主頁 -->
    <div class="notebook">
        <button v-on:click="btn">點擊l</button>
        <webview id="webs" src='http://www.baidu.com'></webview>
    </div>
</template>

<script> const {shell,ipcRenderer} = require('electron') export default { methods:{ btn:function(){ console.log('123') //在外部 默認瀏覽器 打開特定網頁 shell.openExternal('https://www.baidu.com/') } }, mounted:function(){ ipcRenderer.on('webs',function(event,data){ // 在軟件內部 打開外部網頁 let webs=document.getElementById('webs') webs.src=data }) } } </script>
複製代碼
本站公眾號
   歡迎關注本站公眾號,獲取更多信息