Vuejs 嵌套动态组件

Vuejs nested dynamic component

知道我可能会有更多 children,有没有其他方法可以在 VueJS 中做嵌套组件?

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

这是我找到的唯一解决方案 还有其他方法吗?

来自我的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>

来自我的 js:

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'
                    }
                }
            }
        }
    }
]

是的,存在,使用树形菜单,vue.js有一个例子:https://br.vuejs.org/v2/examples/tree-view.html,这是递归。

您可以使用渲染函数来实现:https://vuejs.org/v2/guide/render-function.html

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

<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>

希望对您有所帮助!