我正在尝试使用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"
}
但得到了[对象]
我错过了什么吗?
答案 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>