Gavin
Gavin

Reputation: 2834

Vue sharing state between sibling components

I probably do not want to use vuex for state management yet as it is probably overkill for now. I took a look at https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication. I am using single file component so I am not sure where do I define the shared bus such that both components will have reference to it.

var bus = new Vue()

ChildA.Vue

watch: {
  sideNav: (newValue) => {
    bus.$emit('sideNav-changed', newValue)
  }
}

ChildB.Vue

created () {
  bus.$on('sideNav-changed', data => {
    console.log(`received new value: ${data}`)
    // update own copy here
  })
}

Parent.Vue

<template>
  <childA>
  </childA>
  <childB>
  </childB>
</template>

I want to watch any changes of sideNav on ChildA and emit it to ChildB to update its own value.

Upvotes: 2

Views: 1319

Answers (3)

Rwd
Rwd

Reputation: 35200

The simplest way to do this would be to just attach it to the window i.e.

window.bus = new Vue()

Then it will be available in all of your components without the need to define a global mixin e.g. this will still work:

watch: {
  sideNav(newValue) {
    bus.$emit('sideNav-changed', newValue)
  }
}

Upvotes: 0

bbsimonbb
bbsimonbb

Reputation: 29020

Is this answer any good to you? You can do everything with events, but if you can avoid them, you should. You might not want vuex for now. That's where I am. But you want, right from the start, a store in global scope and reactive pipes. You "declare" the relationship between an element on the page and an item in the store, then basta. Vue takes care of the rest. You don't care about events.

Upvotes: 0

Gavin
Gavin

Reputation: 2834

Found the answer to it...

I declare it on the main.js

const bus = new Vue() // Single event hub

// Distribute to components using global mixin
Vue.mixin({
  data: function () {
    return {
      bus : bus 
    }
  }
})

And also change

watch: {
  sideNav: (newValue) => {
    bus.$emit('sideNav-changed', newValue)
  }
}

to

watch: {
  sideNav: function (newValue) {
    bus.$emit('sideNav-changed', newValue)
  }
}

Upvotes: 1

Related Questions