Vue自定义选择具有对象值的组件

时间:2017-03-02 17:55:01

标签: javascript vue.js

我正在尝试使用Vuejs 2实现自定义选择组件。如文档中所述,我不应直接修改值props并建议使用event将所选数据传递给父组件。当选项值是一个对象并且得到[Object object]时,我遇到了问题。

这是我的选择组件模板:

<div :class="inputLength">
        <select :id="id"
                :value="value"
                @change="setValue($event.target.value)"
                :multiple="multiple"
                class="selectpicker">
            <option value="">Nothing selected.</option>
            <option :selected="option == value" v-for="option in options"
                    :value="option">
                {{ option[label] }}
            </option>
        </select>
        <span v-if="error.any()" class="help-block" v-text="error.all()"></span>

</div>

这是脚本部分:

export default {
    props: {
        value: {
            default() {
               return ''
            }
        },
        options: {
            type: Array,
            require: true
        },
        ...
    },
    methods: {
        setValue(val) {
            this.error.clear();
            this.$emit('input', val);
        }
    }
}

这里是父组件

<input-select-horizontal
    v-model="form.category"
    :label-class="{'col-md-4': true}"
    input-length="col-md-8"
    :options="categories.all()"
    label="name"
    :error="form.errors.get('category_id')">
<span slot="label">Category <span class="required" aria-required="true">*</span></span>

选项:

[
    {
        id: 1,
        name: 'Category 1',
        description: 'desc 1'
    },
    {
        id: 2,
        name: 'Category 2',
        description: 'desc 2'
    },
    ...
]

我期待着

form.category = {
    id: 1,
    name: "Category 1",
    description: "desc 1"
}

但得到了[对象]

我错过了什么吗?

3 个答案:

答案 0 :(得分:2)

你的问题在于:

<option v-for="option in options" :value="option">
  {{ option[label] }}
</option>

您正在获取整个对象并将其分配给option元素的value属性。这不会起作用,因为value属性必须是一个字符串。因此,对象将转换为[Object object]

您应该尝试使用:value="option.id",ID值应该正常通过父组件,您可以使用它来查找正确的类别。

答案 1 :(得分:0)

正如 mzgajner 提到的,您不能绑定对象,因为它会将其转换为字符串。 但是,您可以做的是在选项组件中将对象转换为 base64 字符串,然后在选择组件中再次对其进行解码。

例如: 组件 CustomOption

<template>
  <option v-bind="{ ...$attrs, value: innerValue }" v-on="$listeners">
    <slot>
      {{ label || $attrs.value }}
    </slot>
  </option>
</template>

<script>
export default {
  props: {
    label: [String, Number, Boolean],
  },
  computed: {
    innerValue() {
      return btoa(JSON.stringify(this.$attrs.value));
    },
  },
};
</script>

组件自定义选择

<template>
  <select
    :value="innerValue"
    v-bind="$attrs"
    v-on="{
      ...$listeners,
      input: onInput,
    }"
  >
    <slot></slot>
  </select>
</template>

<script>
export default {
  props: {
    value: null
  },
  computed: {
    innerValue() {
      return btoa(JSON.stringify(this.value));
    },
  },
  methods: {
    onInput(e) {
      let value = JSON.parse(atob(e.target.value));
      this.$emit('input', value);
    },
  },
};
</script>

答案 2 :(得分:-1)

https://www.npmjs.com/package/stf-vue-select


<stf-select v-model="value" style="width: 300px; margin: 0 auto">
      <div slot="label">Input address</div>
      <div slot="value">
        <div v-if="value">
           <span>{{value.address}} (<small>{{value.text}}</small>)</span>
        </div>
      </div>
      <section class="options delivery_order__options">
          <stf-select-option  
           v-for="item of list" :key="item.id"
           :value="item"
           :class="{'stf-select-option_selected': item.id === (value && value.id)}" 
           >
              <span>{{item.text}} (<small>{{item.address}}</small>)</span>
          </stf-select-option>
      </section>
    </stf-select>
相关问题