简体   繁体   English

在对计算函数的初始调用中未定义Vue prop

[英]Vue prop undefined in initial call to computed functions

I have the following Vue component: 我有以下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`;
    }
  }
});

When the component is created, an error is thrown: 创建组件后,将引发错误:

TypeError: Cannot read property 'toLowerCase' of undefined
  at VueComponent.tag

However, when I remove the call to toLowerCase() , the method executes properly, generating a string with the expected type. 但是,当我删除对toLowerCase()的调用时,该方法将正确执行,并生成具有预期类型的​​字符串。 I could work around this by changing my filenames to have capital letters, but I would rather understand why Vue is behaving this way. 我可以通过将文件名更改为使用大写字母来解决此问题,但是我宁愿理解Vue为何采用这种方式。 Why would a property be undefined only when methods are called on it? 为什么仅在调用方法时才定义属性?

Update: after some troubleshooting, I found that this.stuff.type is undefined the first time tag() is computed. 更新:经过一些故障排除后,我发现第一次计算tag()this.stuff.type是未定义的。 Calling toLowerCase() just forces an error on an otherwise silent bug. 调用toLowerCase()只会对其他原本无声的错误强制执行错误。 Is there a reason the props aren't defined when computed functions are called for the first time? 初次调用computed函数时是否没有定义props的原因? Should I be writing my component differently? 我应该以不同的方式编写组件吗?

Props are by default null but you can give them a default value to overcome this problem. 默认情况下,道具为null但您可以为它们提供一个默认值来解决此问题。

Example : 范例:

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

The stuff prop is undefined when the result component is created. 创建result组件时, stuff道具未定义。

There are two options to fix this problem: 有两种方法可以解决此问题:

Either use the v-if directive in the parent component's template to make sure stuff has a value when the result component is created: 使用父组件模板中的v-if指令来确保在创建result组件时, stuff具有值:

<template>
  <result v-if="stuff" :stuff="stuff" />
</template>

Or handle the stuff prop being undefined in the result component. 或处理在result组件中undefinedstuff道具。

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

Note: The img element is a void element, it does not require an end tag. 注意: img元素是一个void元素,它不需要结束标签。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM