【问题标题】:Vuejs Share Data Between ComponentsVuejs 在组件之间共享数据
【发布时间】:2018-01-29 21:46:44
【问题描述】:

我有两个组件:

  • App.vue
  • Sidekick.vue

在我的App.vue 组件中,我有一个我想从Sidekick.vue 访问的属性

App.vue

<template>
  <div id="app">
    <p>{{ myData }}</p>
    <div class="sidebar">
      <router-view/> // our sidekick component is shown here
    </div>
  </div>
</template>

<script>
export default {
  name: 'App',
  data () {
    return {
      myData: 'is just this string'
    }
  }
}
</script>

Sidekick.vue

<template>
  <div class="sidekick">
    {{ myData }}
  </div>
</template>

<script>
export default {
  name: 'Sidekick'
}
</script>

我想从Sidekick.vue 访问myData(在App.vue 中声明)

我尝试通过执行以下操作从Sidekick.vue 中导入App.vue:

Sidekick.vue (错误尝试)

<script>
import App from '@/App'
export default {
  name: 'Sidekick',
  data () {
    return {
      myData: App.myData
    }
  }
}
</script>

我已经阅读了有关道具的信息 - 但只看到了对子/父组件的引用。在我的例子中,Sidekick.vue 显示在App.vue 内的一个 div 中(不确定这是否使它成为一个“孩子”)。我是否需要以某种方式将myData 的访问权限授予&lt;router-view/&gt;?

更新:(显示 App.vue 和 Sidekick.vue 之间的关系

index.js (路由器文件)

import Vue from 'vue'
import Router from 'vue-router'
import Sidekick from '@/components/Sidekick',
import FakeComponent from '@/components/FakeComponent'

Vue.use(Router)

const router = new Router({
  routes: [
    {
      path: '/',
      redirect: '/fakecomponent'
    },
    {
      path: '/sidekick',
      name: 'Sidekick',
      component: Sidekick
    },
    {
      path: '/fakecomponent',
      name: 'FakeComponent',
      component: FakeComponent
    }
  ]
})

export default router

Sidekick.vue 在我们点击 /sidekick 时被渲染

【问题讨论】:

  • "Sidekick.vue 显示在 App.vue 内的 div 中" 你的 Sidekick 用在哪里除了路由视图之外我在 App 的模板上看不到它们,我认为 props 是正确的方式去只是想要更多的上下文:)
  • 随着数据在父子之间共享,您应该考虑使用道具。如果您有多个嵌套组件,并且您在所有组件之间传递相同的 prop 值,或者您试图在子组件之间或在兄弟姐妹之间以反应方式共享数据,您可能需要考虑查看 Vuex。我个人自己不使用 Vuex,但我目前没有处理足够复杂的 Vue 应用程序来保证使用它。由于您似乎正在开发 SPA,因此您可能会发现使用它有一些好处。
  • @Xlee 我已经用“App”和“Sidekick”之间的关系更新了原始问题

标签: javascript vue.js


【解决方案1】:

请记住,经验法则是使用道具以单向流传递数据

道具下降,事件上升。
https://vuejs.org/v2/guide/components.html#Composing-Components

快速解决方案:

在&lt;App/&gt; 和&lt;Sidekick/&gt; 组件之间发布消息的全局事件总线。

https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication

长期解决方案:

使用像vuex 这样的状态管理库更好地将数据封装在一个地方(全局存储)并使用import { mapState, mapMutations } from 'vuex'从组件树中订阅它

【讨论】:

    【解决方案2】:

    亲子交流的时候最好也推荐 选项是使用道具和事件。 Read more in Vue docs


    当想要在多个组件之间共享状态时最好和 推荐的方式是使用Vuex。


    如果您想使用简单的数据共享,您可以使用Vue observable。

    简单示例:假设您有一个游戏,并且您希望许多组件都可以访问错误。 (组件可以访问和操作它)。

    errors.js

    import Vue from "vue";
    
    export const errors = Vue.observable({ count: 0 });
    

    Component1.vue

    import { errors } from 'path-of-errors.js'
    
    export default {
      computed: {
        errors () {
          get () { return errors.count },
          set (val) { errors.count = val }
        }
      }
    }
    

    在Component1 中,errors.count 是反应式的。所以如果你有一个模板:

    <template>
      <div>
        Errors: {{ errors }} 
        <button @click="errors++">Increase</button>
      </div>
    </template>
    

    当您点击增加按钮时,您会看到错误增加。


    如您所料,当您在另一个组件中导入 errors.js 时,两个组件都可以参与操作 errors.count。


    注意:尽管您可能会使用 Vue.observable API 来进行简单的数据共享,但您应该知道这是一个非常强大的 API。例如阅读Using Vue Observables as a State Store

    【讨论】:

      【解决方案3】:

      App.vue:


      <router-view pass_data='myData'/>
      

      Sidekick.vue:


      export default {
        name: "Sidekick",
        props: ["pass_data"],
        created() {
          alert("pass_data: "+this.pass_data)
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2017-03-06
        • 2017-08-16
        • 1970-01-01
        • 2020-08-31
        • 2020-11-08
        相关资源
        最近更新 更多