Vue prop не определен при первоначальном вызове вычисляемых функций

#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`;
    }
  }
});