#javascript #vue.js
#javascript #vue.js
Вопрос:
У меня есть следующий компонент Vue:
Vue.component('result', {
props: ['stuff'],
data: () => ({}),
template: "<img :src='tag' class='result'></img>",
computed: {
tag: function tag() {
return `pages/search/img/${this.stuff.type.toLowerCase()}_tag.png`;
}
}
});
При создании компонента выдается ошибка:
TypeError: Cannot read property 'toLowerCase' of undefined
at VueComponent.tag
Однако, когда я удаляю вызов toLowerCase()
, метод выполняется правильно, генерируя строку с ожидаемым типом. Я мог бы обойти это, изменив имена файлов на заглавные буквы, но я бы предпочел понять, почему Vue ведет себя таким образом. Почему свойство должно быть неопределенным только тогда, когда для него вызываются методы?
Обновление: после некоторого устранения неполадок я обнаружил, что this.stuff.type
при первом tag()
вычислении значение не определено. Вызов toLowerCase()
просто вызывает ошибку в противном случае беззвучной ошибки. Есть ли причина props
, по которой они не определены при computed
первом вызове функций? Должен ли я писать свой компонент по-другому?
Ответ №1:
stuff
Реквизит не определен при result
создании компонента.
Есть два варианта решения этой проблемы:
Либо используйте v-if
директиву в шаблоне родительского компонента, чтобы убедиться stuff
, что имеет значение при создании result
компонента:
<template>
<result v-if="stuff" :stuff="stuff" />
</template>
Или обработайте stuff
prop, находящийся undefined
в result
компоненте.
Vue.component('result', {
props: {
// Object with a default value
stuff: {
type: Object,
// Object or array defaults must be returned from
// a factory function
default: () => ({ type: 'someType'})
},
},
data: () => ({}),
template: "<img :src='tag' class='result' >",
computed: {
tag: function tag() {
return `pages/search/img/${this.stuff.type.toLowerCase()}_tag.png`;
}
}
})
Примечание: img
элемент является элементом void, для него не требуется конечный тег.
Ответ №2:
По умолчанию используются реквизиты null
, но вы можете присвоить им значение по умолчанию, чтобы преодолеть эту проблему.
Пример :
Vue.component('result', {
props: {
stuff: {
type: Object,
default: {
type: ''
}
}
},
data: () => ({}),
template: "<img :src='tag' class='result'></img>",
computed: {
tag: function tag() {
return `pages/search/img/${this.stuff.type.toLowerCase()}_tag.png`;
}
}
});