1

I'm trying to use Electron's ipcRenderer inside my Vue sigle file component to populate some data. It easy enough to call out with a ipcRenderer.send(...) but on the reply I want to update each instance of my component with the response message. I think the comment in ipcRenderer.on(...) explains my issue the best. Is there a good way to do this. I'm completely new to JS.

<template>
  <v-container fluid>
    <v-btn @click="do_action()">{{title}}</v-btn>
    <v-textarea v-model="response_message">
    </v-textarea>
  </v-container>
</template>

<script>
  const { ipcRenderer } = require('electron')

  export default {
    props: ['title'],
    data: function(){
      return {
        response_message: "Original Message"
      }
    },
    methods: {
      do_action: function() {
        ipcRenderer.send('cmnd_foo')
      }
    },
  }

  ipcRenderer.on('cmnd_foo-reply', (event, a_new_message) => {
    // obviously this.response_message isn't in scope...
    // how can I get this intent to work
    this.response_message = a_new_message
  })
</script>
JeffCharter
  • 1,431
  • 17
  • 27
  • [Something like this, perhaps?](https://github.com/SimulatedGREG/electron-vue/issues/249#issuecomment-306568724) - I'm not too familiar with Electron, so take it with a grain of salt.. *Edit* - looks like you need to use/instantiate `ipcRendere.on..` within your `main.js file`...? – Matt Oestreich Jun 07 '19 at 19:01

3 Answers3

1

-- Update --

Use a vuex store or something like.

-- Original --

I seem to have found a way to do it. Maybe there is still a better way?

<template>
  <v-container fluid>
    <v-btn @click="do_action()">{{title}}</v-btn>
    <v-textarea v-model="response_message">
    </v-textarea>
  </v-container>
</template>

<script>
  const { ipcRenderer } = require('electron')

  var catcher = 0;
  function setMessage(msg) {
    this.response_message = msg
  }

  export default {
    props: ['title'],
    data: function(){
      return {
        response_message: "Original Message"
      }
    },
    methods: {
      do_action: function() {
        catcher = setMessage.bind(this)
        ipcRenderer.send('cmnd_foo')
      }
    },
  }

  ipcRenderer.on('cmnd_foo-reply', (event, a_new_message) => {
    catcher(a_new_message);
  })
</script>
JeffCharter
  • 1,431
  • 17
  • 27
  • You could call bind directly in the function, if you registerr the ipcRenderer in a lifecycle hook, like mounted `mounted: function(){ ipcRenderer.on('event', function (){ do something }.bind(this)) }` – Antonio Pet Dec 01 '19 at 16:50
  • 1
    Found a similar solution as Antonio suggested: https://memorytin.com/2018/07/26/electronjs-vue-js-setting-up-ipcrenderer-event-handlers/ – Chen Feb 19 '20 at 15:14
  • I did eventually scrap this method of doing things and now rely on a vuex store. So instead of `ipcRenderer.on` I set something in the vuex store and watch that property. I don't recommend doing the way in this answer unless you just quickly want to get something working. – JeffCharter Feb 19 '20 at 15:27
0

You can apply the solution described on this post How to import ipcRenderer in vue.js ? __dirname is not defined

Just make sure you configure preload.js on vue.config.js:

// vue.config.js - project root
module.exports = {
  pluginOptions: {
    electronBuilder: {
       preload: 'src/preload.js'  //make sure you have this line added
    }
  }
}

Another solution can be found here https://medium.com/swlh/how-to-safely-set-up-an-electron-app-with-vue-and-webpack-556fb491b83 and it use __static to refer to preload file instead of configure it on vue.config.js. To make it work you can disable preload es-lint warning inside of BrowserWindow constructor:

// eslint-disable-next-line no-undef
preload: path.resolve(__static, 'preload.js')

And make sure you added preload.js file on /public folder

rafalimaz
  • 70
  • 10
-2

Just add remote at the end:

const { ipcRenderer } = require('electron').remote
Michael H.
  • 3,323
  • 2
  • 23
  • 31
abdo
  • 16
  • what does the .remote do? – JeffCharter Jun 10 '19 at 13:27
  • it's defines an instance of electron that work in the renderer : i don't know how to explain that but : for main process use : require('electron') and for renderer use : require('electron').remote – abdo Sep 27 '19 at 08:12