我对 Vue 还很陌生,很难弄清楚如何解决这个问题。我在一个深入的项目上已经走了很远,但是我正在努力解决应该是一个简单的功能......
简要背景/概述:
我从 API(我自己的)获取数据,该 API 获取用户创建的研究。他们可以切换到另一项研究,这会更改页面上的数据(星号表示该项目已经在研究中)。这是他们的“整体页面浏览量研究”。他们可以将页面上的项目添加到研究中。他们单击该项目,一个 Bootstrap 5 模式弹出,其中包含他们研究的下拉列表。默认情况下选择当前页面研究,但如果他们愿意,他们可以选择任何其他研究来添加它。因此,如果他们将该项目添加到另一项研究(不是他们正在查看的研究),我们假设他们可以添加它并让 API 返回一个特殊的响应 (409),它会向用户显示“已经在研究中”的消息(toast/flash message/etc)。如果它是他们当前的“页面研究”,那么如果它不存在,他们应该能够添加它,或者如果它已经在研究中,则将其删除。
我只是想提供一个背景概述,以防万一其中的某些内容会对解决方案产生影响(Vue3、Bootstrap 5、引导模式、选择下拉菜单等)。
由于复杂性和适当性,我创建了一个通用模型来复制该问题,以及 CodePen 上的演示。
问题:
我有一个下拉列表(学习选择器)和 2 个按钮(添加和删除)。如果他们从下拉列表中选择的研究不是当前查看的“页面研究”,我们假设“添加”。如果是当前查看的“页面学习”,我们需要做一个检查。它检查该“项目”是否在研究中。如果是,则显示“删除”按钮,否则显示“添加”按钮。
当我选择一个已经在所选“页面研究”中的项目时,它确实显示了“删除”按钮(首先)。然后,当我在下拉列表中切换到不同的研究时,它会交换按钮(显示“添加”)。到目前为止一切都很好......但是,当我将它交换回当前的“页面研究”时,当它应该交换到“删除”按钮时,“添加”按钮保持不变......就像它更新了一次并且忽略了我并且不再听大声笑。
我已经尝试过观察者,计算过,尝试过强制更新...我只是对 Vue 了解不够,无法使其正常工作。
带有虚拟数据的模拟应用程序代码:
<div id="app">
Study ID: {{ currentStudyId }}
<br><br>
Selected StudyData Item:
<select v-model="selectedStudyDataItem">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
<br><br>
<select v-model="selectedStudyModel" name="study_id" class="form-select">
<option disabled value="">Choose a study...</option>
<option v-for="item in studies" :value="item.id" :key="item.id">
{{ item.title }}
</option>
</select>
<button v-show="showAddButton()" type="submit" class="btn btn-primary">Add</button>
<button v-show="showRemoveButton()" type="submit" class="btn btn-danger">Remove</button>
</div>
const TestApp = {
data() {
return {
currentStudyId: 2,
selectedStudyDataItem: 1,
selectedStudyModel: "", // dropdown model
studies: [
{ id: 1, title: "Study 1" },
{ id: 2, title: "Study 2" },
{ id: 3, title: "Study 3" },
{ id: 4, title: "Study 4" }
],
studyData: {
title: "My Cool Study",
user_id: 1,
items: [1, 3]
}
};
},
methods: {
showAddButton() {
// if it isnt the current study, we assume add and let api handle it
if (this.selectedStudyModel !== this.currentStudyId) {
return true;
}
// else, if it isn't in the current viewed study, we can add it
if (!this.isInStudy(this.selectedStudyDataItem)) {
return true;
}
return false;
},
showRemoveButton() {
if (this.selectedStudyModel === this.currentStudyId) {
if (this.isInStudy(this.selectedStudyDataItem)) {
return true;
}
}
return false;
},
isInStudy(something) {
if (this.studyData) {
const match = (item) => item === something;
return this.studyData.items.some(match);
}
return false;
}
}
};
Vue.createApp(TestApp).mount("#app");