Reputation: 2481
Vue suggests to use property-down and event-up pattern to propagate the data between parent and child components. Based on this I created a simple select-box component which lists all USA states and which emits 'state-selected' event. I'm subscribing to this event in my parent class and everything is ok. Here is my code:
<template>
<select v-model="selectedStatus" id="orderStatusSelectBox" class="form-control" name="status" v-on:change="onChange" v-bind:preselectedStatus="filters.selectedStatus">
<option value="" selected="selected" disabled>Select status</option>
<option value="1">New</option>
<option value="2">Scheduling</option>
<option value="3">In production</option>
<option value="4">Completed</option>
<option value="5">On hold</option>
<option value="6">Cancelled</option>
<option value="7">Problem</option>
</select>
</template>
<script>
export default {
data: function () {
return {
selectedStatus: ''
}
},
mounted() {
this.selectedStatus = (this.preselectedStatus ? this.preselectedStatus : '');
},
component: 'select-order-status',
methods: {
onChange() {
this.$emit('statusSelected', this.selectedStatus);
}
},
props: ['preselectedStatus'],
}
</script>
In my parent component apart from this select box child component I have several buttons (quick filters) where you can quickly filter New orders or Completed orders. I added on-click events on those buttons so I can select new status and propagate that value to my child component.
Here is the code:
<template>
<div>
<div class="row filters">
<div class="col-md-12">
<h4>QUICK FILTERS:</h4>
</div>
</div>
<div class="row filters">
<div class="col-md-4">
<div class="row">
<div class="col-md-3">
<button type="button" class="btn btn-yellow m5 fixed-width-btn" v-on:click="statusSelected('1')">New Order</button>
<button type="button" class="btn btn-success m5 fixed-width-btn" v-on:click="statusSelected('4')">Completed</button>
</div>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-md-2">
<div class="form-group">
<order-status-select v-on:statusSelected="statusSelected" v-bind:selectedStatus="filters.selectedStatus"></order-status-select>
</div>
</div>
</div>
<hr>
<span>
<div class="col-md-3">
<div class="form-group">
<select id="agentSelectBox" class="form-control" name="actions">
<option value="" selected="selected">Select action</option>
<option value="1">Action 1</option>
</select>
</div>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-default">Apply</button>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-default">Export CSV</button>
</div>
</div>
</div>
</template>
<script>
import OrderStatusSelectComponent from '../../reusable/OrderStatusSelectComponent.vue';
export default {
data: function () {
return {
filters: {
selectedStatus: '',
resultsPerPage: 10,
currentPage: 1,
},
}
},
mounted() {
},
component: 'filters',
methods: {
search() {
this.$emit('search', this.filters);
},
statusSelected(selectedStatus) {
this.filters.selectedStatus = selectedStatus;
}
},
components: {
'order-status-select': OrderStatusSelectComponent,
},
}
</script>
The problem is, when I click on any button (quick filter) that data is not propageted to child component.
I saw several other posts suggesting Vuex and Vue Bus but is there any other recommended way to handle this problem?
Here is peace of code that is making problems.
<order-status-select v-on:statusSelected="statusSelected" v-bind:selectedStatus="filters.selectedStatus"></order-status-select>
So from my parent component I want to pass filters.selectedStatus
to the child component. When application renders first time status in filters.selectedStatus
is correctly selected in my child component, but when ever I change filters.selectedStatus variable after, that will not reflect in child component.
Upvotes: 0
Views: 63
Reputation: 21485
Your child component is only checking the preselectedStatus on mount
, and after the component has finished mounting it never looks at that property again, even if its value changes.
One way to deal with this is to have the child component watch its properties for changes, and respond as needed:
...
watch: {
preselectedStatus() {
// property value changed:
this.selectedStatus = (this.preselectedStatus ? this.preselectedStatus : '');
}
},
...
Upvotes: 1