Vue2: handling multi-child prop synchronization wi

2019-08-17 19:03发布

问题:

I'm new to Vue (about a, and while reading the docs is very helpful it is often the case where I can not derive how I am supposed to achieve the desired behavior.

I have made several small components to get the feel for passing props and handling events, so now I am trying to makes something a bit larger but am facing some difficulty.

This difficulty stems from the following:

I would like to have a custom select component that are initialized via a v-for loop. All the while I would like to have access to these components selected option. I can bind the select data with v-model in the select component, but I am struggling to get that information out to the wrapper, yet alone the container looping over the wrappers.

Note: I am using Rollup and single file components

top-level

<template >
  <div>
    <select-container
      v-for="(select, index) in selects"
      :index="index"
      :key="select.id"
      :select.sync="select"
    />
  </div>



</template>

<script>
import selectContainer from './select-container.vue';


export default {
  components: { selectContainer },

  props: {
    records: {
      default: function(){return{}},
      type: Object
    }
  },

  data: function() {
    return {
      selects: [{}, {}]
    }
  },

  computed: {

  },

  methods: {

  }
}
</script>

<style scoped>

</style>

select-container

<template>
  <div>
    <my-select
      v-model.sync="select"
    />
  </div>
</template>

<script>
import mySelect from './my-select.vue';

export default {
  components: { mySelect },
  props: {
    index: { type: Number },
    select: {
      type: Object,
      default: function(){return{}}
    }
  },

  data : function(){
    return {

    }
  },

  methods: {

  },

  computed: {

  }
}
</script>

<style scoped>

</style>

my-select

<template>
  <select v-model="selected">
    <option
      v-for="(attr, index) in attributes"
      :value="attr"
      :selected="attr == selected"
    >
      {{attr}}
    </option>
  </select>
</template>

<script>
export default {
  props: {
    attributes: {
      type: Array,
      default: function() {
        return []
      }
    }
  },
  data: function() {
    return {
      selected: ""
    }
  }
}
</script>

<style scoped>
</style>

回答1:

There's still a lot of code in the post that I'm not following, but I think the gist of your question is how to reflect the selected property from the <my-select> component through to the <select-container> component. If that's the case, then the most straightforward approach is probably just to add a value and emit input events.

In the template, add an event handler for the native <select>

<select v-model="selected"  @input="onInput">

Then, in the code, reflect that event up to the parent. Also be sure to accept a value property from that parent.

export default {
  props: {
    value: null,
  },
  data: function() {
    return {
      selected: this.value
    }
  },
  methods: {
    onInput() {
      this.$emit("input", this.selected)
    }
  },
  watch: {
    value(newValue) {
      this.selected = newValue;
    }
  }
}

And then the parent can simply use the conventional v-model binding.

<my-select v-model="select"/>