After copy the Click button
, the copy Click
button does not work.
<template>
<div>
<div id="container" ref="container">
<button @click="handleClick">Click Me</button>
</div>
<div id="clip" ref="clip"></div>
<button @click="copyContent">Copy Content</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const container = ref<HTMLDivElement | null>(null)
const clip = ref<HTMLDivElement | null>(null)
function handleClick() {
console.log('Clicked')
}
function copyContent() {
if (container.value && clip.value) {
// copy container outerHTML to clip innerHTML
clip.value.innerHTML = container.value.outerHTML
}
}
</script>
<style>
#container,
#clip {
margin-bottom: 10px;
}
button {
margin-right: 10px;
}
</style>
I fix the problem by adding a click event to copy click
button.
<template>
<div>
<div id="container" ref="container">
<button @click="handleClick">Click Me</button>
</div>
<div id="clip" ref="clip"></div>
<button @click="copyContent">Copy Content</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const container = ref<HTMLDivElement | null>(null)
const clip = ref<HTMLDivElement | null>(null)
function handleClick() {
console.log('Clicked')
}
function copyContent() {
if (container.value && clip.value) {
// copy container outerHTML to clip innerHTML
clip.value.innerHTML = container.value.outerHTML
// fix the problem,is work
const button = clip.value.querySelector('button')
button!.addEventListener('click', handleClick)
}
}
</script>
<style>
#container,
#clip {
margin-bottom: 10px;
}
button {
margin-right: 10px;
}
</style>
I wonder why vue3 is not working?
How can I use vue3 to solve the problem?
Vue's way to do anything is to work with VDOM and vnodes, so you just create a component that could return its slot and you use the slot a functional component:
<template>
<div>
<copy ref="$copy">
<div id="container">
<button @click="handleClick">Click me</button>
</div>
</copy>
<div id="clip"><component :is="clip"/></div>
<button @click="clip = () => $copy.getSlot()()">Copy Content</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Copy from './Copy.vue';
const clip = ref(null);
const $copy = ref();
function handleClick() {
alert('click')
}
</script>
Copy.vue
<script setup>
import {useSlots} from 'vue';
const slots = useSlots();
defineExpose({
getSlot(name = 'default'){
return slots[name];
}
});
</script>
<template>
<slot />
</template>
A functional approach:
<template>
<div>
<copy ref="$copy">
<div id="container">
<button @click="handleClick">Click me</button>
</div>
</copy>
<div id="clip"><component :is="clip"/></div>
<button @click="clip = () => $copy.getSlot()()">Copy Content</button>
</div>
</template>
<script setup lang="ts">
import { ref, useSlots } from 'vue';
const Copy = {
setup(_, {expose}) {
const slots = useSlots();
expose({getSlot: (name = 'default') => slots[name]});
return () => slots.default();
}
}
const clip = ref(null);
const $copy = ref();
function handleClick() {
alert('click')
}
</script>