3

I have a group of selects but want them all to work differently with v-model without creating separate data properties for them all.

In the example, select 1 and select 2 are one group and select 3 and select 4 are another. When one select select 1, the expected behavior should be that, it does not affect select 2, etc.

My guess is may be a computed property for this? but can't get my head around the proper implementation

Js fiddle: https://jsfiddle.net/uxn501h2/8/

Code snippet:

new Vue({
  el: '#app',
  template: `
        <div>
            Select 1: <select v-model="selectedPerson">
                <option v-for="person in people" :value="person.key">{{person.name}}</option>
            </select>
            Select 2: <select v-model="selectedPerson">
                <option v-for="person in people" :value="person.key">{{person.name}}</option>
            </select>
            <h4>Selected 1 person key : {{selectedPerson}}</h4>
             <h4>Selected 2 person key: {{selectedPerson}}</h4>
            
            <br/>
                       Select 3: <select v-model="selectedPersonTwo">
                <option v-for="person in people" :value="person.key">{{person.name}}</option>
            </select>
            Select 4: <select v-model="selectedPersonTwo">
                <option v-for="person in people" :value="person.key">{{person.name}}</option>
            </select>
            <h4>Selected 3 person Two key: {{selectedPersonTwo}}</h4>
            <h4>Selected 4 person Two key: {{selectedPersonTwo}}</h4>
        </div>
    `,
  data: {
    people: [{
        key: 1,
        name: "Carl"
      },
      {
        key: 2,
        name: "Carol"
      },
      {
        key: 3,
        name: "Clara"
      },
      {
        key: 4,
        name: "John"
      },
      {
        key: 5,
        name: "Jacob"
      },
      {
        key: 6,
        name: "Mark"
      },
      {
        key: 7,
        name: "Steve"
      }
    ],
    selectedPerson: "",
    selectedPersonTwo: ""
  }
});
.required-field > label::after {
  content: '*';
  color: red;
  margin-left: 0.25rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
<body>
  <div id="app"></div>
</body>
nara_l
  • 664
  • 2
  • 9
  • 23
  • It's not totally clear to me how you want the two groups to interact, but they're all working off one array, and your question is very similar to [this one](https://stackoverflow.com/a/47471001/1585345). My tip would be to separate the problem into 1. STORE, 2. computed properties and interface. In your store, your persons array should represent the entire state of the interface - who's selected and in what group. Then create computed properties as needed. – bbsimonbb Jul 06 '18 at 09:43
  • @bbsimonbb looking into the example. Not sure how I could explain any more, but the array idea and example seems plausible, would update – nara_l Jul 07 '18 at 02:31

1 Answers1

0

It looks to me that you'd like to use two-way binding, but with more control between them in the middle. My suggestion would be:

  • Do not use <select v-model="selectedPerson">
  • Instead split them to <select :value="selectedPersonValue" @input="selectedPersonOutput> (which is basically the same thing, but you can specify different input and outputs), where selectedPersonValue can be a computed property or a regular property in data(), and selectedPersonOutput should be a method that will be called when select value changes.

This way you can directly decide what happens on each step.

PS: If you want to influence your property selectedPersonValue from a method, you might consider changing it to data() property and add a watch to it. See what works best for you.

Danon
  • 2,771
  • 27
  • 37
  • Thanks for the input. My guess is the best implementation would be using a computed property as I mentioned. Would you mind providing an adapted working example? – nara_l Jul 06 '18 at 08:22
  • @nara_l I can only show you the door :) You're the one that has to walk through it. – Danon Jul 06 '18 at 08:25