渲染错误:"TypeError: Cannot read property 'length' of undefined"

3

如果我的搜索输入框中包含任何文本,我想要显示一个覆盖层。

这是我的模板,其中包含我的输入框:

Input.vue:

<template>
    <div>
        <input v-model="query" class="input" placeholder="Global search..."></input>

    </div>
</template>
<script>
    export default {
        data() {
            return {
                query: '',
            };
        }
    };
</script>

当我在控制台检查时,query会更新为我在输入框中写的任何文本。

然后,我尝试将这个变量传递给另一个组件,该组件包含我的覆盖层 div:

Overlay.vue

<template>
    <div v-if="this.$root.query.length > 0">
        <div class="search-overlay is-active"></div>
    </div>
</template>

然而,这给我带来了以下错误:

[Vue warn]: 渲染错误:"TypeError: 无法读取未定义的属性“length”"

我在这里做错了什么?


为什么需要使用 this.$root?您能提供有关不同组件的更多详细信息吗? - Thomas Lombart
将您的 query 对象作为属性传递给您的叠加组件:<overlay :query="query" /> 并在 Overlay.vue 中定义该属性。 - Thoomas
2个回答

2
"$root是树中最顶层的组件(使用new Vue()实例化的组件),我不认为它是Input.vue。无论如何,如果Input.vue是根组件,那么像您这样访问组件状态是很混乱的。如果您想在组件之间共享数据,应该通过props进行(数据从父组件流向子组件),或者对于更复杂的情况,您可能需要一个共享数据存储(例如Vuex)。"

1

你永远不应该像这样访问组件数据。这是一种不好的方式。你应该看一下 VueX 和状态管理模式,因为这是你在这里遇到的典型情况。

然而,如果你不想使用VueX(或其他状态管理模式的工具),你可以像这样使用事件:

var Input = Vue.component('custom-input', {
  name : "custom-input",
  template : "#custom-input-template",
  props : ["value"],
  methods : {
    onInput(){    
      this.$emit('input', this.$refs.queryInput.value)
    }
  },
  created() {
    console.log("Custom-input created")
  }
});

var Overlay = Vue.component('custom-overlay', {
  name : "custom-overlay",
  template : "#custom-overlay-template",
  props : ["query"],
  created() {
    console.log("Custom-overlay created")
  }
});

new Vue({
    el: "#app",
    components : {
      Input,
      Overlay
    },
    data: {
    query : null
    }
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
 <div>  
   <custom-input v-model="query"></custom-input>
   <custom-overlay v-show="query && query.length > 0" :query="query"></custom-overlay>
 </div>
</div>


<script type="text/x-template" id="custom-input-template">
    <div>
        <input :value="value" ref="queryInput" class="input" placeholder="Global search..." @input="onInput"></input>
    </div>
</script>

<script type="text/x-template" id="custom-overlay-template">
  <div>
   {{query}}
  </div>
</script>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接