美文网首页
vue2 加载不确定的组件

vue2 加载不确定的组件

作者: IamaStupid | 来源:发表于2021-11-25 10:01 被阅读0次

情形: 有一个项目分PC和H5两部分,PC端打开,左侧是一个模拟的手机界面(空白的div),右侧是一系列的各种组件,比如table样式1组件,table样式2组件...各种组件,把右侧组件拖入空白手机界面,保存后,打开对应的H5链接,就可以看到刚才拖拽的页面。

其中的难点就是,拖入的组件是未知的,又不能提前把组件库上百个组件都提前加载。

// router/index.js


image.png
// all.vue

<template>
<div class="page">
  <p style="padding: 1em; font-size: 30px; text-align: center">
    all
  </p>
  <!--<bg1></bg1>-->
  <LoadComs v-for="(item, i) in comsArr" :key="i"
            :comInfo="item"></LoadComs>
</div>
</template>
<script>
// @ is an alias to /src
// import bg1 from './coms/bg1.vue'
import LoadComs from './coms/LoadComs.vue'
import Vue from 'vue'
export default {
  name: 'all',
  components: {
    // bg1,
    LoadComs
  },
  data () {
    return {
      comsArr: []
    }
  },
  created () {
    console.log(LoadComs, LoadComs.constructor === Vue.component)
    setTimeout(() => {
      this.comsArr = [
        {
          name: 'bg1'
        }
      ]
    }, 1000)
    setTimeout(() => {
      this.comsArr = [
        {
          name: 'bg1',
          props: {
            color: '#f0a00a'
          }
        }
      ]
    }, 3000)
    setTimeout(() => {
      this.comsArr.push({
          name: 'bg1',
          props: {
            color: '#eee',
            children: [
              {
                name: 'bg2',
                props: {
                  color: '#f00',
                  data: []
                }
              },
              {
                name: 'bg3',
                props: {
                  color: '#f1facc',
                  data: []
                }
              }
            ]
          }
        })
    }, 5000)
  }
}
</script>
<style scoped>
</style>


// LoadComs.vue
<script>
import Vue from 'vue'
import myloader from './loadComsVue.js'
export default {
  name: 'load-vue',
  props: {
    comInfo: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  render(createElement) {
    console.log('render::', this.comInfo)

    // 这部分是为了渲染父组件本身
    let comName = this.comInfo.name
    if (!comName) {
      return null
    }
    let com = myloader.loaderVueFile(comName)
    let pComponent = com[comName]
    if (pComponent && pComponent.default) {
      console.log('render~~~', pComponent.default instanceof Vue.component)
      Vue.component(comName, pComponent.default)
    }

    // 这部分是为了把父组件的children渲染做准备,特地分开来写
    let childArr = []
    let propsChildren = (this.comInfo.props && this.comInfo.props.children) || null
    if (Array.isArray(propsChildren) && propsChildren.length > 0) {
      propsChildren.forEach(item => {
        let childCom = myloader.loaderVueFile(item.name)
        let childComponent = childCom[item.name]
        if (childComponent && childComponent.default) {
          let ccxx = Vue.component(item.name, childComponent.default)
          let cc = createElement(item.name, {'props': item.props})
          childArr.push(cc)
          console.log('ccxx', ccxx)
        }
      })
    }

    // context.children = childArr
    return createElement(
      comName,
      {
        props: this.comInfo.props
      },
      [
        ...childArr
      ]
    )
  }
}
</script>

// loadComsVue.js
function loaderVueFile (vueFileName) {
  let arr = null
  if (typeof vueFileName !== 'string') {
    console.error('vue file name is error')
  }
  return {
    [vueFileName]: require('./' + vueFileName)
  }
}

export default {
  loaderVueFile
}

// 组件库里面的组件
// bg1.vue
<template>
<div class="page">
  <p :style="{'background': color}" class="bg1" @click="handleClick">
    bg1
  </p>
  <!-- bg1.vue作为父组件,别忘了加slot -->
  <slot></slot>
</div>
</template>
<script>
// @ is an alias to /src
export default {
  name: 'bg1',
  props: {
    color: String
  },
  created() {
    console.log('created...', this.color)
  },
  mounted() {
    console.log('mounted...', this.color)
  },
  methods: {
    handleClick () {
      console.log(this.color)
    }
  }
}
</script>
<style scoped>
.bg1 {
  padding: 1em; font-size: 30px; text-align: center; background: #f00eee
}
</style>

相关文章

网友评论

      本文标题:vue2 加载不确定的组件

      本文链接:https://www.haomeiwen.com/subject/qaezvltx.html