Reputation: 195
I want to create my own checkbox in Vue. I want to use two icons from fontawesome (lock and unlock). When my checkbox is checked then icon should be locked otherwise unlocked.
Here is my code:
<template>
<div>
<i @click="statusChanged()" v-if="!checked" class="fas fa-lock-open lock"></i>
<i @click="statusChanged()" v-if="checked" class="fas fa-lock lock"></i>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { Prop } from 'vue/types/options';
export default Vue.extend({
props: {
checked: {
type: Boolean as Prop<boolean>,
},
},
methods: {
statusChanged() {
this.checked = !this.checked;
},
},
});
I received an error:
Cannot assign to 'checked' because it is a constant or a read-only property
Can you help resolve this issue?
Upvotes: 12
Views: 57360
Reputation: 7150
Take a look at the prop.sync
modifier. It is made for exactly this kind of case where you want to update the parents value but pass it as a property to the child:
https://v2.vuejs.org/v2/guide/components-custom-events.html#sync-Modifier
Basically you mark the prop as being sync
'able:
<Checkbox :checked.sync="foo"></Checkbox>
And to update the parent you emit an update:prop
event from the child:
this.$emit('update:checked', !this.checked)
This should get you started for your solution:
https://codesandbox.io/s/97rl86n64
Upvotes: 24
Reputation: 3089
Answer originally edited into question by OP @Marek, copied here by the community.
I was able to resolve the problem. Solution was really similar to what @TommyF suggested.
Here is the solution:
<template>
<div>
<i v-if="!checked" class="fas fa-lock-open lock" @click="statusChanged()"></i>
<i v-if="checked" class="fas fa-lock lock" @click="statusChanged()"></i>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { Prop } from 'vue/types/options';
export default Vue.extend({
props: {
checked: {
type: Boolean as Prop<boolean>,
},
},
model: {
prop: 'checked',
event: 'click',
},
methods: {
statusChanged() {
this.$emit('click', !this.checked);
},
},
});
</script>
Upvotes: 2