javascript - Child Component not updating when parent updates vuejs -
i have vue instance passes object child component. child component has checkbox when clicked calls event vue instance handles update object on parent passed child component. based on vue documentation thought cause child component update related fields. however, date field not updating expect when click on checkbox. in image below, when check management name checkbox, expect current day appear, not seeing date. missing here?
design
parent instance
new vue({ el: "#evaluations-app", data: { evaluation: new evaluation() }, methods: { updateemployeeso: function (newso, newsodate) { this.evaluation.employeeso = newso; this.evaluation.employeesodate = newsodate; }, updatereviewerso: function (newso, newsodate) { this.evaluation.reviewerso = newso; this.evaluation.reviewersodate = newsodate; }, updatemanagementso: function (newso, newsodate) { this.evaluation.managementso = newso; this.evaluation.managementsodate = newsodate; } });
child component
vue.component('sign-off', { props: ['initevaluation', 'perspective'], template: ` <div class="sign-off-comp"> <div class="sign-off-item"> <div class="sign-off-field-1 col-1">{{evaluation.employeename}}</div> <input :disabled="!enableemployeeso" v-model="evaluation.employeeso" class="sign-off-field-2 col-2" type="checkbox" @click="employeesochanged"/> <div class="sign-off-field-3 col-3">{{employeesodate}}</div> </div> <div class="sign-off-item"> <div class="sign-off-field-1 col-1">{{evaluation.reviewername}}</div> <input :disabled="!enablereviewerso" v-model="evaluation.reviewerso" class="sign-off-field-2 col-2" type="checkbox" @click="reviewersochanged"/> <div class="sign-off-field-3 col-3">{{reviewersodate}}</div> </div> <div class="sign-off-item"> <div class="sign-off-field-1 col-1">{{evaluation.managementname}}</div> <input :disabled="!enablemanagementso" v-model="evaluation.managementso" class="sign-off-field-2 col-2" type="checkbox" @click="managementsochanged"/> <div class="sign-off-field-3 col-3">{{managementsodate}}</div> </div> </div> `, data: function () { return { evaluation: this.initevaluation, employeeclicked: false, reviewerclicked: false, managementclicked: false, currentcommentsource: this.perspective } }, methods: { employeesochanged: function () { this.employeeclicked = true; //this.evaluation.employeesodate == null || this.evaluation.employeesodate == "" ? this.evaluation.employeesodate = helpers.getcurrentdate() : this.evaluation.employeesodate = ""; this.$emit('employee-so-changed', this.evaluation.employeeso, this.evaluation.employeesodate); }, reviewersochanged: function () { this.reviewerclicked = true; //this.evaluation.reviewersodate == null || this.evaluation.reviewersodate == "" ? this.evaluation.reviewersodate = helpers.getcurrentdate() : this.evaluation.reviewersodate = ""; this.$emit('reviewer-so-changed', this.evaluation.reviewerso, this.evaluation.reviewersodate); }, managementsochanged: function () { this.managementclicked = true; //this.evaluation.managementsodate == null || this.evaluation.managementsodate == "" ? this.evaluation.managementsodate = helpers.getcurrentdate() : this.evaluation.managementsodate = ""; this.$emit('management-so-changed', this.evaluation.managementso, this.evaluation.managementsodate == null || this.evaluation.managementsodate == "" ? helpers.getcurrentdate() : ""); } }, computed: { enableemployeeso: function () { return (this.perspective == "employee" && !this.evaluation.employeeso) || this.employeeclicked; }, enablereviewerso: function () { return (this.perspective == "reviewer" && !this.evaluation.reviewerso && this.evaluation.employeeso) || this.reviewerclicked; }, enablemanagementso: function () { return (this.perspective == "management" && !this.evaluation.managementso && this.evaluation.reviewerso && this.evaluation.employeeso) || this.managementclicked; }, employeesodate: function () { return this.evaluation.employeesodate != null && this.evaluation.employeesodate == new date("01-01-1900") ? "" : this.evaluation.employeesodate != null && this.evaluation.employeesodate.length >= 10 ? this.evaluation.employeesodate.substring(0, 10) : this.evaluation.employeesodate; }, reviewersodate: function () { return this.evaluation.reviewersodate != null && this.evaluation.reviewersodate == new date("01-01-1900") ? "" : this.evaluation.reviewersodate != null && this.evaluation.reviewersodate.length >= 10 ? this.evaluation.reviewersodate.substring(0, 10) : this.evaluation.reviewersodate; }, managementsodate: function () { return this.evaluation.managementsodate != null && this.evaluation.managementsodate == new date("01-01-1900") ? "" : this.evaluation.managementsodate != null && this.evaluation.managementsodate.length >= 10 ? this.evaluation.managementsodate.substring(0, 10) : this.evaluation.managementsodate; } } });
model
export class evaluation { private _employeename: string; private _employeeso: boolean; private _employeesodate: date; private _reviewername: string; private _reviewerso: boolean; private _reviewersodate: date; private _managementreviewername: string; private _managementreviewerso: boolean; private _managementreviewersodate: date; constructor() { this._employeename = ""; this._employeeso = false; this._employeesodate = new date("01-01-1900"); this._reviewername = ""; this._reviewerso = false; this._reviewersodate = new date("01-01-1900"); this._managementreviewername = ""; this._managementreviewerso = false; this._managementreviewersodate = new date("01-01-1900"); } employeename(): string { return this._employeename; } set employeename(employeename: string) { if (this._employeename != employeename) { this._employeename = employeename; } } employeeso(): boolean { return this._employeeso; } set employeeso(employeeso: boolean) { if (this._employeeso != employeeso) { this._employeeso = employeeso; } } employeesodate(): date { return this._employeesodate; } set employeesodate(employeesodate: date) { if (this._employeesodate != employeesodate) { this._employeesodate = employeesodate; } } reviewername(): string { return this._reviewername; } set reviewername(reviewername: string) { if (this._reviewername != reviewername) { this._reviewername = reviewername; } } reviewerso(): boolean { return this._reviewerso; } set reviewerso(reviewerso: boolean) { if (this._reviewerso != reviewerso) { this._reviewerso = reviewerso; } } reviewersodate(): date { return this._reviewersodate; } set reviewersodate(reviewersodate: date) { if (this._reviewersodate != reviewersodate) { this._reviewersodate = reviewersodate; } } managementreviewername(): string { return this._managementreviewername; } set managementreviewername(managementreviewername: string) { if (this._managementreviewername != managementreviewername) { this._managementreviewername = managementreviewername; } } managementreviewerso(): boolean { return this._managementreviewerso; } set managementreviewerso(managementreviewerso: boolean) { if (this._managementreviewerso != managementreviewerso) { this._managementreviewerso = managementreviewerso; } } managementreviewersodate(): date { return this._managementreviewersodate; } set managementreviewersodate(managementreviewersodate: date) { if (this._managementreviewersodate != managementreviewersodate) { this._managementreviewersodate = managementreviewersodate; } } }
update
i noticed in child component using mangementso
& managementsodate
while model has managementreviewerso
& managementreviewersodate
. changing these fixes code. however, based on discussion below, little confused why putting props local data incorrect way handle situation. can please explain?
there nothing wrong initializing data properties props. think biggest source of confusion in lot of comments here fact initevaluation
object. being case, changes object reflected everywhere object used.
in code in question, evaluation
in parent component, , evaluation
in child component are same object. changes made object will reflected in parent , there no no complaint on vue's part because not technically mutating reference object, changing values of it's properties.
generally, vue throw warning if pass primitive value property. lets passed string value , used value v-model
. in that case, vue throw warning (in development version) mutating property. there 2 reasons warning; first because value not propagated parent (which unexpected behavior), , second, because whenever data changed in parent overwrite changes in child.
when object or array passed property, however, vue complain if change object reference. example in code if this:
this.initevaluation = new evaluation()
vue complain mutating property. in code, changing properties of initevaluation
, not result in warning, , results in values being reflected everywhere because updating same object everywhere.
one of ramifications of this, in code, setting evaluation: this.initevaluation
spurious. could use initevaluation
in template , same results using evaluation
. again, because same object. part of luiz attempting explain. luiz's first sentence misleading in case. data function called once means data initialized properties receive value of property once. however, because initevaluation
object, doesn't matter in question's code. object reference never changes, properties do. if parent change reference reason, evaluation
in child not updated new reference.
whether or not updates being reflected everywhere object desirable debatable. in many cases want control when updates occur. in cases might evaluation: object.assign({}, this.initevaluation)
makes copy of initevaluation
object. advanatage of doing can make many changes want object in child component without changes being reflected outside component. then, after have validated changes correct, can emit changes.
Comments
Post a Comment