当前位置: 首页 > 知识库问答 >
问题:

vue3 - 如何避免数据跟着一块变呢?

邹博明
2024-06-22
  1. 输入新的姓名和年龄
  2. 提交
  3. 点击过滤(此时你刚刚添加的姓名和年龄出现在了最终的结果中)
  4. 此时,如果你修改上面输入框中的内容,下面结果中对应的内容也会发生变化

这是为什么呢?该如何修改才能使在修改上面输入框中的内容时,下面结果中对应的内容不发生变化呢?

注:这里的persons可以看作是一个存储在服务端数据库中的大数据。

<script setup lang="ts">import { ref, version as vueVersion, reactive, toRaw } from 'vue'import { version as epVersion } from 'element-plus'import { ElementPlus } from '@element-plus/icons-vue'import {ElMessage} from "element-plus";const form = reactive({  name: "",  age: "",})const formRef = ref(null);async function submit(formInstance) {  if(!formInstance) return;  await formInstance.validate((valid) => {    if(valid) {      console.log("valid success");      ElMessage({        message: "添加成功",        type: "success"      })      persons.push(toRaw(form));    }else {      console.log("valid failed");    }  })}function reset(formInstance) {  if(!formInstance) return;  formInstance.resetFields();}const persons = [{name: "peter", age: "18"}, {name: "Tom", age: "22" }];const filterForm = reactive({  name: ""});const filterPersons = ref();function filter() {  const result = persons.filter(person => filterForm.name === "" || person.name === filterForm.name);  console.log("result: ", result);  filterPersons.value = result;}filter();</script><template>  <h2>添加新数据</h2>  <el-form :model="form" ref="formRef">    <el-form-item prop="name">      <el-input v-model="form.name" placeholder="请输入你的名字"></el-input>    </el-form-item>    <el-form-item prop="age">      <el-select v-model="form.age" clearable>        <el-option v-for="age in 18" :value="age"></el-option>      </el-select>    </el-form-item>        <el-form-item>      <el-button @click="submit(formRef)" type="primary">提交</el-button>      <el-button @click="reset(formRef)">重置</el-button>    </el-form-item>  </el-form>  <h2>过滤数据</h2>  <el-form :model="filterForm">    <el-row :gutter="10">      <el-col :span="12">        <el-form-item clearable>          <el-input prop="name" placeholder="姓名"></el-input>        </el-form-item>      </el-col>      <el-col :span="12">        <el-form-item>          <el-button @click="filter">过滤</el-button>        </el-form-item>      </el-col>    </el-row>  </el-form>  <h2>结果</h2>  <el-table :data="filterPersons">    <el-table-column prop="name" label="姓名"></el-table-column>    <el-table-column prop="age" label="年龄"></el-table-column>  </el-table></template>

element plus playground

image.png

共有4个答案

司寇祖鹤
2024-06-22

你直接深拷贝一个form,再push进去。
就是这里出了问题 persons.push(toRaw(form));

麻宜春
2024-06-22

我的做法就是在点编辑的时候把当前的对象复制一下

JSON.parse(JSON.stringify(persons[index]));

艾才良
2024-06-22

看到第 21 行:

      persons.push(toRaw(form));

formObject,所以这一行是把 form 的引用放进 persons 里了,所以 persons 里的 form同一个对象,具体可以搜 JavaScript 引用。

所以这样改:

     if(valid) {       console.log("valid success");       ElMessage({         message: "添加成功",         type: "success"       })-      persons.push(toRaw(form));+      persons.push({ ...toRaw(form) });     }else {       console.log("valid failed");     }

上面这个是浅拷贝,用于 form 只有一层对象的情况({ a: 1, b: 2 })。如果 form 有对象套对象({ a: { b: 1 }, c: 2 }),用:

persons.push(structuredClone(toRaw(form)));

看看 structuredClone 的兼容性表,如果要兼容不支持的浏览器,搜一下

小牛23129
2024-06-22

persons.push(toRaw(form))因为你push的数据是form,而你下面修改的数据也是form,这是同一份数据,所以会一起变。你应该拷贝一份数据进行push比如使用JSON序列化persons.push(JSON.parse(JSON.stringify(form)))

 类似资料:
  • 问题内容: 某些数据库功能(例如和)很容易受到死锁的影响,因为数据库未指定将使用哪种锁定顺序。我发现有两次 讨论暗示此行为不是SQL标准指定的,更不用说具体的实现了。因此,我在假设我们无法控制锁定顺序的情况下进行操作(至少,这样做并不明显)。 如果我们不能依赖锁定顺序,应该如何避免数据库死锁? 如果我们不应该避免僵局(您将不得不非常努力地说服我),那么我们应该怎么做? 这个问题与数据库无关,所以请

  • Lodash castArray函数没有任何特殊之处。有没有什么方法可以在没有任何外部库的情况下,利用最新的语言功能解决这个问题,但时间很短? 如果您不熟悉该任务: 有没有办法在没有类型检查的情况下做到这一点?请注意,我寻找最短的等效物ES6。

  • 问题内容: 如何避免使用!进行力解开的操作,因为使用此方法通常是错误的选择。 如下所示的代码中有什么更好的选择,使用它可以使代码看起来更简单,并且可以通过if检查变量!被调用永远不会为零,因此不会崩溃。 我的教练向我们介绍了bang(!)运算符,然后告诉我们不要再使用它了。告诉我们原因,如果可选为nil,它将使我们的应用程序崩溃。 但是,我发现自己处于类似bang运算符似乎是最简洁和最安全的选择的

  • 问题内容: 我正在尝试通过从客户端向服务器发送密钥和随机数来认证用户。 我的代码未向我显示客户端的响应。执行下面的代码时,我得到了一个空指针异常。 问题答案: 解决大多数问题的固定步骤: 阅读堆栈跟踪以确定哪一行代码引发NPE 在该行代码处设置一个断点 使用调试器,在遇到断点时,确定该行中的对象引用是 弄清楚为什么引用该文件(到目前为止,这是唯一实际的困难部分) 解决根本原因(也可能很困难)

  • 问题内容: 我有两个简单的Java代码。第一个将恒定功率定义为power = a.pow(b); 第二个将恒定功率定义为power = BigInteger.ONE.shiftLeft(b) 在命令行中设置内存标志- Xmx1024m,第一个代码可以正常工作,但是第二个代码却出现错误:java.lang.OutOfMemoryError:Java堆空间 我的问题:我应该在第二个代码中更改什么以避免

  • 问题内容: 我有一个用于将文本添加到现有.doc文件中的代码,它将通过使用apache POI将其另存为另一个名称。 以下是到目前为止我尝试过的代码 以下是我得到的 我已经添加了与此对应的所有jar文件,但仍然找不到解决方案。我对apache poi是陌生的,所以请帮我提供一些解释和示例。谢谢 问题答案: 从我对问题的评论中复制: 看起来您需要Apache POI发行版中的poi-ooxml-sc