[Vuejs]-How to emit an event to uncheck a checkbox

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

Leave a comment