简体   繁体   中英

Synchronize variable between router in vue.js

I'd like to change value of a variable in a router-view by changing other variable in different routre-view synchronously. I wrote code like below to change variable isFoo in header and catch it in side bar, but it fails.

App.vue:

<template>
  <v-app id="app">
    <router-view name="sidebar"></router-view>
    <router-view name="header"></router-view>
    <router-view name="main"></router-view>
    <router-view name="footer"></router-view>
  </v-app>
</template>
<script>
export default {
  name: 'app',
  isFoo: false
}
</script>

and Sidebar.vue:

<template>
  <div id="sidebar" :isOpen="isFoo"></div>
</template>
<script>
  export default {
    name: 'sidebar',
    data () {
      return {isFoo: this.$parent.$options.isFoo}
    }
  }
</script>

Header.vue:

<template>
  <button v-on:click="foo()">Button</button>
</template>
<script>
export default {
  name: 'header',
  methods: {
    foo: () => {
      this.$parent.$options.isFoo = !this.$parent.$options.isFoo
    }
  }
}
</script>

Your question is essentially about how to share state across multiple components of your app, and is quite general.

Your code does not work because you have copied isFoo across your components instead of just referencing a single source of truth for that data. Also you should specify reactive data in the data property of each component, not directly within the $options of the component.

I've fixed your code to make it work:

 const Header = { template: '<button @click="$parent.isFoo = true">Click Me</button>' } const Sidebar = { template: '<div>Sidebar: {{ $parent.isFoo }}</div>' } const router = new VueRouter({ routes: [ { path: '/', components: { header: Header, sidebar: Sidebar } } ] }) new Vue({ router, el: '#app', data: { isFoo: false } }) 
 <script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script> <script src="https://rawgit.com/vuejs/vue-router/dev/dist/vue-router.js"></script> <div id="app"> <router-view name="header"></router-view> <router-view name="sidebar"></router-view> </div> 

However I do not recommend this approach. You really shouldn't be accessing this.$parent because it tightly couples the components.

I'm not going to go into detail about better ways of doing this because there are lots of SO questions which cover this topic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM