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

新手上路,请多包涵

我正在尝试使用 Vuejs 2 实现自定义选择组件。如文档中所述,我不应直接修改值道具并建议使用事件将所选数据传递给父组件。 I’m having issue when the option value is an object and got [Object object] instead.

这是我的选择组件模板:

 <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"
}

但是得到了 [Object object]

我错过了什么?

原文由 Lazuardi Rea Rizkina 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 406
2 个回答

你的问题出在这里:

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

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

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

原文由 mzgajner 发布,翻译遵循 CC BY-SA 3.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>

原文由 Rik De Peuter 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题