我正在学习如何使用vue.js来提取电影信息并进行显示。
在主应用程序mc中,我有一个方法getMovie,在调用另一个方法updateMovie时没有调用它。 updateMovie方法是从子组件详细信息卡
发出的事件'switch'调用的我可以看到我的应用程序上的标题发生了变化,如果你点击导演然后点击导演下的电影,方法updateMovie就可以了。输入字段也会更改值。为什么getMovie不起作用?
var mc = new Vue({
el: "#movie-card",
data: {
title: '',
valid: false,
loading: false,
error: false,
mc: {},
directorArray: [],
actorArray: [],
},
computed: {
checkMulti: function(item) {
if (Object.keys(item).length <= 1) {
return false;
} else {
return true;
}
}
},
methods: {
getMovie: function() {
this.cm = {};
console.log("getMovie called")
if (this.title !== "") {
this.loading = true;
this.error = false;
searchString = 'https://www.omdbapi.com/?t=' + this.title;
var that = this;
axios.get(searchString)
.then(function(res) {
that.cm = res.data;
that.directorArray = res.data.Director.trim().split(/\s*,\s*/);
that.actorArray = res.data.Actors.trim().split(/\s*,\s*/);
that.valid = true;
that.loading = false;
})
.catch(function(error) {
console.log(error.message);
that.loading = false;
that.error = true;
})
}
},
updateMovie: function(movie) {
console.log(movie);
this.title = movie;
this.getMovie;
}
}
})
Vue.component('details-card', {
props: [
'name',
'title'
],
template: `
<div>
<a href=""
@click="handleShowDetails($event)"
>
{{ name }}
</a>
<div v-if="visible" class="detailsCard">
<h3 class="removeTopMargin">{{ name }}</h3>
<img :src="picUrl">
<h4>Known for</h4>
<p v-for="movie in knownForArray">
<a href=""
@click="switchMovie(movie.original_title, $event)"
>{{ movie.original_title }}</a>
</p>
</div>
</div>
`,
data: function() {
return {
picUrl: "",
knownForArray: [],
visible: false
}
},
methods: {
handleShowDetails: function($event) {
this.visible = !this.visible;
this.callPic($event);
},
switchMovie( movie , $event) {
if ($event) $event.preventDefault();
console.log("switching to...", movie);
this.$emit('switch', movie);
},
callPic: function(event) {
if (event) event.preventDefault();
let that = this;
let searchString = "https://api.themoviedb.org/3/search/person?api_key=9b8f2bdd1eaf20c57554e6d25e0823a2&language=en-US&query=" + this.name + "&page=1&include_adult=false";
if (!this.picUrl) { //only load if empty
axios.get(searchString)
.then(function(res) {
let profilePath = res.data.results[0].profile_path;
if (profilePath === null) {
that.picUrl = "http://placehold.it/150x200"
} else {
that.picUrl = 'https://image.tmdb.org/t/p/w150/' + profilePath;
}
that.personPic = profilePath;
that.knownForArray = res.data.results[0].known_for;
}).catch(function(err){
console.log(err);
})
}
},
hideDetails: function () {
this.visible= false;
}
}
})
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
*:focus {
outline: none;
}
ul {
padding-left: 1em;
}
.loading {
margin: auto;
max-width: 450px;
}
.details {
display:block;
margin: 1em auto;
text-align: center;
}
.searchBar {
padding: .5em;
-webkit-box-shadow: 0px 2px 16px 2px rgba(168,168,168,0.45);
-moz-box-shadow: 0px 2px 16px 2px rgba(168,168,168,0.45);
box-shadow: 0px 2px 16px 2px rgba(168,168,168,0.45);
text-align: center;
}
.searchBar input {
padding: .5em;
width: 300px;
font-size: 1em;
border: none;
border-bottom: 1px solid gray;
}
.searchBar button {
padding: .2em;
border: 2px solid gray;
border-radius: 8px;
background: white;
font-size: 1em;
color:#333;
}
img {
display: block;
margin: auto;
width: 150px;
padding-bottom: .33em;
}
.card {
max-width: 500px;
margin: 2em auto;
-webkit-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
-moz-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
padding: 2em;
}
.detailsCard {
-webkit-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
-moz-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
padding: 1em;
}
/* ======= Typography */
html {font-size: 1em;}
body {
background-color: white;
font-family: roboto;
font-weight: 400;
line-height: 1.45;
color: #333;
}
p {margin-bottom: 1.3em;}
h1, h2, h3, h4 {
margin: 1.414em 0 0.5em;
font-weight: inherit;
line-height: 1.2;
}
h2, h3, h4 {
border-bottom: 1px solid gray;
}
h1 {
margin-top: 0;
font-size: 3.998em;
text-align: center;
}
h2 {font-size: 2.827em;}
h3 {font-size: 1.999em;}
h4 {font-size: 1.414em;}
small, .font_small {font-size: 0.707em;}
.removeTopMargin {
margin-top: .5em;
}
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="movie-card">
<div class="searchBar">
<input type="text" ref="input" v-model="title" placeholder="Enter a movie title here..." v-on:keyup.enter="getMovie">
<button type="submit" @click="getMovie">Search</button>
</div>
<div class="loading" v-if="loading">
<BR><BR>
<h1>Loading...</h1>
</div>
<div class="loading" v-if="error">
<BR><BR>
<h1>Something went wrong!</h1>
</div>
<div class="card" v-if="valid && !loading">
<h1> {{ cm.Title }}</h1>
<div v-if="!(cm.Poster === 'N/A')" class="poster">
<img v-bind:src="cm.Poster">
</div>
<div class="details">
<p>{{ cm.Year + " – " + cm.Rated + " – " + cm.Runtime }}</p>
</div>
<p>{{ cm.Plot }}</p>
<div class="directors" v-if="cm.Director">
<h3 v-if="(directorArray.length > 1)">Director</h3>
<h3 v-else>Director</h3>
<p>
<p v-for="(director, index) in directorArray">
<details-card :name="director" v-on:switch="updateMovie"></details-card>
</p>
</p>
</div>
<div class="actors" v-if="cm.Actors">
<h3 v-if="actorArray.length > 1">Actors</h3>
<h3 v-else>Actor</h3>
<p>
<p v-for="(actor, index) in actorArray">
<details-card :name="actor"></details-card>
</p>
</p>
</div>
<div class="ratings" v-if="cm.Ratings">
<h3>Ratings</h3>
<ul>
<li v-for="rating in cm.Ratings">{{ rating.Source }}: {{ rating.Value }}</li>
</ul>
</div>
</div>
</div>