1👍
✅
Please, take a look at following snippet (no need for emits just use prop):
const { ref, nextTick } = Vue
const app = Vue.createApp({
setup() {
const stat = ref(null)
const myArray = [1,2,3]
const uncheck = () => {
stat.value = false
nextTick(() => stat.value = null)
}
return { stat, myArray, uncheck }
},
})
app.component('child', {
template: `
<input type="checkbox" :checked="status" />
`,
props: ['status'],
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
<button @click="uncheck">Uncheck all boxes!</button>
<div v-for="d in myArray">
<child :status="stat"></child>
</div>
</div>
0👍
To emit events to multiple siblings components, you need register an eventbus as a global property.
const emitter = mitt();
app.config.globalProperties.emitter = emitter;
Button
<script>
export default {
methods: {
click() {
this.emitter.emit('UncheckCheckbox')
}
}
}
</script>
SelectComponent
<script>
export default {
created() {
this.emitter.on('UncheckCheckbox', () => {
//uncheck your checkbox
})
}
}
</script>
Use global eventbus, you can emit/listen event in anywhere.
But i think it is always not a good practices. Make all checkboxes controlled is more compatible with data-view concept.
<button @click="uncheckAll">Uncheck all boxes!</button>
<div v-for="d in myArray">
<SelectComponent :checked="d.checked" />
</div>
<script setup>
const myArray = reactive(new Array(10).fill(0).map({ checked: true }))
const uncheckAll = () => {
myArray.forEach(d => d.checked = false)
}
</script>
SelectComponent
<template>
<input type="checkbox" :checked="checked" @change="emit('change', $event.target.checked)"/>
</template>
<script setup>
const props = defineProps<{
checked: boolean
}>()
const emit = defineEmits<{
(e: 'change', checked: boolean): void
}>()
</script>
const { createApp, reactive } = Vue
const app = createApp({
template: `
<div style="display: flex;justify-content: space-around;">
<span><EventDemo /></span>
<span><VMDemo /></span>
</div>
`
})
app.config.globalProperties.emitter = mitt()
app.component('EventDemo', {
template: `
<h2>Event Demo</h2>
<button @click="toggleAll">Toggle All</button>
<div v-for="d in 10"><EventCheck />{{ d }}</div>
`,
methods: {
toggleAll() {
this.emitter.emit('checkAll')
}
}
})
app.component('EventCheck', {
template: `<input type="checkbox" :checked="checked" />`,
data: () => ({ checked: true }),
created() {
this.emitter.on('checkAll', () => {
this.checked = !this.checked
})
}
})
app.component('VMDemo', {
template: `
<h2>VM Demo</h2>
<button @click="toggleAll">Toggle All</button>
<div v-for="(d, idx) in myArray"><VMCheck :checked="d.checked" />{{ idx + 1 }}</div>
`,
setup() {
const myArray = reactive(new Array(10).fill(0).map(d => ({ checked: true })))
const toggleAll = () => myArray.forEach(d => d.checked = !d.checked)
return { myArray, toggleAll }
}
})
app.component('VMCheck', {
template: `<input type="checkbox" :checked="checked" />`,
props: ['checked']
})
app.mount('#app')
<script src="https://unpkg.com/mitt/dist/mitt.umd.js"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app"></div>
👤lry
Source:stackexchange.com