I had a similar issue using props with checkbox to support 2 and 3 states .
to handle this I used computed property with getter and setter using Vuetify checkbox
Here is my example
<template>
<v-container class="checkbox-container">
<v-checkbox
type="checkbox"
:indeterminate="indeterminate"
:color="indeterminate ? '#767575' : 'success'"
v-model="internalState"
@click.stop="onCheckbox"
@keyup.space.prevent="onCheckbox"
></v-checkbox>
</v-container>
</template>
<script>
/**
* Responsability: boolean field editor checkbox
* When @threeState is true : following states (check, uncheck, indeterminate) otherwise (check, uncheck)
* @checkboxState is an external state where it contains always the current state of checkbox
**/
export default {
model: {
// v-model prop
prop: 'checkboxState',
},
props: {
threeState: Boolean,
/**
* Init state is the starting state Which the chekbox starts from.
* by defining initstate it will ignore the default input @boolProperty
**/
initState: {
type: String,
default: 'false',
},
// Reperesent the value of checked state in model
config: {
type: Object,
default: () => ({
checked: 'true',
unchecked: 'false',
indeterminate: null,
}),
},
checkboxState: {
type: String,
},
},
data() {
return {
internalState: this.checkboxState,
indeterminate: false,
}
},
computed: {
state: {
get() {
return this.checkboxState
},
set(newState) {
this.changeCheckboxState(newState)
},
},
},
// Change the state of checkbox after DOM is mounted
mounted() {
this.changeCheckboxState(this.initState)
},
methods: {
changeCheckboxState(state) {
this.$vnode.data.model.callback(state)
this.internalState = state === this.config.checked
this.indeterminate = state === this.config.indeterminate
},
onCheckbox() {
if (this.threeState) {
switch (this.state) {
case this.config.unchecked:
this.state = this.config.checked
break
case this.config.checked:
this.state = this.config.indeterminate
break
case this.config.indeterminate:
this.state = this.config.unchecked
break
}
} else {
this.state = (!(this.state === this.config.checked)).toString()
}
},
},
}
</script>
<style lang="scss" scoped>
.checkbox-container {
width: 50px;
}
</style>