vue.js 从选项循环中获取选定对象

djmepvbi  于 2023-04-12  发布在  Vue.js
关注(0)|答案(6)|浏览(189)

我试图找到一种方法来绑定Vue select-element中的对象数组。案例如下:

data: {
  ideas: [
    { id: 1, code: "01A", text: "option 1", props: [] }, 
    { id: 2, code: "02A", text: "option 2 , props: [{ details: "something" }]}
  ]},
  currentForm: {
    something: "foo",
    else: "bar",
    ideaCode: "01A",
    text: "option 1"
  }
];

在HTML中…

<select v-model="currentForm.ideaCode" @change="setCodeAndLabelForForm(???)">
  <option v-for="i in ideas" value="i">{{ i.text }}<option>
</select>

基本上,我需要能够跟踪用户选择了哪个对象,触发我自己的更改事件,同时与另一个对象的单个键绑定......选择的值/引用键应该与用户选择的选项/对象分开。currentForm与option不是同一个对象类型!它只包含option恰好拥有的一些属性,我试图通过触发用户选择的change-event将这些属性转移到options。**
问题是我还没有弄清楚如何为函数传递当前选定的值,或者如何编写类似于以下内容的内容:

<select v-model="selectedIdea" @change="setCodeAndLabelForForm" :track-by="currentForm.ideaCode">
  <option v-for="i in ideas" value="i">{{ i.text }}<option>
</select>

一种可行的(和有效的)方法是:

<select v-model="currentForm.ideaCode" @change="setCodeAndLabelForForm">
  <option v-for="i in ideas" value="i.ideaCode">{{ i.text }}<option>
</select>

setCodeAndLabelForForm: function() {
    var me = this;
    this.ideas.forEach(function(i) {
        if(i.ideaCode == me.currentForm.ideaCode) {
            me.currentForm.ideaCode = i.selectedIdea.ideaCode;
            me.currentForm.text = i.text;
            ... do stuff & run callbacks ...
        }
    });
}

...但这看起来很糟糕。有更好的建议吗?

2g32fytz

2g32fytz1#

你可以这样实现:
创建空对象数据以跟踪选定值:

currentForm: {}

观察模型上的currentForm并传递选定的对象:

<select v-model="currentForm" @change="setCodeAndLabelForForm(currentForm)">

option中传入选定值:(你在这一步做得很好,但我只是把i改为idea,因为它有点令人困惑的循环索引)

<option v-for="idea in ideas" :value="idea">{{ idea.text }}<option>

应用您的方法:

setCodeAndLabelForForm(selected) {
  // Now, you have the user selected object
}
6rvt4ljy

6rvt4ljy2#

一个更好的解决方案:在v-for中使用索引

<select v-model="selIdeaIndex" @change="setCodeAndLabelForForm">
  <option v-for="(i,idx) in ideas" value="idx">{{ i.text }}<option>
</select>

对于js:

data: {
  selIdeaIndex:null,
  ideas: [
    { id: 1, code: "01A", text: "option 1", props: [] }, 
    { id: 2, code: "02A", text: "option 2", props: [{ details: "something" }]}
  ]
},
methods:{
    setCodeAndLabelForForm: function() {
        var selIdea = this.ideas[this.selIdeaIndex];
        //Do whatever you wanna do with this selIdea.
    }
}
ttcibm8c

ttcibm8c3#

我不知道这是否是最好的解决方案,但我使用如下计算属性来解决这个问题:
在JavaScript文件(ES6)中:

data () {
    return {
        options: [
            { id: 1, text: "option 1" },
            { id: 2, text: "option 2" }
        ],
        selectedOptionId: 1
    }
},
computed: {
    selectedOption () {
        return _.find(this.options, (option) => {
            return option.id === this.selectedOptionId
        });
    }
}

在HTML文件中:

<select v-model="selectedOptionId">
  <option v-for="option in options" :value="option.id" :key="option.id">{{ option.text }}<option>
</select>

“_”符号是一个叫做Lodash的常见JavaScript库,我强烈推荐它的用法。它可以让你保存一些宝贵的时间。

2cmtqfgy

2cmtqfgy4#

如果你知道你的option只来自那个v-for="i in ideas",那么<option>索引将与item索引相同。
因此,<select>.selectedIndex将是所选this.item的索引。

new Vue({
  el: '#app',
  data: {
    ideas: [
      { id: 1, code: "01A", text: "option 1", props: [] }, 
      { id: 2, code: "02A", text: "option 2" , props: [{ details: "something" }]}
    ],
    currentForm: {ideaCode: "01A", text: "option 1"}
  },
  methods: {
    setCodeAndLabelForForm: function(selectedIndex) {
      var selectedIdea = this.ideas[selectedIndex];
      this.currentForm = {ideaCode: selectedIdea.code, text: selectedIdea.text};
    }
  }
})
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>

<div id="app">
  <select v-model="currentForm.ideaCode" @change="setCodeAndLabelForForm($event.target.selectedIndex)">
    <option v-for="i in ideas" :value="i.code">{{ i.text }}</option>
  </select>
  <br> currentForm: {{ currentForm }}
</div>

与你的不同之处:@change="setCodeAndLabelForForm($event.target.selectedIndex)"setCodeAndLabelForForm实现。

gcmastyq

gcmastyq5#

一个简单的方法是使用$ref
有一个使用$ref@change的解决方案。
Vue.js get selected options' raw object

rwqw0loc

rwqw0loc6#

我已经有一段时间没有问过这个问题了,也有一些很好的建议来处理这种情况。我不记得这里给出的确切的业务案例,但只是快速浏览一下,看起来我不知道如何设置/初始化正确的选择。因为只处理@change事件是查尔兹的游戏--它是一个单独的值与基于对象的选项列表的配对,这更难。我最有可能寻找的是AngularJS曾经拥有的东西(track-by -property,它匹配任何给定的值和selected-option)。
就我个人而言,现在的日子,我会分开UI逻辑,而不是试图迫使他们融合在一起。对我来说,最可行的方法是处理选项列表和所选选项作为一个逻辑区域**(即数据:{ list:[...options],selectedIdea:Object })**并将“currentForm”-object从selection中分离出来。让我们打破这个:

  • selectedIdea是需要触发currentForm-object的变化的东西。它不是任何类型的混合模型,它只是一个普通的对象,一个可用的选择,纯粹而简单。
  • 再一次:每当selectedValue ===其中一个选项时,select-dropdown会自动设置为right selection。
  • “currentForm”-object有一个属性,可以用来设置selectedIdea。在本例中,它是“ideaCode”。这个ideaCode不会自动进行任何配对,或者 * 组件逻辑需要来表示规则,这些规则触发选择正确的选项,匹配“ideaCode”。*
  • 只是一个额外的虽然:selectedIdea和currentForm-object是两个不同的逻辑元素。如果你愿意,它们甚至可以被分离成不同的组件,在某些情况下,将它们分离是一件非常好的事情。

因此,通过这些语句,我想我会将select的v-model更改为它应该是的样子:选择的对象之一(将v-model=“currentForm.ideaCode”更改为v-model=“selectedIdea”或类似的)。然后我只需为该selectedIdea添加watcher并从那里对currentForm对象进行任何更改。
通过currentForm.ideaCode初始化这个选项怎么样?在create-method上执行以下操作之一:

  • 迭代可用选项的列表。当您找到选项currentForm.ideaCode == option.code =〉this.selectedIdea = option时
  • 。。。或使用ecmascript find-method来执行相同的操作
  • ...或使用下划线/lodash find-method来执行相同的操作

另一种方法是使用计算值,正如Augusto Escobar所建议的那样。$ref也可以工作,正如张锋所建议的那样,但这种方法仍然需要解决方案来初始化正确的选项(当用初始值加载编辑器时)。也感谢Bhojendra Rauniyar--你沿着都是对的,但我就是无法理解答案,因为我不知道如何回溯最初的选择。
感谢一年来的所有建议!

相关问题