gpt4 book ai didi

javascript - 无法在 Vue.JS 中将数据从一个组件推送到另一个组件

转载 作者:行者123 更新时间:2023-12-02 23:26:07 25 4
gpt4 key购买 nike

我试图通过 Prop 将数据从父组件(主页路由)传递到子组件(播放列表路由)。在子组件中,我收到错误“TypeError:无法读取未定义的属性'length'”。这两个组件目前位于同一页面上,但我试图将子组件移动到其自己的路线,这导致了此错误。

App.vue

<template>
<div id="app">
<Header></Header>
<router-view></router-view>
<Footer></Footer>
</div>
</template>

<script>
import Header from './components/header.vue'
import Footer from './components/footer.vue'


export default {
name: 'app',
components: {
Header,
Footer,
}
}
</script>

<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 0px;
}
</style>

Main.js

import Vue from 'vue';
import App from './App.vue';
import "jquery";
import "bootstrap";
import VueRouter from 'vue-router';

import "bootstrap/dist/css/bootstrap.min.css"
import { library } from '@fortawesome/fontawesome-svg-core'
import { faSearch } from '@fortawesome/free-solid-svg-icons'
import { faRedo } from '@fortawesome/free-solid-svg-icons'
import { faPlus } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import Home from './components/home.vue'
import Next from './components/next.vue'
import List from './components/myList.vue'


library.add(faSearch)
library.add(faRedo)
library.add(faPlus)

Vue.component('font-awesome-icon', FontAwesomeIcon)
Vue.use(VueRouter);
Vue.config.productionTip = false

const router = new VueRouter({
routes: [
{
path: '/home',
component: Home
},
{
path: '/next',
component: Next
},
{
path: '/playlist',
component: List
}
]
});

new Vue({
render: h => h(App),
router
}).$mount('#app')

父组件:

<template>
<div class="container search">

<div class="jumbotron" style="clear:both">
<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>-->

<button
type="button"
class="btn btn-primary btn-lg mb-3 float-right"
v-on:click="addItem(result)"
:disabled="result.disableButton"
>

<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",
components: {
List
},
data: function() {
return {
title: "Simple Search",
isActive: true,
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: [],
List: [],
search: "",
loading: "",
message: false,
isValidationAllowed: false,
loadingClass: "loading",
errorTextClass: "error-text",
disableButton: false
};
},

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

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

methods: {
getData: function() {
this.isValidationAllowed = true;
this.loading = true;
fetch(`https://thisapi.com/api`)
.then(response => response.json())
.then(data => {
this.result = data.results;
this.loading = false;
/* eslint-disable no-console */
console.log(data);
/* eslint-disable no-console */
});
},

toggleClass: function() {
// Check value
if (this.isActive) {
this.isActive = false;
} else {
this.isActive = true;
}
},

refreshPage: function() {
this.search = "";
},
addItem: function(result) {
result.disableButton = true; // Or result['disableButton'] = true;
this.List.push(result);
/* eslint-disable no-console */
console.log(result);
/* eslint-disable no-console */
},

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

.red {
background: red;
}

.blue {
background: blue;
}

.div {
width: 100px;
height: 100px;
display: inline-block;
border: 1px solid black;
}
</style>

子组件或/list(路由)

<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">{{List.length}}</span>
</button>

<div class="col-md-4 float-left p-2 mb-3 " v-for="(result, index) in List" :key="index">
<img
:src="resizeArtworkUrl(result)"
alt="Album Cover"
class="album-cover align-self-start mr-3 card-img-top"
>
<div class="card-body">
<h5 class="card-title">{{result.collectionName}}</h5>
<h6 class="mt-0 mb-2">{{result.artistName}}</h6>
<p class="mt-0 mb-2">{{result.primaryGenreName}}</p>

<button class="btn btn-danger" v-on:click="removeElement(result)">Remove</button>
</div>
</div>
</div>
</template>

<script>
export default {
name: 'List',
props:
["List"],

methods: {
removeElement: function(index) {
this.List.splice(index, 1);
},

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

<style scoped>

.album-cover {
width: 100%;
height: auto;
background-color: aqua;
}

</style>

最佳答案

如果您想从当前父组件重定向到播放列表组件,您可以这样做:

this.$router.push({
path: '/playlist',
params: {List: this.List}
});

然后在你的路由器中添加 props 属性:

{
path: '/playlist',
component: List,
props: true,
}

关于javascript - 无法在 Vue.JS 中将数据从一个组件推送到另一个组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56728522/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com