Javascript Vuejs嵌套动态组件

Javascript Vuejs嵌套动态组件,javascript,vue.js,vuejs2,components,nested-loops,Javascript,Vue.js,Vuejs2,Components,Nested Loops,知道我可能会有更多的孩子,有没有其他方法在VueJS中实现嵌套组件 我事先不知道代码中会有哪个组件,所以我使用动态组件,但它们总是有多个子元素,而且数量并不总是相同的 这是我找到的唯一解决办法 还有别的办法吗 从我的html: <component :is="blocksElements[0].componentId"> <component :is="blocksElements[0].child.componentId" v-if="blocksElements[0

知道我可能会有更多的孩子,有没有其他方法在VueJS中实现嵌套组件

我事先不知道代码中会有哪个组件,所以我使用动态组件,但它们总是有多个子元素,而且数量并不总是相同的

这是我找到的唯一解决办法 还有别的办法吗

从我的html:

<component :is="blocksElements[0].componentId">
    <component :is="blocksElements[0].child.componentId" v-if="blocksElements[0].hasChild">
        <component :is="blocksElements[0].child.child.componentId" v-if="blocksElements[0].child.hasChild" v-bind="blocksElements[0].child.child.props">
            <component :is="blocksElements[0].child.child.child.componentId" v-if="blocksElements[0].child.child.hasChild" v-bind="blocksElements[0].child.child.child.props"></component>
        </component>
    </component>
</component>

是的,存在,使用树菜单,vue.js有一个例子:,这是递归。

您可以使用渲染函数来实现这一点:

下面是一个例子(我写得很快,所以你可以进一步改进):


从“./Row.vue”导入行
从“./Column.vue”导入列
从“./BlockImage.vue”导入BlockImage
导出默认值{
组成部分:{
一行
柱
区块图像
},
数据(){
返回{
区块选择:[
{
componentId:'行',
hasChild:是的,
儿童:{
componentId:'列',
hasChild:是的,
儿童:{
componentId:“块图像”,
hasChild:是的,
道具:{
logo:true,
宽度:“120”
},
儿童:{
componentId:“块图像”,
hasChild:错,
道具:{
标志:假,
宽度:“130”
}
}
}
}
}
]
}
},
渲染:函数(h){
设els=[]
让结果为空
常量buildElementBlocks=函数(el){
el.取消移位(el)
如果(el.hasChild){
返回buildElementBlocks(el.child)
}
结果=h(el.componentId,{props:el.props})
埃尔斯
.拼接(1)
.forEach(元素=>{
结果=h(element.componentId{
道具:element.props
}[结果])
})
}
buildElementBlocks(此.$data.blocksElements[0])
返回结果
}
}

我希望这有帮助

谢谢,但是如果你只有一个组件的话,这就行了,不是吗?我想不出用动态组件实现这一点的方法如果我有一个子数组而不是只有一个子数组,我不知道如何实现你的代码。你能帮忙吗?
blocksElements: [
    {
        componentId: 'row',
        hasChild: true,
        child: {
            componentId: 'column',
            hasChild: true,
            child: {
                componentId: 'block-image',
                hasChild: true,
                props: {
                    logo: true,
                    width: '120'
                },
                child: {
                    componentId: 'block-image',
                    hasChild: false,
                    props: {
                        logo: true,
                        width: '120'
                    }
                }
            }
        }
    }
]
<script>
import Row from './Row.vue'
import Column from './Column.vue'
import BlockImage from './BlockImage.vue'

export default {
  components: {
    Row,
    Column,
    BlockImage
  },
  data () {
    return {
      blocksElements: [
      {
        componentId: 'row',
        hasChild: true,
        child: {
          componentId: 'column',
          hasChild: true,
          child: {
            componentId: 'block-image',
            hasChild: true,
            props: {
              logo: true,
              width: '120'
            },
            child: {
              componentId: 'block-image',
              hasChild: false,
              props: {
                logo: false,
                width: '130'
              }
            }
          }
        }
      }
      ]
    }
  },

  render: function (h) {
    let els = []
    let result = null
    const buildElementBlocks = function (el) {
      els.unshift(el)
      if (el.hasChild) {
        return buildElementBlocks(el.child)
      }
      result = h(el.componentId, { props: el.props })
      els
        .splice(1)
        .forEach(element => {
          result = h(element.componentId, {
            props: element.props
          }, [result])
        })
    }
    buildElementBlocks(this.$data.blocksElements[0])
    return result
  }
}
</script>