Reputation: 13192
My parent component like this :
<template>
<div ref="modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content modal-content-data">
<form id="form-data">
...
<location-select .../>
...
</form>
</div>
</div>
</div>
</template>
<script>
import LocationSelect from './LocationSelect.vue'
export default{
name: 'CartModal',
components:{
LocationSelect,
},
mounted(){
$(this.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
}
}
</script>
If modal hidden, it will reset data in parent component and it works
I want to reset data also in child component
I try like this :
<template>
<select class="form-control" v-model="selected" ...>
...
</select>
</template>
<script>
export default{
name: 'LocationSelect',
...
created() {
$(this.$parent.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
}
};
</script>
But it does not work
The child component no reset the data
How can I solve this problem?
Upvotes: 3
Views: 8583
Reputation: 82499
The main problem with this code is the handler in LocationSelect
is being added before this.$parent.$refs.modal
exists. A ref
does not exist until the component is mounted.
The easiest way to solve this would be to move the code to mounted
.
mounted() {
$(this.$parent.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
}
Or you could leave it in created
and use nextTick
.
created() {
this.$nextTick(() => {
$(this.$parent.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
})
}
Another way to handle this would be to add a ref
to the LocationSelect
component and add a method that clears it that can be called from the parent. In LocationSelect
add this method:
methods:{
clear(){
Object.assign(this.$data, this.$options.data())
}
}
In the parent template add a ref:
<location-select ref="locationSelect" ... />
And in your parent's mounted:
mounted(){
$(this.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
this.$refs.locationSelect.clear()
})
}
However, the most idiomatic way to handle this with Vue would be to modify the component to support v-model
and then it would be automatically cleared when the parent is cleared.
<template>
<select class="form-control" v-model="selected" ...>
...
</select>
</template>
<script>
export default {
props: ["value"],
name: 'LocationSelect',
computed:{
selected:{
get(){ return this.value },
set(v) { this.$emit('input', v) }
}
},
};
</script>
And then in the parent template:
<location-select v-model="someDataValue" ... />
If you did this, then when the parent is clear, the child is automatically cleared as well.
Upvotes: 2