For the code posted below vue
component it is a child component and is hosted in a specific parent. When I make two ways binding via vModelCheckGeoTIFFOverlayBandAverages
by introducing a change to compPropsVModelCheckGeoTIFFOverlayBandAverages
, the changes
do not get reflected in the parent component.
Am I making the binding of the checkbox
wrong
code:
<template>
<cds-checkbox id="idCheckboxGeoTIFFOverlayBandAveragesContainer">
<label id="idTextGeoTIFFOverlayBandAverages">{{ tempTextBandAverages }}</label>
<input
type="checkbox"
:value="compPropsVModelCheckGeoTIFFOverlayBandAverages"
@input="$emit('update:compPropsVModelCheckGeoTIFFOverlayBandAverages', $event.target.checked)"
:disabled="isCheckboxGeoTIFFOverlayBandAveragesDisabled"
:checked="compPropsVModelCheckGeoTIFFOverlayBandAverages"
@change="onCheckboxGeoTIFFOverlayBandAveragesChanged"
/>
</cds-checkbox>
</template>
<script>
import { GeoTIFFOverlaySettingsConstants } from '../../../resources/....';
import { StoreOnCheckboxBandAveragesStatusChanged } from '../../../../../...';
let msg = null;
export default {
name: 'SentinelHubGeoTIFFOverlayBand1',
data() {
return {
refStoreOnCheckboxBandAveragesStatusChanged: StoreOnCheckboxBandAveragesStatusChanged,
isCheckboxChecked: false,
tempTextBandAverages: GeoTIFFOverlaySettingsConstants.CONST_STRING_BAND_1_AVERAGES.description,
};
},
components: {},
props: {
isCheckboxGeoTIFFOverlayBandAveragesDisabled: {
type: Boolean,
default: true,
},
vModelCheckGeoTIFFOverlayBandAverages: {
type: Boolean,
default: null,
},
},
emits: {
'update:vModelCheckGeoTIFFOverlayBandAverages':null,
},
computed: {
compPropsVModelCheckGeoTIFFOverlayBandAverages: {
get() {
return this.vModelCheckGeoTIFFOverlayBandAverages;
},
set(value) {
this.$emit('update:vModelCheckGeoTIFFOverlayBandAverages', value);
},
},
},
watch: {
isCheckboxChecked(newVal, oldVal) {
this.compPropsVModelCheckGeoTIFFOverlayBandAverages = newVal;
},
},
methods: {
async onCheckboxGeoTIFFOverlayBandAveragesChanged() {
this.isCheckboxChecked = !this.isCheckboxChecked;
await this.refStoreOnCheckboxBandAveragesStatusChanged.actions.init();
this.refStoreOnCheckboxBandAveragesStatusChanged.setters.set(this.isCheckboxChecked);
},
},
};
</script>
explained above in the question
An input emits update:compPropsVModelCheckGeoTIFFOverlayBandAverages
event, while the name of the event is update:vModelCheckGeoTIFFOverlayBandAverages
. This shows the problem with long naming. v-model
already suggests the convention, "modelValue" prop and "update:modelValue" event. As long as a component deals with one value, these names are unambiguous and can be conventionally used.
It's still beneficial to use it with v-model
with native elements like input
instead of direct use of props and events because this allows to skip low-level details like $event.target.checked
and make code shorter and less error-prone.
It's unclear if the component requires to have its own local state. If it's not needed, there's no need for data()
for component state, and the names can be kept short and intelligible:
<label id="idTextGeoTIFFOverlayBandAverages">{{ labelText }}</label>
<input
type="checkbox"
v-model="isChecked"
:disabled="disabled"
/>
and
props: {
modelValue: {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
},
emits: {
'update:modelValue':null,
},
data() {
return {
labelText: GeoTIFFOverlaySettingsConstants.CONST_STRING_BAND_1_AVERAGES.description,
};
},
computed: {
isChecked: {
get() {
return this.modelValue;
},
set(value) {
this.$emit('update:modelValue', value);
},
},
},
watch: {
isChecked(newVal, oldVal) {
// can be used to do anything on value updates, e.g. sync a store
},
}
And is supposed to be used as:
Or without v-model
, the usage is more straightforward than with input
:
<SentinelHubGeoTIFFOverlayBand1
:modelValue="someValue"
@update:modelValue="updateSomeValue"
:disabled="someDisabled"/>