vue2-qewd-hello-world

This is a basic example Vue.js version 2.x app using a QEWD-Up/QEWD.js back-end. It uses the standard @vue/cli build tools. The example assumes you have a QEWD-Up/QEWD.js back-end server running on http://localhost:8090.

Generate your app skeleton

vue create vue2-qewd-hello-world

Choose the Vue.js 2.x defaults when asked for

Project setup

npm install
# add qewd-client module to enable WebSocket connection in QEWD-Up/QEWD.js interactive apps
npm install qewd-client

File changes to a fresh Vue.js 2.x app skeleton to integrate with QEWD-Up/QEWD.js interactive apps (using WebSockets)

Notice that with the new qewd-client module version, the vue-qewd plugin module isn't needed anymore. You can still use it if you need to use the legacy ewd-client module.

  • in src/main.js:
import Vue from 'vue'
import App from './App.vue'

// import QEWD from the qewd-client
import { QEWD } from 'qewd-client'

// add QEWD as a global property
// now you can use QEWD in all your app components as `this.$qewd.reply(...)`
Vue.prototype.$qewd = QEWD

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
  • in src/App.vue:
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <!-- show your app's main component when QEWD's websocket is ready -->
    <HelloWorld v-if="qewdReady" msg="Welcome to Your Vue.js App"/>
    <!-- during startup, show a startup indicator -->
    <h1 v-else>Starting QEWD-Up/QEWD.js ...</h1>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
// import the socket.io client into our App component
import io from 'socket.io-client'

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  data () {
    return {
      // define a reactive property set to true when QEWD's websocket is registered
      qewdReady: false
    }
  },
  created () { 
    let self = this
    /*
      create an event handler invoked when QEWD's connection is registered/ready
    */
    this.$qewd.on('ewd-registered', function() {
      // Your QEWD environment is ready, set the qewdReady data property to true
      self.qewdReady = true
      // optionally turn on logging to the console
      self.$qewd.log = true
    });
    /*
      start QEWD-Up/QEWD.js client with these required params:
      - application: QEWD's application name
      - io: the imported websocket client module
      - url: the url of your QEWD-Up/QEWD.js server (hardcoded in this example,
        the url can be passed in too using a process.env.QEWD_URL parameter)

      *** important: by default, a Vue.js app will run it's development server on localhost:8080 
      (this is the same port as QEWD's default port 8080)
      you'll *need* to change the port to e.g. 8090 in QEWD's config
      to make it work with a Vue.js app!
    */
    this.$qewd.start({
      application: 'hello-world',
      io,
      url: 'http://localhost:8090'
    })
  }
}
</script>
  • in src/components/HelloWorld.vue:
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    ...
    <hr>
    <p>message from QEWD: {{ qewdMessage }}</p>
    <button @click="sendMessage">Send message to QEWD</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {
      // add a reactive property to hold a message coming back from QEWD-Up/QEWD.js
      qewdMessage: ''
    }
  },
  methods: {
    sendMessage() {
      // preserve Vue.js's this for use in QEWD's reply
      let self = this
      // send a test 'hello-world' message to QEWD-Up/QEWD.js
      this.$qewd.reply({
        type: 'hello-world'
      }).then(response => {
        // log QEWD's response on the console
        console.log(response)
        // show an error message in the app
        self.qewdMessage = response.message.error || ''
      }) 
    }
  }
}
</script>

Compiles and hot-reloads for development

npm run serve

Compiles and minifies for production

npm run build

Lints and fixes files

npm run lint

Customize configuration

See Configuration Reference.

Debugging with VSCode

See the recipe at Vue.js debugging in Chrome and VS Code

Remark: for a Vue.js 2.x project, I needed to comment out the devtool: "source-map" statement inside vue.config.js for breakpoints to work correctly. For a Vue.js 3.x project, the source-map statement is needed as described in the recipe.

Deploying to non-root domain url's

In case you deploy your app and/or your QEWD-Up/QEWD.js server to a non-root domain url, you need to configure some parameters.

The QEWD.js server back-end

When you reverse proxy your QEWD-Up/QEWD.js server using Apache, Nginx, ... under a non-root path (e.g. https://mydomain.com/qewd) you need to configure your webserver to reverse proxy QEWD.js's built-in static webserver under this path. Don't forget to add statements to proxy the websocket ws://mydomain.com/qewd and/or wss://mydomain.com/qewd protocol too.

  • for Apache:
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/qewd/?(.*) "ws://qewd-server.local:8090/$1" [P,L]

ProxyPass /qewd http://qewd-server.local:8090
ProxyPassReverse /qewd http://qewd-server.local:8090
  • for Nginx:
http {
  server {
    listen 80;
    server_mame mydomain.com

    location /qewd {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $host;

      proxy_pass http://qewd-server.local:8090;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
  }
}

This setting ensures the socket.io module in the QEWD-Up/QEWD.js server picks up messages from a /qewd path/location too. If you don't set this config option, your websocket messages will be refused with an Invalid namespace /qewd error.

In case the same QEWD-Up/QEWD.js server is reverse proxied behind multiple Apache/Nginx proxy servers simultaneously, you can add multiple io_paths in this array (only in case the proxied path/location is different on the proxy servers). E.g. if you have one Apache server using the path/location /qewd1 and another using the path/location /qewd2, the setting becomes:

{
  "qewd": {
    ...
    "webSockets": {
      "io_paths": ["/qewd1","/qewd2"]
    }
  },
  ...
}

Important note: make sure you install/upgrade your qewd module v2.51.7 or later in your QEWD-Up/QEWD.js server setup using npm install qewd for this feature to work!

Vue.js web apps

The QEWD-Up/QEWD.js client start parameters

To start the QEWD-Up/QEWD.js connection successfully using the qewd-client module, you need to tell the module where your QEWD-Up/QEWD.js back-end server lives:

this.$qewd.start({
  application: 'hello-world',
  io,
  url: 'http://mydomain.com/qewd',
  io_path: '/qewd'
})

Notice both url and io_path need to contain the url subpath /qewd.

Deploy your app to a non-root url using Vue's publicPath setting

When you build your app and deploy it to a non-root url, you need to tell @vue/cli where your app will be deployed in the vue.config.js file using the publicPath setting:

module.exports = {
  publicPath: '/vue',
  configureWebpack: {
    //devtool: "source-map"
  }
};

During development, you need to adjust the url setting in your launch.json config in VSCode to point to this public path:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "vuejs: chrome",
      "url": "http://localhost:8080/vue",
      "webRoot": "${workspaceFolder}",
      "breakOnLoad": true,
      "pathMapping": {
        "/_karma_webpack_": "${workspaceFolder}"
      },
      "sourceMapPathOverrides": {
        "webpack:/*": "${webRoot}/*",
        "/./*": "${webRoot}/*",
        "/src/*": "${webRoot}/*",
        "/*": "*",
        "/./~/*": "${webRoot}/node_modules/*"
      },
      "preLaunchTask": "vuejs: start"
    }
  ]
}

The tasks.json with the vuejs: start pre-launch task:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "vuejs: start",
      "type": "npm",
      "script": "serve",
      "isBackground": true
    }
  ]
}