12

So currently I am working with VueJS 2 and I am very new with it. Now I was getting some help with some other people, but I am still stuck.

Here is what I want to achieve (example - closely linked to what I want):

  1. I have a NodeJS application that listens on WebSockets. The application listens for connections via WebSocket and will take JSON data, with a command and then a data object with any content needed for that command.

The command for example could be login, and the data be username and password. The login function on the NodeJS application will then take this data, do what it needs and then return it back over the socket, whether it was successful or not, and maybe include an ID and some user information for Vuex to pickup and place in it's state, for the front-end of the application to pick up/use.

Currently I am using this boiler plate: https://github.com/SimulatedGREG/electron-vue

Which has served me very well as a learning curve, due to me wanting to use Vue and Vuex to manage my application and then use WebSockets for managing data to and from the data server.

So if you look at the link I sent in app/src/renderer/ (this is where the main code is for vue and vuex).

A friend of mine added the following code for me as an example and I am stuck trying to get it into vuex as actions and mutations. He made it all in one vue component, so I am struggling on how it works with vuex. As I want to be able to access the (example) loginUser action from anywhere in the application (uses routes for multiple pages/views).

So in the MyApp/app/src/renderer/components/LandingPageView.vue

<template>
  <div>
    <img src="./LandingPageView/assets/logo.png" alt="electron-vue">
    <h1>Welcome.</h1>
    <current-page></current-page>
    <websocket-output></websocket-output>
    <versions></versions>
    <links></links>
  </div>
</template>

<script>
  import CurrentPage from './LandingPageView/CurrentPage'
  import Links from './LandingPageView/Links'
  import Versions from './LandingPageView/Versions'
  import WebsocketOutput from './LandingPageView/WebsocketOutput'
  export default {
    components: {
      CurrentPage,
      Links,
      Versions,
      WebsocketOutput
    },
    name: 'landing-page'
  }
</script>

<style scoped>
  img {
    margin-top: -25px;
    width: 450px;
  }
</style>

That is the updated file for that, and then below is the code for the MyApp/app/src/renderer/components/LandingPageView/WebsocketOutput.vue

<template>
  <div>
    <h2>Socket output:</h2>
    <p v-text="socket_out"></p>
  </div>
</template>

<script>
  var ws = require("nodejs-websocket")

  export default {
    data () {
      return {
        socket_out: "connecting to the websocket server..."
      }
    },
    mounted () {
      const parent = this
      var connection = ws.connect("ws://dannysmc.com:9999", {}, function (conn) {})
      connection.on("text", function (text) {
        console.log('Text received: ' + text)
        parent.socket_out = text
      })
      connection.on("connect", function () {
        connection.send('yo')
      })
    },
    created () {
      // Set $route values that are not preset during unit testing
      if (process.env.NODE_ENV === 'testing') {
        this.$route = {
          name: 'websocket-output',
          path: '/websocket-output'
        }
      }
    }
  }
</script>

<style scoped>
  code {
    background-color: rgba(46, 56, 76, .5);
    border-radius: 3px;
    color: #fff;
    font-weight: bold;
    padding: 3px 6px;
    margin: 0 3px;
    vertical-align: bottom;
  }

  p {
    line-height: 24px;
    color: red;
  }
</style>

Everything else is just the boiler plate that you see, so if anyone is willing to help me and give me some tips of what to read that explains this or anything else? as I can't find much information on it unfortunately.

Dahknee
  • 591
  • 3
  • 12
  • 28
  • Why not just set up your socket outside any of your single file components, and when you receive data, dispatch an action to Vuex. If you're components are then set up properly they should render the new state. – Bert Jun 02 '17 at 17:26
  • So would I set up the socket say on load, then when events occur from the socket, require the store and do `store.dispatch()`? – Dahknee Jun 02 '17 at 19:21
  • I don't use Vuex, but I have an electron app that uses websockets and yes essentially, in my renderer script I create the websocket, require the store, and set up events in my websocket such that they call the store directly. Vue will just render changes when the store changes. – Bert Jun 02 '17 at 19:23
  • @BertEvans Oh I didn't know it was that simple! Thank you; will give it a go. – Dahknee Jun 02 '17 at 19:29

1 Answers1

17

I have an electron application that uses Vue and a websocket for information and here is how I set mine up.

I have a store defined that also actually creates and sets up the websocket.

Store.js

const socket = require("socket-library") // Take your pick of socket libs

const mySocket = new socket(...)
mySocket.on("message", message => store.handleMessage(message))
...other handlers...

const store = {
    handleMessage(message){
        // do things with the message
    }
}

export default store

Renderer.js

import store from "./store"

new Vue({
    data:{
        store
    }
})

This exposes my store at the root level of my Vue and allows me to pass data to components, or what have you. The store manages all the incoming information from the websocket.

With you wanting to use Vuex, you could do essentially the same thing, where Vuex would be your store and when messages come in over the socket, you just pass them to Vuex.

mySocket.on("message", msg => vuexStore.dispatch("onSocketMessage", msg))

and set up your Vue and components to work with Vuex as you typically would.

Bert
  • 80,741
  • 17
  • 199
  • 164
  • Thanks for this! I have used this to build my own, this is a lot easier than what I had in mind. – Dahknee Jun 05 '17 at 09:07
  • 7
    there is also a websocket plugin example in the vuex docs: https://vuex.vuejs.org/en/plugins.html#committing-mutations-inside-plugins – Jörn Mar 12 '18 at 10:01
  • This appears to be much easier to understand than the official Vuex plugin example though. How would using a plugin improve things? – Charlie Jan 21 '19 at 14:27
  • Has the websocket API changed? The new methods seem to be `.onopen` and `onmessage`: https://developer.mozilla.org/de/docs/Web/API/WebSocket – Ulli Apr 15 '21 at 04:13
  • Also, in Vuex I think (and it says so in @Jörn 's example) it's better to use mutations instead of actions, in the normal case that you want to mutate the state without further async operations on the websocket data. – Ulli Apr 15 '21 at 04:13
  • 1
    @Jörn sadly the example provided does not make clear where the socket object should come from. When trying to use the native WebSocket API in the store.js file to instantiate it, I'm getting "WebSocket is not defined". Installing the ws npm package does not make sense, as it does not work in the browser. – Marian Klühspies Sep 18 '21 at 13:46