vue.js - 使用 v-show 时组件会重新渲染?VueJS
问题描述
首先,我将解释我的问题以及我在做什么。我正在编写一个表示表中单行的组件。该组件首先显示有关类别的信息(其名称、描述和 ID)。我有一个编辑按钮,我可以在其中编辑每个类别的名称和描述。看起来像这样:
当我单击编辑按钮时,我将数据替换为输入(仅在名称和描述中),因此我能够更改值,然后将信息发送到服务器。
所以有什么问题?问题是,当我按下编辑按钮时,我更改了输入值(它与 v-model 绑定),然后我再次按下编辑按钮(所以我不想更改数据)数据实际上保持为输入是,我不希望那样。我只想要初始值。
好吧,我已经通过使用 :value 而不是 v-model 解决了这个问题(也许还有另一种方法?)。
问题是,当我保存更改然后检查输入是否正确时,它会重新渲染 DOM(当我显示错误消息时)以及最初具有输入的值,我不想要那个。这是组件的代码:
<template>
<tr>
<th>
{{idCategory}}
</th>
<td>
<p v-if="isEditingCategory === false">
{{category.name}}
</p>
<form class="field" v-show="isEditingCategory">
<div class="control">
<input class="input"
type="text"
:value="category.name"
ref="categoryNameInput"
style="width: auto;">
</div>
<p class="help is-danger" v-show="showHelpMessage">al menos 3 caracteres.</p>
</form>
</td>
<td>
<!-- TODO. hacer un pipe para que muestre solo los primeros 10 caracteres. -->
<p v-if="isEditingCategory === false">
{{ category.description }}
</p>
<form class="field" v-if="isEditingCategory">
<div class="control">
<input class="input" type="text" :value="category.description" ref="descriptionInput" style="width: auto;">
</div>
</form>
</td>
<td>
<!-- Buttons... -->
<button class="button is-info is-outlined" @click="onEditCategory">
<span class="icon">
<i class="fas fa-edit"></i>
</span>
</button>
<button class="button is-success"
@click="onSaveCategory"
v-if="isEditingCategory">
<span class="icon">
<i class="far fa-save"></i>
</span>
</button>
</td>
</tr>
</template>
export default {
data() {
return {
isEditingCategory: false,
isPostingChanges: false,
category: {
id: this.idCategory,
name: this.categoryName,
description: this.categoryDescription,
index: this.arrayIndex
},
showHelpMessage: false
}
},
methods: {
onSaveCategory() {
this.showHelpMessage = false;
const MIN_CHAR = 3;
const categoryNameValue = this.$refs.categoryNameInput.value;
const descriptionValue = this.$refs.descriptionInput.value;
if (categoryNameValue.length >= MIN_CHAR) {
console.log(categoryNameValue)
} else {
this.showHelpMessage = true;
}
},
onEditCategory() {
this.isEditingCategory = !this.isEditingCategory;
}
},
props: ['idCategory', 'categoryName', 'categoryDescription', 'arrayIndex']
}
解决方案
处理这样的工作流程的一般方法是使用这些步骤
- 在切换到编辑模式时,将道具值复制到本地副本并使用绑定到您的表单输入
v-model
- 点击save时,验证本地值
- 将值提交到您的服务器。这也是禁用输入、按钮等的好时机
- 成功后,使用新值向组件父级发出事件并关闭编辑模式
- 父级接收此事件并更新其数据。对数据的更改通过您的行组件的道具向下流动,并且值被更新
例如(只关注单个输入)
<td>
<fieldset class="field" :disabled="isPostingChanges" v-if="isEditingCategory">
<div class="control">
<input class="input"
type="text"
v-model="categoryForm.name"
style="width: auto;"
>
</div>
<p class="help is-danger" v-show="showHelpMessage">al menos 3 caracteres.</p>
</fieldset>
<p v-else>
{{ category.name }} <!-- display the prop value here -->
</p>
</td>
export default {
props: { category: Object }, // just pass the entire category object as a prop
data: () => ({
isEditingCategory: false,
isPostingChanges: false,
showHelpMessage: false,
categoryForm: null
}),
methods: {
onEditCategory () {
this.isEditingCategory = !this.isEditingCategory
if (this.isEditingCategory) {
// assign local copies from props
this.categoryForm = { ...this.category }
}
},
async onSaveCategory () {
// do your validation against `this.categoryForm`, then if valid...
this.isPostingChanges = true
// now send to your server (this is all guesswork)
const res = await fetch(`/api/categories/${this.category.id}`, {
method: "PUT",
headers: { "Content-type": "application/json" },
body: JSON.stringify(this.categoryForm)
})
this.isPostingChanges = false
if (res.ok) {
const updated = await res.json() // the updated values from the server
this.isEditingCategory = false
this.$emit("updated", updated) // emit the new values
}
}
}
}
然后在你的父组件中,添加一个监听器
<row-component
v-for="(category, index) in categories"
:key="category.id"
:category="category"
@updated="updateCategory($event, index)"
/>
methods: {
updateCategory(category, index) {
// remove the old category and replace it with the updated one
this.categories.splice(index, 1, category)
}
}
推荐阅读
- flutter - Flutter PageController AnimateToPage 破坏了应用程序
- c# - 有没有办法在 Blazor 中检查 url 是否有路由约束?
- python - C-FIND 研究按患者 ID 和日期
- python - 如何使用循环将元素附加到列表中?
- postgresql - 重用存储在 PostgreSQL 和 SSRS 中的参数时出错
- json - 如何在 Azure SQL 中生成 JSON 值数组
- html - 将图像向右对齐但不移动整个部分
- r - 有条件地删除数据框中的列?
- javascript - 如何将 javascript 文件/函数 API 正确导入 React.js 应用程序?
- bash - 使用 tar 压缩并验证,然后上传到 S3 并验证