【问题标题】:How can I access the bound value of a <select>'s currently selected <option>?如何访问 <select> 的当前选定 <option> 的绑定值?
【发布时间】:2021-04-23 21:22:04
【问题描述】:

假设我正在制作一个包含&lt;select&gt; 的简单组件。此组件支持v-model,如文档中的here

Vue.component('custom-select', {
  template: '#component',
  props: ['options', 'value'],
});
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

<script type="text/x-template" id="component">
  <div id="component">
    <select :value="value" @input="$emit('input', $event.target.value)">
      <option v-for='option in options' :value="option">
        <slot v-bind="{ option }"></slot>
      </option>
    </select>
  </div>
</script>

如果选项是字符串,这很好用。但是,如果它们是不同的类型(例如对象),则发出的值将转换为字符串(例如 '[object Object]')。这是因为$event.target.value 从 DOM 中拉取值,它始终是字符串类型。

有没有办法获得所选&lt;option&gt; 的原始绑定值?我知道v-model 是一个选项,但它使事情变得复杂,因为它需要添加观察者。


编辑我发现 Vue 似乎将原始绑定值分配给 DOM 节点上的 _value 属性,但我不确定访问它是否是一个好主意,因为它是下划线前缀,似乎没有记录。

【问题讨论】:

    标签: vue.js vuejs2


    【解决方案1】:

    假设options prop 是一个对象数组,如下所示 您可以将子组件的事件发射器更改为返回对象而不是字符串,如下所示:

    <style>
      [v-cloak] {
        display: none;
      }
    </style>
    <!-- // App -->
    <div id="app">
      <div v-cloak>
        Value in parent: {{selectedValue}}
        <br><br>
        <custom-select :options='selectOptions' v-model='selectedValue'></custom-select>
      </div>
    </div>
    
    <!-- // JS Code -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    
    <script type="text/x-template" id="component">
      <div id="component">
        <select @change="$emit('input', options.find(option => option.value == $event.target.value))">
          <option v-for='option in options' :value="option.value">
            {{ option.text }}
          </option>
        </select>
      </div>
    </script>
    <script>
      // Mount App
      new Vue({
        el: '#app',
        data() {
          return {
            selectOptions: [
              { text: 'Apple', value: 'apple', price: '10' },
              { text: 'Banana', value: 'banana', price: '20' },
              { text: 'Strawberry', value: 'strawberry', price: '30' },
            ],
            selectedValue: {}
          }
        },
        // Custom component
        components: {
          'custom-select': Vue.component('custom-select', {
            template: '#component',
            props: ['options', 'value'],
          })
        }
      })
    </script>

    【讨论】:

    • 这是一个很好的解决方法,但不是一个合适的解决方案,因为它要求所有项目都有一个基于字符串的 ID
    • @Ryan 我不确定你有什么样的输入数据。您可以分享示例输入吗?
    • 我正在寻找一种适用于任意数据类型数组的解决方案。
    • @Ryan 几个例子会有帮助。
    【解决方案2】:

    虽然我还没有找到原始问题的确切解决方案,但我找到了一种我认为可以令人满意地解决问题的设计模式。通过使用带有 getter 和 setter 的计算属性,我可以在 &lt;select&gt; 上使用 v-model,而无需观察者或任何内部组件状态。

    Vue.component('custom-select', {
      template: '#component',
      props: ['options', 'value'],
      computed: {
        valueProxy: {
          get() {
            return this.value;
          },
          set(newValue) {
            this.$emit('input', newValue);
          },
        },
      },
    });
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    
    <script type="text/x-template" id="component">
      <div id="component">
        <select v-model="valueProxy">
          <option v-for='option in options' :value="option">
            <slot v-bind="{ option }"></slot>
          </option>
        </select>
      </div>
    </script>

    【讨论】:

      猜你喜欢
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多