简体   繁体   中英

How to use js to dynamically add components and listen to their events in vue3?

I've recently been learning Vue3. I want to add components dynamically, and the parent component can listen to the events of the added chirld components. To make it clear what I want to do, I have written the following code. I want a new button to be added when the mouse moves over any of the buttons. But only the first button actually triggers the hello function, which means that the code "v-on:addButton": hello in line 7 of App.vue doesn't work. I would like to know how to modify the code to meet my requirements, or if there is another easy way to implement this functionality.

Chirld components/Hello.vue

<script setup lang="ts">
  defineProps(['text'])
  defineEmits(['addButton'])
</script>

<template>
  <button @mouseenter="$emit('addButton')">{{text}}</button>
</template>

Father App.vue

<script setup>
  import {createApp} from 'vue'
  import Hello from './components/Hello.vue'
    
  let cnt = 0
  function hello() {
    console.log('you enter a button')
    const app = createApp(Hello, {"text": String(cnt++), "v-on:addButton": hello})
    const newNode = document.createElement('div')
    document.getElementById("rootDiv").append(newNode)
    app.mount(newNode)
  }
</script>

<template>
  <div id="rootDiv">
    <Hello text="0" v-on:addButton="hello"/>
  </div>
</template>

Update:

Thanks for the replies. I found that simply changing "v-on:addButton": hello to onaddButton: hello works.

Manipulating the DOM directly in most cases doesn't work with Vue since you'll loose the reactivity and other binding stuff, another approach is to use cnt variable to render the components using v-for directive ;:


<script setup>
  import {ref} from 'vue'
  import Hello from './components/Hello.vue'
  
  let cnt = ref(0)
  function addBtn() {
     cnt.value++
  }
</script>

<template>
  <div id="rootDiv">
    <Hello v-for="i in cnt" :text="i" v-on:addButton="addBtn"/>
  </div>
</template>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM