Vue動態創建組件實例


Vue動態創建組件實例並掛載到body

方式一

import Vue from 'vue'

/**
 * @param Component 組件實例的選項對象
 * @param props 組件實例中的prop
 */
export function create(Component, props) {
  const comp = new (Vue.extend(Component))({ propsData: props }).$mount()
  
  document.body.appendChild(comp.$el)

  comp.remove = () => {
    document.body.removeChild(comp.$el)

    comp.$destroy()
  }

  return comp
}

方式二

import Vue from 'vue'

export function create(Component, props) {
  // 借雞生蛋new Vue({render() {}}),在render中把Component作為根組件
  const vm = new Vue({
    // h是createElement函數,它可以返回虛擬dom
    render(h) {
      console.log(h(Component,{ props }));
      
      // 將Component作為根組件渲染出來
      // h(標簽名稱或組件配置對象,傳遞屬性、事件等,孩子元素)
      return h(Component, { props })
    }
  }).$mount() // 掛載是為了把虛擬dom變成真實dom
  // 不掛載就沒有真實dom
  // 手動追加至body
  // 掛載之后$el可以訪問到真實dom
  document.body.appendChild(vm.$el)

  console.log(vm.$children);
  
  // 實例
  const comp = vm.$children[0]

  // 淘汰機制
  comp.remove = () => {
    // 刪除dom
    document.body.removeChild(vm.$el)

    // 銷毀組件
    vm.$destroy()
  }

  // 返回Component組件實例
  return comp
}

使用

  • A組件(要動態創建的組件)
<template>
  <div class="a">
    <h2>{{ title }}</h2>
    <p>{{ data }}</p>
  </div>
</template>

<script>
export default {
  props: {
    title: {
      type: String,
      default: "hello world!"
    },
    message: {
      type: String,
      default: "o(∩_∩)o 哈哈"
    },
    duration: {
      type: Number,
      default: 1000
    }
  },
  data() {
    return {
      data: "我是a組件",
    };
  },
  created() {
    let num = 1
    
    const timer = setInterval(() => {
      this.data = num++
    }, this.duration)

    this.$once("hook: beforeDestroy", () => clearInterval(timer))
  }
};
</script>

<style>
.a {
  position: fixed;
  width: 100%;
  top: 16px;
  left: 0;
  text-align: center;
  pointer-events: none;
  background-color: #fff;
  border: grey 3px solid;
  box-sizing: border-box;
}
</style>
  • B組件(操作動態創建組件的地方)
<template>
  <div class="b">
    <button @click="createA">創建</button>
  </div>
</template>

<script>
import A from "@/components/A.vue"
import { create } from "@/utils/create.js"
export default {

  components: {
    A,
  },
  methods: {
    createA() {
      // 創建A組件,並掛載到body上
      create(A, { title: "vue", message: "么么噠😙" })
    }
  },
};
</script>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM