【发布时间】:2017-12-31 12:38:16
【问题描述】:
我有一个将对象传递给子组件的 vue 实例。子组件有一个复选框,单击该复选框时会调用 vue 实例处理的事件,以更新传递给子组件的父对象。基于vue documentation,我认为这会导致子组件更新相关字段。但是,当我单击复选框时,日期字段并没有像我预期的那样更新。在下图中,当我选中管理名称复选框时,我希望会出现当前日期,但我没有看到任何日期。我在这里错过了什么?
设计
父实例
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;
}
});
子组件
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;
}
}
});
型号
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");
}
get EmployeeName(): string {
return this._EmployeeName;
}
set EmployeeName(employeeName: string) {
if (this._EmployeeName != employeeName) {
this._EmployeeName = employeeName;
}
}
get EmployeeSO(): boolean {
return this._EmployeeSO;
}
set EmployeeSO(employeeSO: boolean) {
if (this._EmployeeSO != employeeSO) {
this._EmployeeSO = employeeSO;
}
}
get EmployeeSODate(): Date {
return this._EmployeeSODate;
}
set EmployeeSODate(employeeSODate: Date) {
if (this._EmployeeSODate != employeeSODate) {
this._EmployeeSODate = employeeSODate;
}
}
get ReviewerName(): string {
return this._ReviewerName;
}
set ReviewerName(reviewerName: string) {
if (this._ReviewerName != reviewerName) {
this._ReviewerName = reviewerName;
}
}
get ReviewerSO(): boolean {
return this._ReviewerSO;
}
set ReviewerSO(reviewerSO: boolean) {
if (this._ReviewerSO != reviewerSO) {
this._ReviewerSO = reviewerSO;
}
}
get ReviewerSODate(): Date {
return this._ReviewerSODate;
}
set ReviewerSODate(reviewerSODate: Date) {
if (this._ReviewerSODate != reviewerSODate) {
this._ReviewerSODate = reviewerSODate;
}
}
get ManagementReviewerName(): string {
return this._ManagementReviewerName;
}
set ManagementReviewerName(managementReviewerName: string) {
if (this._ManagementReviewerName != managementReviewerName) {
this._ManagementReviewerName = managementReviewerName;
}
}
get ManagementReviewerSO(): boolean {
return this._ManagementReviewerSO;
}
set ManagementReviewerSO(managementReviewerSO: boolean) {
if (this._ManagementReviewerSO != managementReviewerSO) {
this._ManagementReviewerSO = managementReviewerSO;
}
}
get ManagementReviewerSODate(): Date {
return this._ManagementReviewerSODate;
}
set ManagementReviewerSODate(managementReviewerSODate: Date) {
if (this._ManagementReviewerSODate != managementReviewerSODate) {
this._ManagementReviewerSODate = managementReviewerSODate;
}
}
}
更新
我刚刚注意到,在我的子组件中,我使用了MangementSO 和ManagementSODate,而模型使用了ManagementReviewerSO 和ManagementReviewerSODate。更改这些修复了我的代码。但是,基于下面的讨论,我有点困惑,为什么将 props 放入本地数据是处理这种情况的不正确方法。有人可以解释一下吗?
【问题讨论】:
-
不要在数据函数中存储传递下来的属性,而不是
evaluation.ReviewerName,只需使用initEvaluation.ReviewerName。 -
@AndreyKudriavtsev 为什么我应该避免存储传递下来的属性?在这种情况下,我将同时更改子组件中的 [type]SO 和 [type]SODate 字段。如果我不将这些存储在数据中,那么我将根据文档更新会引发错误的道具。
-
因为您破坏了该属性的“反应性”。您应该直接在方法和计算属性中使用属性,而不是使用本地数据,就像使用
this.evaluation.ReviewerSODate使用this.initEvaluation.ReviewerSODate一样。您不会丢失任何东西,只需将一个变量替换为另一个变量即可。
标签: javascript typescript vue.js vuejs2 vue-component