首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TypeError:无法读取未定义Vue JS的属性“push”

TypeError:无法读取未定义Vue JS的属性“push”
EN

Stack Overflow用户
提问于 2019-06-18 23:06:09
回答 1查看 2.1K关注 0票数 0

我有一个组件,它试图将数据推送到另一个子组件,由于我是Vue.js新手,所以这里有点困惑。我试图将子组件导入主组件,但是添加项的推送会导致问题吗?有什么想法吗?

我知道错误:

TypeError:无法读取未定义的属性“push”

我不知道为什么或者在哪里?

主要组件:

代码语言:javascript
运行
复制
<template>
  <div class="container search">
    <list></list>

    <div class="jumbotron">
      <h1 class="display-4">{{title}}</h1>
      <p class="lead">{{intro}}</p>
      <hr class="my-4">
      <p v-if="validated" :class="errorTextClass">Enter a valid search term</p>

      <button
        type="button"
        class="btn btn-primary btn-lg mb-3"
        v-on:click="refreshPage"
        v-if="result.length > 1"
      >
        <font-awesome-icon icon="redo"/>Start again
      </button>
      <input
        class="form-control form-control-lg mb-3"
        type="search"
        placeholder="Search"
        aria-label="Search"
        v-model="search"
        required
        autocomplete="off"
        id="search"
      >

      <div v-for="(result, index) in result" :key="index">
        <div class="media mb-4">
          <img
            :src="resizeArtworkUrl(result)"
            alt="Album Cover"
            class="album-cover align-self-start mr-3"
          >
          <div class="media-body">
            <h4 class="mt-0">
              <button
                type="button"
                class="btn btn-primary btn-lg mb-3 float-right"
                v-on:click="addItem(result)"
              >
                <font-awesome-icon icon="plus"/>
              </button>
              <b>{{result.collectionName}}</b>
            </h4>
            <h6 class="mt-0">{{result.artistName}}</h6>
            <p class="mt-0">{{result.primaryGenreName}}</p>
          </div>
        </div>
      </div>

      <div :class="loadingClass" v-if="loading"></div>

      <button
        class="btn btn-success btn-lg btn-block mb-3"
        type="submit"
        v-on:click="getData"
        v-if="result.length < 1"
      >
        <font-awesome-icon icon="search"/>Search
      </button>
    </div>
  </div>
</template>

<script>
import List from "../components/myList.vue";

export default {
  name: "Hero",
  props: {
    List
  },
  components: {
    List
  },
  data: function() {
    return {
      title: "Simple Search",
      intro: "This is a simple hero unit, a simple jumbotron-style.",
      subintro:
        "It uses utility classes for typography and spacing to space content out.",
      result: [],
      errors: [],
      search: "",
      loading: "",
      message: false,
      isValidationAllowed: false,
      loadingClass: "loading",
      errorTextClass: "error-text"
    };
  },

  watch: {
    search: function(val) {
      if (!val) {
        this.result = [];
      }
    }
  },

  computed: {
    validated() {
      return this.isValidationAllowed && !this.search;
    }
  },

  methods: {
    getData: function() {
      this.isValidationAllowed = true;
      this.loading = true;
      fetch(`xxxxxxxx`)
        .then(response => response.json())
        .then(data => {
          this.result = data.results;
          this.loading = false;
          /* eslint-disable no-console */
          console.log(data);
          /* eslint-disable no-console */
        });
    },
    refreshPage: function() {
      this.search = "";
    },
    addItem: function(result) {
      this.myList.push(result);
    },

    resizeArtworkUrl(result) {
      return result.artworkUrl100.replace("100x100", "160x160");
    }
  }
};
</script>

<style>
.loading {
  background-image: url("../assets/Rolling-1s-42px.gif");
  background-repeat: no-repeat;
  height: 50px;
  width: 50px;
  margin: 15px;
  margin-left: auto;
  margin-right: auto;
}

.error-text {
  color: red;
}

.media {
  text-align: left;
}

.album-cover {
  width: 80px;
  height: auto;
}
</style>

子组件:

代码语言:javascript
运行
复制
<template>
  <div class="mb-5 container">
    <button type="button" class="btn btn-primary mt-2 mb-2 btn-block">
      My List
      <span class="badge badge-light">{{myList.length}}</span>
    </button>
    <ul class="list-group" v-for="(result, index) in myList" :key="index">
      <li class="list-group-item">
        <b>{{result.collectionName}}</b>
        <h6 class="mt-0">{{result.artistName}}</h6>
        <p class="mt-0">{{result.primaryGenreName}}</p>
      </li>
    </ul>
  </div>
</template>

<script>

export default {
  name: "List",

  data: function() {
    return {
      myList: [],
      result: []
    };
  }
}
</script>
EN

回答 1

Stack Overflow用户

发布于 2019-06-19 00:27:29

数据应该始终从父组件流到子组件;子组件不应该修改属于父组件的数据。

如果您希望主组件能够将一个项推送到myList,那么myList应该属于主组件,并通过一个支柱将它传递给子组件。

简化示例:

主组件

代码语言:javascript
运行
复制
<list :list="list"/>
<button @click="addItem">Add Item</button>
代码语言:javascript
运行
复制
import List from './list.vue'

export default {
  components: {
    List
  },
  data() {
    return {
      list: []
    }
  },
  methods: {
    addItem() {
      this.list.push('New Item')
    }
  }
}

列表组件

代码语言:javascript
运行
复制
<ul>
  <li v-for="item of list">{{ item }}</li>
</ul>
代码语言:javascript
运行
复制
export default {
  props: ['list']
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56658127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档