I am creating a custom checkbox component in Vue, and it is working fine with the data being stored in the root instance. I plan to reuse this component (along with many other components I'm building) in a wide variety of cases. I do not want to have to update or edit the root Vue instance every time I use the component, and want to store the data ONLY in the component itself. The boolean value of checked/unchecked needs to be reactive.
I played around with using a computed value, but could not get that to work either. I am open to using this though if I need to.
(THIS VERSION DOES NOT WORK)
<body>
<script src="https://unpkg.com/vue@2.6.10"></script>
<div id="app">
<checkbox-item v-model="checkData">Active</checkbox-item>
{{ checkData }}
</div>
</body>
</html>
<script>
Vue.component('checkbox-item', {
template: `
<label class="checkbox-item">
<input type="checkbox" :checked="value"
@change="$emit('input', $event.target.checked)"
class="checkbox-input">
<span class="checkbox-label">
<slot></slot>
</span>
</label>
`,
data: function() {
return {
checkData: null
}
},
props: ['value']
})
new Vue({
el: '#app',
})
</script>
(THIS VERSION WORKS, BUT AGAIN I NEED THE DATA TO NOT BE IN THE ROOT INSTANCE)
<body>
<script src="https://unpkg.com/vue@2.6.10"></script>
<div id="app">
<checkbox-item v-model="checkData">Active</checkbox-item>
{{ checkData }}
</div>
</body>
<script>
Vue.component('checkbox-item', {
template: `
<label class="checkbox-item">
<input type="checkbox" :checked="value"
@change="$emit('input', $event.target.checked)"
class="checkbox-input">
<span class="checkbox-label">
<slot></slot>
</span>
</label>
`,
props: ['value']
})
new Vue({
el: '#app',
data: {
checkData: null
}
})
</script>
The error I get is:
[Vue warn]: Property or method "checkData" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
And checkData
is not reactive like it was in the working example.
EDIT: Okay, here's what works! I am definitely going to look into using SFC's and other code organization methods, but for now it's still in one html file. Does anyone see a reason this wouldn't work in the long run?
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<checkbox-item></checkbox-item>
</div>
</body>
</html>
<script>
Vue.component('checkbox-item', {
template: `
<label class="checkbox-item">
<input type="checkbox" v-model="checkData"
class="checkbox-input">
<span class="checkbox-label">
<slot>Active: {{checkData}}</slot>
</span>
</label>
`,
data: function(){
return {
checkData: this.checked
}
},
})
new Vue({
el: '#app',
})
</script>