如何将数据传递给嵌套的子组件vue js?

时间:2018-06-03 04:32:21

标签: javascript vue.js vue-component

我得到了如何在类似情况下使用道具将数据从父级传递给子级

<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&gt; x> y&gt;东西,它仍然是最终将接收数据的东西组件,我不知道该怎么做。

我听说过提供/注入,但我不确定它是否适当使用,或者至少我无法使其正常工作。

然后我尝试传递道具,但后来我发现自己试图将道具绑定到一个组件以作为道具传递给子组件并且听起来不对,所以我只是重新编写了我的组件在&#39;东西&#39;组件,但我觉得这可能是重写代码的方式接近合理。

2 个答案:

答案 0 :(得分:1)

有几种方法可以传递数据父级> x> y>内容

  • 道具-适用,但您必须通过所有组件传递数据...
  • 商店(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>

答案 1 :(得分:0)

使用观察者或计算的属性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>