Electron選擇文件、文件夾對話框(非原創,傳播)

文章轉載自:https://www.jianshu.com/p/e71...,感謝文章做者,成功完成選擇文件夾 的功能html

1.第一種方法,純js代碼
其原理是:利用input標籤的file類別,打開選擇文件對話框經過input標籤的change事件,將選擇的文件返回。爲了使每次選擇的文件都獲得更新,在input對象用完後每次都移除出html中,下次使用時再從新建立並添加到html中。代碼以下:
/**
         *按鈕事件實現函數
         *原理:利用input標籤的file類別,打開選擇文件對話框
         *經過change事件,將選擇的文件返回。爲了使每次選擇的文件都獲得更新,
         *在input對象用完後每次都移除出html中,下次使用時再從新建立並添加到html中
         */
        btnClickFun:function(dir){
            // 建立input標籤
            var inputObj=document.createElement('input')
                // 設置屬性
                inputObj.setAttribute('id','_ef');
                inputObj.setAttribute('type','file');
                inputObj.setAttribute("style",'visibility:hidden');
                if(dir){ // 若是要選擇路徑,則添加如下兩個屬性
                    inputObj.setAttribute('webkitdirectory', "");
                    inputObj.setAttribute('directory', "");
                }
                // 添加到DOM中
                document.body.appendChild(inputObj);
                // 添加事件監聽器
                inputObj.addEventListener("change",this.updatePath);
                // 模擬點擊
                inputObj.click();
        },
        // 打開文件選擇器input標籤的change事件響應
        updatePath:function(){
            var inputObj = document.getElementById("_ef");
            var files = inputObj.files;
            console.log(files)
            try{
                if(files.length > 1){
                    alert('當前僅支持選擇一個文件')
                }
                else{
                    switch(this.btntype){
                        case 'store':
                            // 臨時變量的值賦給輸出路徑
                            this.outpath = files[0].path;
                            break;
                        case 'add':
                            // 添加文件操做
                            this.filepath = files[0].path;
                            if(this.addFile(this.filepath)){
                                alert("添加成功")
                            }
                            break;
                            default:
                            break;
                    }
                }
                // 移除事件監聽器
                inputObj.removeEventListener("change",function(){});
                // 從DOM中移除input
                document.body.removeChild(inputObj);
            }catch (error) {
                alert(error)
            }
        },
btnClickFun函數中建立並設置了input標籤屬性及監聽器,函數updatePath爲change事件監聽的回調函數。經過input標籤對象的files屬性得到選中的文件名。2.第二種方法,electron首先在子進程中引入ipcRenderer模塊,import {ipcRenderer} from 'electron'利用該模塊向主進程發送「open-directory-dialog」消息,配置參數爲「openDirectory」或「openFile」,而且設置主進程返回的消息「selectedItem」的回調函數爲getPath,
// 按鈕點擊事件
        btnClick:function(type){
           this.btntype = type;
            // 判斷點擊事件是哪一個按鈕發出的
            switch(type){
                case 'store':
                // 選擇存貯路徑
                    //
this.btnClickFun(true);
                    ipcRenderer.send('open-directory-dialog','openDirectory');
                    ipcRenderer.on('selectedItem',this.getPath);
                    break;
                case 'add':
                // 添加文件
                    //
this.btnClickFun(false);
                    ipcRenderer.send('open-directory-dialog','openFile');
                    ipcRenderer.on('selectedItem',this.getPath);
                    break;
                case 'remove':
                    this.deleteItem();
                    break;
                case 'pack':
                    break;
                    default:
                    break;
            }
        },
        getPath:function(e,path){
            console.log(path)
            if(path == null){
                    alert('請選擇一個文件/文件夾')
            }
            else{
                switch(this.btntype){
                    case 'store':
                        // 臨時變量的值賦給輸出路徑
                        this.outpath = path;
                        break;
                    case 'add':
                        // 添加文件操做
                        this.filepath = path;
                        if(this.addFile(this.filepath)){
                            alert("添加成功")
                        }
                        break;
                        default:
                        break;
                }
            }
        },
而後在主進程中設置好子進程的消息監聽,而且引入dialog模塊import { dialog } from 'electron'
// 綁定打開對話框事件
ipcMain.on('open-directory-dialog', function (event,p) {
  dialog.showOpenDialog({
    properties: [p]
  },function (files) {
      if (files){// 若是有選中
        // 發送選擇的對象給子進程
        event.sender.send('selectedItem', files[0])
      }
  })
});
這樣就能夠完成選擇文件/文件夾的操做了。3.第一種方法實現的vue組件純JS實現的文件選擇器,須要操做DOM原理:利用input標籤的file類別,打開選擇文件對話框經過change事件,將選擇的文件返回。爲了使每次選擇的文件都獲得更新,在input對象用完後每次都移除出html中,下次使用時再從新建立並添加到html中默認打開文件夾,若是須要選擇文件,則須要在調用處配置屬性dir='file'屬性caption顯示按鈕的文本信息成功調用後會向父進程發送一個‘btnSelectItem’消息用於返回選中的文件全路徑vue

這其中參考了vue官方文檔《將原生事件綁定到組件》章節,解決父組件調用時子組件按鈕不響應的問題。將原生事件綁定到組件
你可能有不少次想要在一個組件的根元素上直接監聽一個原生事件。這時,你能夠使用v-on 的 .native 修飾符:web

在有的時候這是頗有用的,不過在你嘗試監聽一個相似  的很是特定的元素時,這並非個好主意。好比上述  組件可能作了以下重構,因此根元素其實是一個  元素:app

  {{ label }}electron

這時,父級的 .native 監聽器將靜默失敗。它不會產生任何報錯,可是 onFocus 處理函數不會如你預期地被調用。
爲了解決這個問題,Vue 提供了一個 $listeners 屬性,它是一個對象,裏面包含了做用在這個組件上的全部監聽器。例如:
{
  focus:
function (event) { / ... / }
  input:
function (value) { / ... / },
}
有了這個 $listeners 屬性,你就能夠配合 v-on="$listeners" 將全部的事件監聽器指向這個組件的某個特定的子元素。對於相似  的你但願它也能夠配合 v-model 工做的組件來講,爲這些監聽器建立一個相似下述 inputListeners 的計算屬性一般是很是有用的:
Vue.component('base-input', {
  inheritAttrs:
false,
  props: [
'label', 'value'],
  computed: {
    inputListeners:
function () {函數

var vm = thisthis

// Object.assign 將全部的對象合併爲一個新對象code

return Object.assign({},component

// 咱們從父級添加全部的監聽器htm

this.$listeners,

// 而後咱們添加自定義監聽器,

// 或覆寫一些監聽器的行爲
        {

// 這裏確保組件配合 v-model 的工做
          input:
function (event) {
            vm.$emit(
'input', event.target.value)
          }
        }
      )
    }
  },
  template:
          {{ label }}           
})
如今  組件是一個徹底透明的包裹器了,也就是說它能夠徹底像一個普通的 元素同樣使用了:全部跟它相同的特性和監聽器的均可以工做。

4.第二種方法實現的vue組件Electron的ipcRenderer模塊實現的選擇文件器默認打開文件夾,若是須要選擇文件,則須要在調用處配置屬性dir='file'屬性caption顯示按鈕的文本信息成功調用後會向父進程發送一個‘btnSelectItem’消息用於返回選中的文件全路徑

相關文章
相關標籤/搜索