我一直在搜索SO和Vue论坛上的任何与递归组件相关的问题,当我最终尝试了一些错误时,它会导致另一个错误,所以这里是分解:
我有一个 Contents.vue 组件,里面有 Item.vue :
<template>
<div class="content__wrapper wrapper" :class="{'expanded-content': state.expansion}">
<p v-if="liked && items.length === 0" class="title">{{ data.defaults.add_liked }}</p>
<p v-if="!liked && assemble_contents_array.length === 0" class="title">{{ data.defaults.products_missing }}</p>
<Item v-for="(item, index) in liked ? items : assemble_contents_array" :key="`item-${index}`" :full_data="items" :item_data="item" :ind="index"
:expand="state.item_for_expansion === index" :is_expansion="state.expansion" :defaults="data.defaults"
:is_similar_item="false"/>
</div>
</template>
<script>
import Item from './Item'
export default {
props: ["data", "items", "content_categories", "liked"],
data(){
return{
state:{
item_for_expansion: null,
expansion: false
}
}
},
computed:{
assemble_contents_array(){
if(!this.liked){
let contenst_array = []
this.content_categories.sub_categories
.map(type => this.data[this.content_categories.category][type])
.forEach(e => e.forEach(c => contenst_array.push(c)))
return contenst_array
}
}
},
created(){
this.$eventHub.on("expand_item", index => {
if(index === "")
this.state.expansion = false
else
this.state.expansion = true
this.state.item_for_expansion = index
})
},
components:{
Item
}
}
</script>
以下是 Item.vue ,其中包含 Similar-items.vue :
<template>
<div class="item__wrapper" :class="{'expanded': expand, 'shrink' : !expand && is_expansion}">
<div v-if="expand">
<span class="item__close" @click="expansion">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M23 20.168l-8.185-8.187 8.185-8.174-2.832-2.807-8.182 8.179-8.176-8.179-2.81 2.81 8.186 8.196-8.186 8.184 2.81 2.81 8.203-8.192 8.18 8.192z"/>
</svg>
</span>
<Gallery :main="item_data.img" :images="item_data.images"/>
<Checkout v-if="defaults.shop" :data="item_data" :defaults="defaults" class="right-panel"/>
<Summary v-else :data="item_data" :defaults="defaults" class="right-panel"/>
<div class="item__description">
<p v-if="item_data.type">
{{ defaults.further_reading }}
</p>
<div v-html="item_data.desc">
{{ item_data.desc }}
</div>
</div>
<SimilarItems :data="full_data"/>
</div>
<div v-else>
<svg v-if="!state.liked" @click="add_to_liked" class="item__like" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.653 19.415c-1.162 1.141-2.389 2.331-3.653 3.585-6.43-6.381-12-11.147-12-15.808 0-4.005 3.098-6.192 6.281-6.192 2.197 0 4.434 1.042 5.719 3.248 1.279-2.195 3.521-3.238 5.726-3.238 3.177 0 6.274 2.171 6.274 6.182 0 1.269-.424 2.546-1.154 3.861l-1.483-1.484c.403-.836.637-1.631.637-2.377 0-2.873-2.216-4.182-4.274-4.182-3.257 0-4.976 3.475-5.726 5.021-.747-1.54-2.484-5.03-5.72-5.031-2.315-.001-4.28 1.516-4.28 4.192 0 3.442 4.742 7.85 10 13l2.239-2.191 1.414 1.414zm7.347-5.415h-3v-3h-2v3h-3v2h3v3h2v-3h3v-2z"/></svg>
<svg v-else @click="add_to_liked" class="item__like" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15.582 19.485c-1.141 1.119-2.345 2.287-3.582 3.515-6.43-6.381-12-11.147-12-15.808 0-4.005 3.098-6.192 6.281-6.192 2.197 0 4.434 1.042 5.719 3.248 1.279-2.195 3.521-3.238 5.726-3.238 3.177 0 6.274 2.171 6.274 6.182 0 1.577-.649 3.168-1.742 4.828l-1.447-1.447c.75-1.211 1.189-2.341 1.189-3.381 0-2.873-2.216-4.182-4.274-4.182-3.257 0-4.976 3.475-5.726 5.021-.747-1.54-2.484-5.03-5.72-5.031-2.315-.001-4.28 1.516-4.28 4.192 0 3.442 4.742 7.85 10 13l2.168-2.121 1.414 1.414zm7.418-5.485h-8v2h8v-2z"/></svg>
<div @click="expansion">
<img :src="item_data.img" class="item__image">
<p class="item__title">{{ item_data.name }}</p>
<p class="item__price" v-if="item_data.type">${{ item_data.price }}</p>
</div>
</div>
</div>
</template>
<script>
import Gallery from './utils/gallery'
import Checkout from './utils/checkout'
import Summary from './utils/summary'
import SimilarItems from './utils/similar-items'
export default {
name: "Item",
props: [ "full_data", "item_data", "ind", "expand", "is_expansion", "defaults", "is_similar_item"],
data(){
return{
state:{
get_parent_height: 0,
scrolled_depth: 0,
liked: this.item_data.liked === undefined ? false : this.item_data.liked
}
}
},
methods:{
/*
* Adds item to liked
*/
add_to_liked(){
this.state.liked = !this.state.liked
this.$eventHub.emit("adjust_liked", this.state.liked)
this.$eventHub.emit("add_or_delete_item", this.item_data, this.state.liked, "liked_items")
},
/*
* Expands the item to show detail page
*/
expansion(){
if(this.expand){
this.$eventHub.emit("clear_size")
}
else{
this.state.scrolled_depth = document.querySelector("html").scrollTop
}
this.$eventHub.emit(this.is_similar_item ? "expand_similar_item" : "expand_item", this.expand ? "" : this.ind)
// Scroll to previously scrolled
setTimeout( _ => document.querySelector("html").scrollTop = !this.expand ? this.state.scrolled_depth : 0, 100)
}
},
beforeUpdate(){
this.state.liked = this.item_data.liked === undefined ? false : this.item_data.liked
},
components:{
Gallery,
Checkout,
Summary,
SimilarItems
}
}
</script>
现在最后,这里有 Similar-items.vue ,其中再次包含 Item.vue :
<template>
<div class="similar-items">
<Item v-for="(item, ind) in data" :key="'similar-item-'+ind" class="similar-items__item" :data="item" :ind="ind"
:expand="state.item_for_expansion === ind" :is_expansion="state.expansion" :defaults="data.defaults"
:is_similar_item="true" :is_firts="false"/>
</div>
</template>
<script>
import Item from '../Item'
export default {
props: ["data"],
name: "similar-items",
data(){
return{
state:{
item_for_expansion: null,
expansion: false
}
}
},
methods: {
},
created(){
this.$eventHub.on("expand_similar_item", index => {
if(index === "")
this.state.expansion = false
else
this.state.expansion = true
this.state.item_for_expansion = index
})
},
components:{
Item
}
}
</script>
哪位给了我:
Unknown custom element: <Item> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
所以我尝试添加:
beforeCreate() {
this.$options.components.Item = require('./Item').default
}
到 Contents.vue ,我删除了import Item
和components: { Item }
,但我在 Similar-items.vue <中保留了相同的内容/ p>
这给了我这个错误:Unknown custom element: <Item> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
然后我尝试添加:
beforeCreate() {
this.$options.components.Item = require('../Item')
},
到 Similar-items.vue 并删除import Item
和components: { Item }
这给了我:Failed to mount component: template or render function not defined.
简而言之, Contents.vue 里面有 Item.vue ,里面有 Similar-items.vue ,在其中有 Item.vue ,以及递归发生的地方。
现在我有点迷失了。
就像一个FYI:我已经尝试了一个有条件的 Similar-items.vue 来强调 Item.vue ,但仍然没有用。
答案 0 :(得分:0)
首先,您应该在Item.vue中的SimilarItems组件上设置条件渲染,以防止渲染循环。如果当前已迭代的项目已经是类似项目,我们不希望显示更多项目。
<SimilarItems v-if="!is_similar_item" :data="full_data"/>
导入Vue组件时,请务必详细说明扩展文件。如果在您的文件夹中,您有一个像这样的独立组件:
导入将首先选择.js,这可能只包含您的脚本而没有模板键。