在我们平常的开发中组件递归很常见,一般情况下递归有两种类型,一种是自递归如:A->A->A,另一种是相互递归如:A->B->A。对于A->A单个组件自递归的情况,vue推荐使用name来解决,用法非常简单。
// component A
<template>
<div>
<componentA/>
</div>
</template>
<script>
export default{
name:'componentA'
}
</script>
但是对于A-B-A 两个组件相互递归调用的方式,name并不能很好的处理,如果在B組件直接使用A組件会显示组件未注册,而使用相互引入的方式,也会报未注册。
// component A
<template>
<div>
组件A
<componentB/>
</div>
</template>
<script>
import componentB from './componentB'
export default{
component:{
componentB
}
}
</script>
// component B
<template>
<div>
组件B
<componentA/>
</div>
</template>
<script>
import componentA from './componentA'
export default{
component:{
componentA
}
}
</script>
以上写法会报错,说组件A未定义,那么对于这种需求如何解决呢?
这里有两种解决方式
方法1.配合name 使用solt将组件传递过去
方法2.全局注册A组件
假设数据接口是这样个可以无限层次的JSON
[
{
name: "item1",
children: [
{
name: "item1-1",
},
{
name: "item1-2",
children: [
{
name: "item1-1-1",
},
],
},
],
},
{
name: "item2",
children: [
{
name: "item2-1",
},
{
name: "item2-2",
},
],
},
],
方法一:name + slot
将当前组件已slot的形式传递给子组件。
//A组件
<template>
<div>
组件A
<div v-for="(item,key) in data" >
<componentB :key="key" :data="item" >
<template v-slot="scope">
<componentA :data="scope.data"></componentA>
</template>
</componentB>
</div>
</div>
</template>
<script>
import componentB from './componentB.vue'
export default {
name: 'componentA',
props:['data'],
components:{
componentB
}
}
</script>
// component B
<template>
<div >
组件B {{data.name}}
<slot :data="data.children"></slot>
</div>
</template>
<script>
export default {
name: 'componentB',
props:['data'],
}
</script>
方法二:全局组件
全局注册A组件后就不会再报A未注册了
//main.js
import Vue from 'vue'
import App from './App.vue'
import componentA from './componentA'
Vue.component('componentA',componentB)
new Vue({
render: h => h(App),
}).$mount('#app')
接下来组件正常使用就可以了
//A组件
<template>
<div >
组件A
<div v-for="(item,key) in data" >
<componentB :key="key" :data="item" ></componentB>
</div>
</div>
</template>
<script>
import componentB from './componentB.vue'
export default {
name: 'componentA',
props:['data'],
components:{
componentB
}
}
</script>
// component B
<template>
<div>
组件B {{data.name}}
<componentA :data="data.children">
</div>
</template>
<script>
export default {
name: 'componentB',
props:['data'],
}
</script>