У меня есть компонент comobox для отображения тегов из запроса API. Компонент получает теги в качестве реквизита в следующем формате:
"tags": [ { "name": "Rejected" }, { "name": "Accepted" } ] }
Я пытаюсь получить значение name
и сделать его как v-model
, чтобы отображать теги, сохраненные в БД, и сохранять новые теги, если пользователям нужно их обновить. Вот код комобокса:
<v-container fluid>
<v-combobox
v-model = "model"
:items = "items"
:search-input.sync = "search"
hide-selected
hint = "Maximum of 5 tags"
label = "Add some tags"
multiple
persistent-hint
small-chips
>
<template v-slot:no-data>
<v-list-item>
<v-list-item-content>
<v-list-item-title>
No results matching "<strong>{{ search }}</strong>". Press <kbd>enter</kbd> to create a new one
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
</v-combobox>
</v-container>
Реквизит
props:{
value:{
required: true,
type:Object
}
}
вычисленный
computed: {
model() {
return Object.entries(this.value.tags).forEach(([key,value]) => {
return this.model = value
})
}
},
Проблема, когда я пытаюсь получить значение с помощью Object.entries
(что-то, что я хочу использовать для перебора свойств):
TypeError: невозможно преобразовать undefined или null в объект
так как forEach над неопределенным или нулевым типом?
эм... ты не можешь. forEach()
— это метод объекта Array (и некоторых других объектов типа Array) в JavaScript. Это означает, что вы часто вызываете его из действительного объекта Array. Пустой объект по-прежнему является объектом, поэтому [].forEach(console.info);
работает, но ничего не делает, так как нечего перебирать.
Вы говорите, что нет решения этого вопроса?
Ошибка Cannot convert undefined or null to object
указывает на то, что this.value.tags
еще не определено при вычислении. Вычисляемый реквизит запускается при инициализации до предоставления value
. Одним из решений является указание значения по умолчанию в объявлении свойства, которое содержит начальную tags
:
export default {
props: {
value: {
default: () => ({ tags: [] })
}
}
}
tags
Если я правильно понимаю, вы пытаетесь сопоставить значения name
из tags[]
в массив. Вы можете сделать это с помощью Array.prototype.map:
export default {
computed: {
model() {
// takes the `name` property from each object in `tags[]`
return this.value.tags.map(({ name }) => name)
}
}
}
Я заметил, что вы привязываете model
вычисляемую опору к <v-combobox v-model = "model">
, но v-model
требует свойства, доступного для записи, а model
— нет. Вы должны увидеть предупреждение консоли в режиме разработки по этому поводу.
Я думаю, что model
действительно должен быть items
здесь. Выбранное пользователем значение будет храниться в v-model
, так что это должно быть какое-то свойство, объявленное в data()
вашего компонента:
<template>
<v-combobox
v-model = "selectedItems"
:items = "model"
/>
</template>
<script>
export default {
data() {
return {
selectedItems: []
}
},
computed: {
model() { /* ... */ }
}
}
</script>
Оператор return внутри
forEach
не действует.tags
содержит массив, поэтомуObject.entries()
будет иметь неожиданный результат. Независимо от всего этого, ясно, чтоthis.value.tags
— этоundefined
илиnull
. Введите это в консоли и посмотрите, как это работает:Object.entries({name: 'test', number: 42})