Vue.Js, привязка значения к флажку в компоненте

Я делаю компонент, который является оберткой вокруг флажка (я сделал то же самое с вводами типа 'text' и 'number'), но я не могу получить свое переданное значение для правильного связывания.

Мой компонент:

<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>

Я импортировал это глобально; и я вызываю это в другом виде, выполнив:

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

Моя модель находится в данных, а свойство ShowInCalendar является логическим значением, и в моем тестовом случае оно имеет значение true. Поэтому, когда я просматриваю страницу, флажок установлен. Используя инструменты Vue в Firefox, я вижу модель. ShowInCalendar имеет значение true, и флажок установлен. Однако, когда я щелкаю по нему, флажок остается установленным, и значение ShowInCalendar изменяется на 'on', а затем изменяются, не изменяя значение ShowInCalendar.

Я нашел этот пример здесь: https://jsfiddle.net/robertkern/oovb8ym7/ и попытался реализовать локальное свойство данных для него, но результат не работает.

Суть того, что я пытаюсь сделать, - это иметь начальное контрольное состояние флажка, равное ShowInCalendar (или любому другому свойству, связанному с помощью v-модели в компоненте), а затем обновить это свойство (быть истинным или ложным) когда флажок установлен.

Может кто-нибудь предложить мне какой-нибудь совет, пожалуйста?

Спасибо.

4 ответа

Вы не должны $emit event.target.value, это значение флажка, это не логическое значение. Если вы хотите определить, является ли флажок обновлением (быть истинным или ложным) или нет, вам следует $emit event.target.checked как сказал fstep.

Если v-on - единственный прослушиватель, который будет использоваться, возможно, его будет проще использовать v-model как в примере флажка из входных документов Vue.

Однако вы можете использовать прослушиватели на основе документов Binding-Native-Events-to-Components

<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>


Не меняй реквизит. Ваш компонент, имеющий v-model, должен испускать входные события при изменении. Родитель будет обрабатывать фактическое изменение значения.

Испускается при вводе флажка родительскому элементу.

(Vue3, настройка скрипта, Typescript)

Родитель использовал

      <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>

Метод 1 :

:: нет необходимости.

@inputдля@changeй.valueдля.checked:: корректно для ввода флажка ( ).

Компонент Triline.vue

      <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>

Метод 2 (с использованием) :

:: необходимо для.

y:: правильно для ввода флажка ( ).

Компонент Triline.vue

      <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>

Метод 3 :

const checkedo:: необходимо для watch.

@input=@changeй.value=.checked:: корректно для ввода флажка (первые абзацыпервые абзацыпервые абзацы ).

Компонент Triline.vue

      <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>
Другие вопросы по тегам