我有一个组件,而另一个组件。基本上,如果我将鼠标悬停在名称上,则希望在下面填充其相关详细信息。到目前为止,我已经成功地传递了id,但是该id并没有太多用处,因为数据无关紧要。我不知道我在想什么
以下是我的代码
<template>
<div>
<ul class="pokemon-list">
<li v-for="(character, index) in filteredPokemon" :key="index">
<!-- <router-link :to="'/pokemon/'+ character.url.slice(0,-1).split('/').pop()"> -->
<a href='#' @mouseover="greet(character.url)">
{{character.name}}
</a>
<!-- </router-link> -->
</li>
</ul>
<input type="text" v-model="search" placeholder="Search Pokemon">
<SinglePokemon :name="characters.name" :pid="id"/>
</div>
</template>
<script>
import SinglePokemon from "./singlePokemon.vue"
export default {
name: 'pokemon',
components: {
SinglePokemon
},
data () {
return {
id: '',
characters: [],
charactersDetails : [],
search : ""
}
},
methods: {
greet: function(id){
this.id = id.slice(0,-1).split('/').pop();
}
},
mounted(){
let total = this.$http.get(`https://pokeapi.co/api/v2/pokemon`)
.then((data)=>{
this.characters = data.body.results;
}).catch((err)=>{
console.log(err);
})
},
computed: {
filteredPokemon: function(){
return this.characters.filter((character)=> {
return character.name.match(this.search)
})
}
}
}
</script>
我想在传递ID时显示此组件的相关信息
<template>
<div>
<ul class="details">
<li>
Name: {{charactersDetails.name}} {{pid}}
</li>
<li>
Abilities: {{charactersDetails.abilities}}
</li>
<li>
Height: {{charactersDetails.height}}
</li>
<li>
Weight: {{charactersDetails.weight}}
</li>
<li>
Species: {{charactersDetails.species}}
</li>
</ul>
</div>
</template>
<script>
export default {
props: ['name', 'pid'],
data(){
return {
id: this.pid,
charactersDetails : {
name : "",
abilities : "",
height: "",
weight: "",
species: ""
}
}
},
mounted(){
let results = this.$http.get(`https://pokeapi.co/api/v2/pokemon/${this.id}`)
.then((results)=>{
return results.json()
}).then(data => {
this.charactersDetails.abilities = data.abilities[0].ability.name; //ability
this.charactersDetails.name = data.name //name
this.charactersDetails.weight =data.weight //weight
this.charactersDetails.height = data.height //height
this.charactersDetails.species = data.species.name //species name
})
}
}
</script>
答案 0 :(得分:0)
子组件在首次创建时将仅安装一次。此时,pid
的值将是一个空字符串。您应该在开发人员工具的“网络”标签中看到相应的HTTP请求。该请求应该会成功,但是我想您会在控制台中收到错误消息,因为返回的数据没有abilities
属性。
对父级id
属性的后续更改将作为子级pid
的属性向下传递。这应该导致模板使用新的pid
值进行更新,但不会从服务器加载任何其他数据。
有几种方法可以解决此问题。
一种解决方案是在watch
上引入pid
:
watch: {
pid: 'loadDetails'
},
created () {
this.loadDetails()
},
methods: {
loadDetails () {
// TODO: You may want alternative behaviour when pid is empty
if (!this.pid) {
return
}
// Note: this.pid, not this.id
this.$http.get(`https://pokeapi.co/api/v2/pokemon/${this.pid}`)
// ... the rest of your code for loading goes here
}
}
注意:
this.id
更改为this.pid
。您还应该从子组件的id
中删除data
属性。拥有data
属性来复制道具是不必要的,并且可能导致错误。mounted
钩子移到名为loadDetails
的方法中。 mounted
挂钩可以删除。mounted
挂钩中加载数据,而是从created
挂钩中加载数据。您使用哪个并不重要,但是created
对我来说更正确。另外,您可以在immediate
上设置watch
标志,以便在首次创建组件时自动触发它。pid
最初为空,因此在首次创建组件时尝试加载数据是无关紧要的。但是,最好编写该组件使其能够在一般情况下工作,而不仅仅是在您遇到的特定情况下。loadDetails
内部,我选择了pid
失踪时的援助。如果pid
变回空白,则将保留先前的详细信息。目前这可能不是问题,但在一般情况下可能不是正确的行为。let results =
部分。它什么也没做。解决此问题的另一种方法是使用key
。
<SinglePokemon :name="characters.name" :pid="id" :key="id" />
使用key
会告诉Vue销毁组件,并在id
更改时创建一个新组件。新组件将运行其mounted
挂钩,因此将运行您的加载代码。
这似乎是一个更简单的解决方案,但它依赖于组件的父级进行一些魔术处理才能使其正常工作。子组件本身非常脆弱。通常,较早的解决方案将是更可取的,因为它可以使子级更加健壮,并且不需要父级组件的任何特殊帮助。