vue 注册动态组件

component 标签

  • 优点:简单
  • 缺点:多个组件是需要写多个的import和components声明
<div id="app">
    <component :is="currentView"></component>
    <button @click="handleChangView('A')">切换到A</button>
    <button @click="handleChangView('B')">切换到B</button>
    <button @click="handleChangView('C')">切换到C</button>
</div>
import comA from './components/comA'
import comB from './components/comB'
import comC from './components/comC'
components:{comA,comB,comC},

data: {
    currentView: 'comA'
},
methods: {
    handleChangView (component) {
        this.currentView = 'com' + component;
    }
}
复制代码

Vue.component

  • 优点:代码量少
  • 缺点:全局注册
<main-content v-if="isMainShow"/>

import Vue from 'vue'

isMainShow: false,

/** 统一加载注册组件资源 */
registerMainComponent(com) {
  // com 为组件的文件名
  this.isMainShow = false
  const body = require('@/views/pages/components/' + com)
  Vue.component('main-content', body)
  this.isMainShow = true
}
复制代码

完整的全局注册组件方法

/**
   * 动态注册组件
   * @param {*} tpl = {name:'',template:'',data:'',methods:''}
   * @param {*} tpl = {name:'aaa',template:'<el-input v-model="input" placeholder="请输入内容"></el-input>',data:{"input": "111"},methods:'click(){alter('123')}'}
   data的格式很容易出错
   */
  Vue.prototype.asyncComponent = function(tpl) {
    tpl.elname = 'async-component'
    return new Promise(async(resolve, reject) => {
      const validate = await asyncComponent_validate(tpl)
      if (validate) {
        const params = {
          elname: tpl.elname,
          template: tpl.template,
          data: tpl.data,
          methods: tpl.methods
        }
        Vue.component(params.elname, function(resolve, reject) {
          setTimeout(function() {
            resolve({
              data: () => {
                return params.data
              },
              template: params.template,
              methods: eval('(' + params.methods + ')')
            })
          }, 500)
        })
        const cssText = tpl.style
        const style = document.createElement('style')
        style.innerText = cssText
        document.head.appendChild(style)
        resolve(true)
      } else {
        resolve(false)
      }
    })
  }
  function asyncComponent_validate(tpl) {
    const params = ['elname', 'template', 'data', 'methods']
    let result = true
    params.forEach((i) => {
      if (!tpl.hasOwnProperty(i)) {
        Message({
          message: '动态注册组件 {' + i + '} 未定义',
          type: 'warning'
        })
        result = false
      }
    })
    return result
  }
复制代码

利用异步加载require + component标签

  • 优点:局部注册,代码量少
<template>
    <div>
        <component v-for="app in comps" :is="initPath(app)"></component>
    </div>
</template>
<script>
  export default {
    data () {
      return {
        comps: ['comp1', 'comp2'],
      }
    },
    created () {
    },
    methods:{
        initPath (name) {
            <!--vue-cli2不需要加.default-->
            <!--vue-cli3工程需要加.default,否则报错:Failed to mount component: template or render function not defined.-->
            return require(`./components/${name}.vue`).default
        }
    }

  }
</script>
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享