最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue.Js, binding a value to a checkbox in a component - Stack Overflow

programmeradmin2浏览0评论

I'm making a component which is a wrapper around a checkbox (I've done similar with inputs of type 'text' and 'number') but I cannot get my passed in value to bind correctly.

My component is:

<template>
  <div class="field">
    <label :for="name" class="label">
      {{ label }}
    </label>
    <div class="control">
      <input :id="name" :name="name" type="checkbox" class="control" :checked="value" v-on="listeners" />
    </div>
    <p v-show="this.hasErrors" class="help has-text-danger">
      <ul>
        <li v-for="error in errors" :key="error">{{ error }}</li>
      </ul>
    </p>
  </div>
</template>
<script>
export default {
  name: 'check-edit',
  props: {
    value: {
      type: Boolean,
      default: false
    },
    label: {
      type: String,
      default: ''
    },
    name: {
      type: String,
      default: ''
    },
    errors: {
      type: Array,
      default: () => []
    }
  },
  mounted () {
  },
  computed: {
    listeners () {
      return {
        // Pass all component listeners directly to input
        ...this.$listeners,
        // Override input listener to work with v-model
        input: event => this.$emit('input', event.target.value)
      }
    },
    hasErrors () {
      return this.errors.length > 0
    }
  },
}
</script>

I've imported it globally; and am invoking it in another view by doing:

<check-edit name="ShowInCalendar" v-model="model.ShowInCalendar" label="Show in calendar?" :errors="this.errors.ShowInCalendar"></check-edit>

My model is in data and the property ShowInCalendar is a boolean and in my test case is true. So when I view the page the box is checked. Using the Vue tools in firefox I can see the model.ShowInCalendar is true, and the box is checked. However, when I click it the box remains checked and the value of ShowInCalendar changes to 'on', then changes thereafter do not change the value of ShowInCalendar.

I found this example here: / and have tried to implement a local data property for it but the result is not working.

The crux of what I'm trying to do is have the initial checkstate of the checkbox be that of ShowInCalendar (or whatever property is bound via v-model on the component) and then have that property be update (to be true or false) when the checkbox is checked.

Can anyone offer me any advice please?

Thank you.

I'm making a component which is a wrapper around a checkbox (I've done similar with inputs of type 'text' and 'number') but I cannot get my passed in value to bind correctly.

My component is:

<template>
  <div class="field">
    <label :for="name" class="label">
      {{ label }}
    </label>
    <div class="control">
      <input :id="name" :name="name" type="checkbox" class="control" :checked="value" v-on="listeners" />
    </div>
    <p v-show="this.hasErrors" class="help has-text-danger">
      <ul>
        <li v-for="error in errors" :key="error">{{ error }}</li>
      </ul>
    </p>
  </div>
</template>
<script>
export default {
  name: 'check-edit',
  props: {
    value: {
      type: Boolean,
      default: false
    },
    label: {
      type: String,
      default: ''
    },
    name: {
      type: String,
      default: ''
    },
    errors: {
      type: Array,
      default: () => []
    }
  },
  mounted () {
  },
  computed: {
    listeners () {
      return {
        // Pass all component listeners directly to input
        ...this.$listeners,
        // Override input listener to work with v-model
        input: event => this.$emit('input', event.target.value)
      }
    },
    hasErrors () {
      return this.errors.length > 0
    }
  },
}
</script>

I've imported it globally; and am invoking it in another view by doing:

<check-edit name="ShowInCalendar" v-model="model.ShowInCalendar" label="Show in calendar?" :errors="this.errors.ShowInCalendar"></check-edit>

My model is in data and the property ShowInCalendar is a boolean and in my test case is true. So when I view the page the box is checked. Using the Vue tools in firefox I can see the model.ShowInCalendar is true, and the box is checked. However, when I click it the box remains checked and the value of ShowInCalendar changes to 'on', then changes thereafter do not change the value of ShowInCalendar.

I found this example here: https://jsfiddle.net/robertkern/oovb8ym7/ and have tried to implement a local data property for it but the result is not working.

The crux of what I'm trying to do is have the initial checkstate of the checkbox be that of ShowInCalendar (or whatever property is bound via v-model on the component) and then have that property be update (to be true or false) when the checkbox is checked.

Can anyone offer me any advice please?

Thank you.

Share Improve this question asked Feb 28, 2019 at 23:25 Stan EdStan Ed 1341 gold badge1 silver badge7 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 13

You should not $emit event.target.value, it's the value of the checkbox, it's not a Boolean value. If you want to detect the checkbox is update(to be true or false) or not, You should $emit event.target.checked just like fstep said.

If v-on is the only listener that will be used it might be easier to use v-model as in the checkbox example from the Vue input docs.

However you can use listeners based on Binding-Native-Events-to-Components docs

<template>
  <div class="field">
    <label :for="name" class="label">
      {{ label }}
    </label>
    <div class="control">
      <input :id="name" :name="name" type="checkbox" class="control" checked="value" v-on="listeners" />
    </div>
    <p v-show="this.hasErrors" class="help has-text-danger">
      <ul>
        <li v-for="error in errors" :key="error">{{ error }}</li>
      </ul>
    </p>
  </div>
</template>
<script>
export default {
    name: 'check-edit',
    props: {
        value: {
            type: Boolean,
            default: false
        },
        label: {
            type: String,
            default: ''
        },
        name: {
            type: String,
            default: ''
        },
        errors: {
            type: Array,
            default: () => []
        }
    },
    mounted() {},
    computed: {
        listeners() {
            var vm = this;
            // `Object.assign` merges objects together to form a new object
            return Object.assign(
                {},
                // We add all the listeners from the parent
                this.$listeners,
                // Then we can add custom listeners or override the
                // behavior of some listeners.
                {
                    // This ensures that the component works with v-model
                    input: function(event) {
                        vm.$emit('input', event.target.checked);
                    }
                }
            );
        },
        hasErrors() {
            return this.errors.length > 0;
        }
    }
};
</script>


Don't change props. Your component, having a v-model, should be emitting input events on change. The parent will handle the actual changing of the value.

Emits from a checkboox input to parent.

(Vue3, Script setup, Typescript)

Parent used

<script setup lang="ts">

import { ref } from 'vue'
import Triline from './Triline.vue'

const aa= ref(false)

</script>

<template>
    <div style="color: aliceblue;">
       <Triline @on-checked="aa=$event"/>
       {{aa}}
    </div>
</template>

Metode 1:

const checkedo:: isnt necessary.

@input for @change y .value for .checked:: is correct for checkbox input (firts paragraphs).

Triline.vue component

<script setup lang="ts">

import { ref} from 'vue'

const checkedo= ref(false);

const emit = defineEmits<{
(e:"onChecked",v:boolean):void}>()

</script>

<template>
    <div class="triline">
  
        <input type="checkbox" id="checkbox"
        :value="checkedo"
        @change="$emit('onChecked',checkedo =($event.target as HTMLInputElement).checked)"
        >
        <label for="checkbox">{{ checkedo }}</label>
    </div>
</template>

Metode 2 (using watch):

const checkedo:: is necessary for the watch.

@input=@change y .value=.checked:: is correct for checkbox input (firts paragraphs).

Triline.vue component

<script setup lang="ts">

import { ref, watch } from 'vue'

const checkedo= ref(false);

const emit = defineEmits<{
(e:"onChecked",v:boolean):void}>()

watch(checkedo, () => {
      emit("onChecked", checkedo.value);
})

</script>

<template>
    <div class="triline">
  
        <input type="checkbox" id="checkbox"
        :value="checkedo"
        @change="event => checkedo=(event.target as HTMLInputElement).checked"
        >
        <label for="checkbox">{{ checkedo }}</label>
    </div>
</template>

Metode 3:

const checkedo:: is necessary for the watch.

@input=@change y .value=.checked:: is correct for checkbox input (firts paragraphs).

Triline.vue component

<script setup lang="ts">

import { ref, watch} from 'vue'

const checkedo= ref(false);

const emit = defineEmits<{
(e:"onChecked",v:boolean):void}>()

watch(checkedo, () => {
      emit("onChecked", checkedo.value);
})

</script>

<template>
    <div class="triline">
  
        <input type="checkbox" id="checkbox"
        v-model="checkedo"
        >
        <label for="checkbox">{{ checkedo }}</label>
    </div>
</template>
发布评论

评论列表(0)

  1. 暂无评论