I have a rather straightforward parent/child component. I am looking to utilize the child component in two ways - first, for adding a new entry and second, for updating an entity.
Here are the components that I've built: https://codepen.io/anon/pen/bJdjyx. In this implementation, I do not use props; instead, I sync the value from the parent to the child using custom events.
Add - Template:
<div id="app">
<v-app>
<v-content>
<v-container grid-list-xl>
<my-address
:addresscompany.sync="addressCompany"
:addressstreet.sync="addressStreet"
></my-address>
<v-btn @click="submit">Submit</v-btn>
</v-container>
</v-content>
</v-app>
</div>
<script type="text/x-template" id="address-template">
<div>
<v-text-field
name="company"
v-model="addressCompany"
@change="updateCompany()">
</v-text-field>
<v-text-field
name="street"
v-model="addressStreet"
@change="updateStreet()">
</v-text-field>
</div>
</script>
Add - Script:
let addressComponent = {
template: '#address-template',
data() {
return {
addressCompany: '',
addressStreet: '',
}
},
methods: {
updateCompany () {
this.$emit('update:addresscompany', this.addressCompany);
},
updateStreet () {
this.$emit('update:addressstreet', this.addressStreet);
}
}
};
new Vue({
el: '#app',
components: {'my-address' : addressComponent},
data() {
return {
addressCompany: '',
addressStreet: '',
}
},
methods: {
submit () {
console.log('Company ' + this.addressCompany);
console.log('Street ' + this.addressStreet);
}
}
})
However, this template does not work for the edit case because I need props to pass the value to the child. Therefore, I have come up with this solution: https://codepen.io/anon/pen/zXGLQG
Update - Template:
<div id="app">
<v-app>
<v-content>
<v-container grid-list-xl>
<my-address
:addresscompany.sync="addressCompany"
:addressstreet.sync="addressStreet"
></my-address>
<v-btn @click="submit">Submit</v-btn>
</v-container>
</v-content>
</v-app>
</div>
<script type="text/x-template" id="address-template">
<div>
<v-text-field
name="company"
:value="addressCompany"
@change="updateCompany()">
</v-text-field>
<v-text-field
name="street"
:value="addressStreet"
@change="updateStreet()">
</v-text-field>
</div>
</script>
Update - Script:
let addressComponent = {
template: '#address-template',
props: ['addressCompany', 'addressStreet'],
data() {
return {
}
},
methods: {
updateCompany () {
this.$emit('update:addresscompany', this.addressCompany);
},
updateStreet () {
this.$emit('update:addressstreet', this.addressStreet);
}
}
};
new Vue({
el: '#app',
components: {'my-address' : addressComponent},
data() {
return {
addressCompany: 'Company',
addressStreet: 'Street',
}
},
methods: {
submit () {
console.log('Company ' + this.addressCompany);
console.log('Street ' + this.addressStreet);
}
}
})
The key difference is that for the update case, I don't use v-model on the child elements as I can't directly change the props. Instead, by using :value, the update event is not triggered.
What is the correct way to use this child component for both add and update operations? Is there a standard Vue approach before resorting to Vuex for these functionalities?
Thank you!