【问题标题】:How to pass data to nested child components vue js?如何将数据传递给嵌套的子组件vue js?
【发布时间】:2018-11-12 18:29:10
【问题描述】:

我知道如何在以下情况下使用道具将数据从父母传递给孩子:

<template>
<div>
      <div v-for="stuff in content" v-bind:key="stuff.id">
        <ul>
          <li>
            {{ stuff.items }}
          </li>
        </ul>
      </div>
</div>
</template>

<script>
export default {
  name: stuff,
  props: ['content'],
  data () {
    return {

    }
  }
}
</script>

然后将数据绑定到父组件中的组件就好了,

<template>
  <div>
    <stuff v-bind:content="stuffToPass"></stuff>
  </div>
</template>
<script>
import stuff from './stuff.vue';
export default {
  data () {
    return {
      stuffToPass: [
        {id: 1, items: 'foo'},
        {id: 2, items: 'bar'},
        {id: 3, items: 'baz'}
      ]
    }
  },
  components: {
    stuff
  }
}
</script>

但是假设我有根组件,并且我想将数据传递给 stuff 组件,就像上面一样,但是当我有许多其他组件时,例如 parent > x > y > stuff,它仍然是最终将接收该数据的东西组件,我不知道该怎么做。

我听说过提供/注入,但我不确定这是否合适,或者至少我无法让它发挥作用。

然后我尝试传递道具,但后来我发现自己试图将道具绑定到组件以作为道具传递给子组件,这听起来不对,所以我只是在'stuff' 组件,但我觉得这可能是重写许多代码以接近合理的方式。

【问题讨论】:

  • 你应该使用github.com/vuejs/vuex
  • 是的,我将使用 vuex。这个问题的动机是,如果“东西”组件也将用于/在其他组件中,我将需要通过特定的父级传递数据
  • 您可以将数据从父级传递给 x,然后将 x 传递给 y,最后一个 y 传递给填充组件。或者您可以使用任何状态管理库,例如 redux 或 Flux。
  • 那么在父组件中:

标签: javascript vue.js vue-component


【解决方案1】:

传递数据有几种可能性parent > x > y > stuff

  • props - 适用,但您必须通过所有组件传输数据...
  • store (vuex) - 适用,但处理起来可能会变得复杂
  • 活动巴士 - 最灵活、最直接的方式

下面,一个简单的例子说明如何实现事件总线:

// src/services/eventBus.js

import Vue from 'vue';
export default new Vue();

您要发出事件的代码:

// src/components/parent.vue

<script>
import EventBus from '@/services/eventBus';

export default {
  ...
  methods: {
    eventHandler(val) {
      EventBus.$emit('EVENT_NAME', val);
    },
  },
  ...
};
</script>

你想在哪里监听事件的代码:

// src/components/stuff.vue

<script>
import EventBus from '@/services/eventBus';

export default {
  ...
  mounted() {
    EventBus.$on('EVENT_NAME', val => {
      // do whatever you like with "val"
    });
  },
  ...
};
</script>

【讨论】:

    【解决方案2】:

    使用观察者或计算属性https://vuejs.org/v2/guide/computed.html

    const Stuff = Vue.component('stuff', {
      props: ['content'],
      template: `<div>
          <div v-for="stuff in content" v-bind:key="stuff.id">
            <ul>
              <li>
                {{ stuff.items }}
              </li>
            </ul>
          </div>
    </div>`
    });
    
    const Adapter = Vue.component('adapter', {
      components: { Stuff },
      props: ['data'],
      template: `<div>
            <Stuff :content="newData"/>
      </div>`,
      data() {
        return {
          newData: []
        };
      },
      created() {
        this.changeData();
      },
      watch: {
        data: {
          deep: true,
          handler: function() {
            this.changeData();
          }
        }
      },
      methods: {
        changeData() {
          this.newData = JSON.parse(JSON.stringify(this.data));
        }
      }
    });
    
    const app = new Vue({
      el: '#app',
      components: { Adapter },
      data() {
        return {
          stuffToPass: [
            { id: 1, items: 'foo' },
            { id: 2, items: 'bar' },
            { id: 3, items: 'baz' }
          ]
        };
      },
      methods: {
        addItem() {
          this.stuffToPass.push({ id: this.stuffToPass.length + 1, items: 'new' });
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.1/vue.js"></script>
       <div id="app">
          <button @click="addItem">Add</button>
          <Adapter :data="stuffToPass"/>
        </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-02
      • 2016-09-24
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 1970-01-01
      • 2018-11-23
      相关资源
      最近更新 更多