属性或方法“回文”未在实例上定义,但在渲染期间引用

Posted

技术标签:

【中文标题】属性或方法“回文”未在实例上定义,但在渲染期间引用【英文标题】:Property or method "palindrome" is not defined on the instance but referenced during render 【发布时间】:2019-11-29 16:31:30 【问题描述】:

我在这个问题上已经坚持了一段时间,在 Google、Stack Overflow 上阅读过 100 多篇帖子,但没有找到关于正在发生的事情的解释。

我是 VUE 的新手,还在学习,但这件事让我感到困惑。

我有一个人员数据对象列表,其中启动了 v-for 代码并根据数据对象在表中表示行。

        <tr v-for="person in people" :key="person.id">
          <td>
            <router-link
              :to="name: 'person-edit', params:  id: person.id "
            >person | fullName</router-link>
          </td>

<!--          Shows No as a result-->
          <td>(person | palindrome) ? 'Yes' : 'No'</td>
<!--          Shows No as a result-->
          <td v-if="person | palindrome">Yes</td>
          <td v-else>No</td>
<!--          Shows true as a result-->
          <td>person | palindrome</td>

          <td>person.authorised ? 'Yes' : 'No'</td>
          <td>person.enabled ? 'Yes' : 'No'</td>
          <td>person.colours | colourNames</td>
        </tr>

第一个和第二个代码示例也会在客户端控制台上打印此错误:

[Vue 警告]:属性或方法“回文”未在 实例,但在渲染期间引用。确保该属性是 反应式,无论是在数据选项中,还是对于基于类的组件,通过 初始化属性。看: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

自从 人 | palindrome 返回 true 这证明回文函数正在运行,但是,我无法在 HTML 代码部分中呈现 Yes 或 No。

<script lang="ts">
  import Vue from 'vue';
  import getPeople from '../api/people-api';

  export default Vue.extend(
  async mounted() 
    this.people = await getPeople();
  ,
  data() 
    const people: IPerson[] = [];

    return 
      people,
    ;
  ,
  filters: 
    colourNames: (colours: IColour[]): string => 

      const coloursString: string[] = [];

      colours.forEach((colour) => 
        coloursString.push(colour.name);
      );

      return coloursString.sort().join();
    ,
    fullName: (person: IPerson): string => 
      return `$person.firstName $person.lastName`;
    ,
    palindrome: (person: IPerson): boolean => 
      const fullName = `$person.firstName $person.lastName`;
      // TODO: Step 5
      //
      // Implement the palindrome computed field.
      // True should be returned When the FullName is spelt the same
      // forwards as it is backwards. The match should ignore any
      // spaces and should also be case insensitive.
      //
      // Example: "Bo Bob" is a palindrome.

      const nameLowerCase = fullName.toLowerCase().split(' ').join('');
      const nameReversed = nameLowerCase.split('').reverse().join('');
      return nameLowerCase === nameReversed;
    ,
  ,
);
</script>

如果全名是回文,我已经设法将回文函数更改为返回字符串,但是,任务特别要求在回文函数启动时返回布尔值。

任何提示,建议?请。

编辑

人物数据集:

[
  
    "id": 1,
    "firstName": "Bo",
    "lastName": "Bob",
    "authorised": true,
    "enabled": false,
    "colours": [
      
        "id": 1,
        "name": "Red"
      
    ]
  ,
  
    "id": 2,
    "firstName": "Brian",
    "lastName": "Allen",
    "authorised": true,
    "enabled": true,
    "colours": [
      
        "id": 1,
        "name": "Red"
      ,
      
        "id": 2,
        "name": "Green"
      ,
      
        "id": 3,
        "name": "Blue"
      
    ]
  ,
  
    "id": 3,
    "firstName": "Courtney",
    "lastName": "Arnold",
    "authorised": true,
    "enabled": true,
    "colours": [
      
        "id": 1,
        "name": "Red"
      
    ]
  ,
  
    "id": 4,
    "firstName": "Gabriel",
    "lastName": "Francis",
    "authorised": false,
    "enabled": false,
    "colours": [
      
        "id": 2,
        "name": "Green"
      
    ]
  ,
  
    "id": 5,
    "firstName": "George",
    "lastName": "Edwards",
    "authorised": true,
    "enabled": false,
    "colours": [
      
        "id": 2,
        "name": "Green"
      ,
      
        "id": 3,
        "name": "Blue"
      
    ]
  ,
  
    "id": 6,
    "firstName": "Imogen",
    "lastName": "Kent",
    "authorised": false,
    "enabled": false,
    "colours": [
      
        "id": 1,
        "name": "Red"
      ,
      
        "id": 2,
        "name": "Green"
      
    ]
  ,
  
    "id": 7,
    "firstName": "Joel",
    "lastName": "Daly",
    "authorised": true,
    "enabled": true,
    "colours": [
      
        "id": 2,
        "name": "Green"
      
    ]
  ,
  
    "id": 8,
    "firstName": "Lilly",
    "lastName": "Hale",
    "authorised": false,
    "enabled": false,
    "colours": [
      
        "id": 1,
        "name": "Red"
      ,
      
        "id": 2,
        "name": "Green"
      ,
      
        "id": 3,
        "name": "Blue"
      
    ]
  ,
  
    "id": 9,
    "firstName": "Patrick",
    "lastName": "Kerr",
    "authorised": true,
    "enabled": true,
    "colours": [
      
        "id": 2,
        "name": "Green"
      
    ]
  ,
  
    "id": 10,
    "firstName": "Sharon",
    "lastName": "Halt",
    "authorised": false,
    "enabled": false,
    "colours": [
      
        "id": 1,
        "name": "Red"
      ,
      
        "id": 2,
        "name": "Green"
      ,
      
        "id": 3,
        "name": "Blue"
      
    ]
  ,
  
    "id": 11,
    "firstName": "Willis",
    "lastName": "Tibbs",
    "authorised": true,
    "enabled": false,
    "colours": [
      
        "id": 1,
        "name": "Red"
      ,
      
        "id": 2,
        "name": "Green"
      ,
      
        "id": 3,
        "name": "Blue"
      
    ]
  
]

【问题讨论】:

【参考方案1】:

过滤器只能用在模板表达式的末尾。过滤器之后唯一可以出现的东西是它的参数或另一个链接过滤器。

如果您在表达式中间使用过滤器,例如 (person | palindrome) ? 'Yes' : 'No',则 | 将被解释为 javascript 的按位 OR 运算符。在这种情况下,personpalindrome 都被视为 Vue 实例的属性。即this.personthis.palindrome。后者不存在,因此您会看到警告消息。

你在一个循环中,所以使用计算属性会很棘手。

解决此问题的一种方法是使其成为方法而不是过滤器。然后您可以使用palindrome(person) ? 'Yes' : 'No' 调用它。

如果您真的想将其保留为过滤器并将其更改为返回字符串不是一种选择,那么您可以使用链接。应该是这样的:

<td> person | palindrome | toYesNo </td>

然后,您将定义一个名为 toYesNo 的过滤器来获取布尔值并返回相关字符串。

【讨论】:

最终使用了方法。感谢您的详细解释。【参考方案2】:

我认为您的问题出在语法上,您是否尝试过将其设为计算属性而不是括号中的三元运算符?您可以像这样访问过滤器: this.$options.filters.palindrome 让它成为一个计算,你应该很好。

此外,我假设您正在使您的过滤器在全球范围内正确可用,否则这可能是原因。 在调试方面,提供一些实际数据以便对其进行测试会有所帮助。 第一步是控制台记录您的过滤器以查看它是否存在。 console.log(this.$options.filters.palindrome),然后看我的第一条评论

【讨论】:

感谢您的回复。我没有考虑全局设置过滤器,但是,如果没有将它们设置为全局,colorNames 和 fullName 将无法访问。我只是不明白为什么&lt;td&gt;person | palindrome&lt;/td&gt; 返回一个真值,但是,当我尝试将它挤入 v-if 它被读取为假时。另外&lt;td&gt;(this.$options.filters.palindrome) ? 'Yes' : 'No'&lt;/td&gt; 这打破了整个事情,表格主体根本没有呈现。 正如我所写,将其设为 computed 属性 not 内联,不同之处似乎在于语法。 (这不是内联可用的)此外,您还需要根据文档执行 Vue.filter 以使其在全球范围内可用,如果不这样做,它将不可用。就为什么它为真而言,它很有可能将其评估为一个字符而不是一个过滤器。

以上是关于属性或方法“回文”未在实例上定义,但在渲染期间引用的主要内容,如果未能解决你的问题,请参考以下文章

“属性或方法未在实例上定义,但在渲染期间引用”

Vue属性或方法未在实例上定义但在渲染期间引用?

属性或方法“sendResetMail”未在实例上定义,但在渲染期间引用

Vue警告:属性或方法“item”未在实例上定义,但在渲染期间被引用

属性或方法“消息”未在实例上定义,但在渲染期间引用

未在实例上定义但在渲染期间引用的属性或方法 I Vuex