1

I have a Vue instance where I want to make accessible to all components some

  • methods
  • objects

I wrote this:

import mqtt from 'mqtt'

new Vue({
  el: '#app',
  methods: {
    foo: function() {
      console.log("Hello Foo!");
    }
    mqtt: mqtt.connect('mqtt://server:8083')
  },
  render: h => h(App), 
  router
});

Unfortunately, in my components I cannot reach either foo nor mqtt.

<template>

</template>
<script>

export default {
  data() {
    return {};
  },
  mounted() {
    this.foo(); // Doesn't work
    this.mqtt.on('connect', () => {}) // Doesn't work
  }
}
</script>

What's wrong?

2
  • What is the function toto? Commented Nov 29, 2018 at 13:33
  • My mistake, it was foo Commented Nov 29, 2018 at 13:34

1 Answer 1

4

To distribute pure functions (without side effects) you can use mixins.

const mixin = {
    methods:{
        foo() {
            console.log('foo')
        }
    }
}

Then you can define the mixin in the vue instance:

new Vue({
    mixins: [mixin],
    // ...
})

This function can now be used in every component as if it where defined there.

Your mqtt connection is quite another story. You are sharing the result of mqtt.connect. This function does not return a function, so it cannot be shared via methods. Furthermore: This function creates state. A good way to share state is Vuex. With Vuex you can share state across multiple components and define mutations.

Define a store in src/store/index.js:

const store = new Vuex.Store({
  state: {
    connected: false,
    result: null
  },
  mutations: {
    setMqtt (state, mqttResult) {
      state.connected = true
      state.result = mqttResult
    }
  }
})

Add it to your app:

import store from './store'

new Vue({
  el: '#app',
  mixins: [mixin],
  store,
  // ....
})

Now you can access this store in each component, with:

this.$store.state.connected
this.$store.state.result

The access should only be done in functions that are defined in computed. As soon as any change occurs in the state, all functions defined in computed are evaluated again.

Now you can fetch the data in your main file and commit the result:

mqtt.connect('mqtt://server:8083').on('connect', (someData) => {
    store.commit('setMqtt', someData)
})

Links to the official docs:

https://v2.vuejs.org/v2/guide/mixins.html

https://vuex.vuejs.org/

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for your answer. I am starting the implementation but still, I am far away from using this mounted() {this.foo(); } in my components.
I guess the solution would be to add the mixins to every components I use or, better, inherit from a component that implements this mixins. Is that correct?
You can inject it as a global mixin: vuejs.org/v2/guide/mixins.html#Global-Mixin
Right, but I cannot call the methods from my global mixins into my sub-components. Remember I would like to do mounted() {this.foo(); } from any component of my application.
Why not? This should be possible. Also, you could define mounted in the mixin.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.