You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js:如何阻止输入框在实时数据更新时自动同步内容?

Vue.js:如何阻止输入框在实时数据更新时自动同步内容?

嗨,我来帮你搞定这个问题~

你现在遇到的核心问题是:打开模态框编辑数据时,每5秒的全局数据更新会同步修改模态框里的输入内容,这是因为你的passedData没有和原数据完全切断引用关系,导致原数据更新时,编辑用的副本也被牵连了。

给你几个关键的修改点,一步步解决:

1. 修正数据结构的语义

你现在passedData初始是数组,但它其实是用来存储单个待编辑的产品对象,所以先把它改成空对象,同时新增一个变量控制模态框的显示/隐藏(原来的代码没做这部分逻辑哦):

data() {
  return {
    items: [],
    passedData: {}, // 从数组改成对象更符合存储单个数据的语义
    modal1Visible: false // 新增变量,用来控制模态框的显示状态
  };
}

2. 创建完全独立的深拷贝副本

打开模态框时,不要只用浅拷贝(Object.assign),而是用深拷贝把原item完全复制一份,彻底切断和原数据的引用关联。对于普通的产品对象,用JSON.parse(JSON.stringify(item))就可以轻松实现深拷贝:

openModal(idModal, item) {
  // 深拷贝原数据,生成完全独立的编辑副本
  this.passedData = JSON.parse(JSON.stringify(item));
  this.modal1Visible = true; // 打开模态框
}

3. 用双向绑定替代单向:value

原来的:value是单向绑定,只能从数据同步到输入框,而且如果数据被意外修改,输入框会立刻同步变化。改成v-model后,你编辑的是独立的副本,原数据更新也不会影响它:

<div class="modal" id="modal1" v-show="modal1Visible">
  <form method="post" @submit.prevent="handleSubmit">
    <input type="text" v-model="passedData.category" />
    <input type="text" v-model="passedData.rating" />
    <input type="text" v-model="passedData.price" />
    <input type="text" v-model="passedData.stock" />
    <button>Submit</button>
  </form>
</div>

4. 补充提交逻辑(可选但必要)

可以加一个提交方法,处理编辑后的逻辑,比如提交到后台,或者更新本地数据后重新拉取最新内容:

methods: {
  // ... 保留其他已有方法
  async handleSubmit() {
    // 这里替换成你的实际提交逻辑,比如把编辑后的数据发送到后端
    console.log("要提交的编辑数据:", this.passedData);
    // 提交成功后关闭模态框
    this.modal1Visible = false;
    // 可选:提交后重新拉取最新数据
    // await this.fetchData();
  }
}

修改后的完整代码

<div id="app">
  <div class="modal" id="modal1" v-show="modal1Visible">
    <form method="post" @submit.prevent="handleSubmit">
      <input type="text" v-model="passedData.category" />
      <input type="text" v-model="passedData.rating" />
      <input type="text" v-model="passedData.price" />
      <input type="text" v-model="passedData.stock" />
      <button>Submit</button>
    </form>
  </div>

  <table>
    <tr v-for="item in items" :key="item.sku">
      <td>{{ item.sku }}</td>
      <td>{{ item.stock }}</td>
      <td><button @click="openModal('modal1', item)">Edit</button></td>
    </tr>
  </table>
  
</div>

<script>
  const app = Vue.createApp({
    data() {
      return {
        items: [],
        passedData: {},
        modal1Visible: false
      };
    },
    mounted() {
      this.fetchData();
      setInterval(this.fetchData, 5000);
    },
    methods: {
      async fetchData() {
        const response = await fetch("https://dummyjson.com/products");
        const data = await response.json();
        this.items = data.products;
      },
      openModal(idModal, item) {
        this.passedData = JSON.parse(JSON.stringify(item));
        this.modal1Visible = true;
      },
      async handleSubmit() {
        // 这里替换成你的实际提交逻辑
        console.log("提交的数据:", this.passedData);
        this.modal1Visible = false;
        // 可选:提交后重新拉取最新数据
        // await this.fetchData();
      }
    },
  });

  app.mount("#app");
</script>

为什么这样能解决问题?

  • 深拷贝后的passedData是完全独立的对象,和原items里的产品没有任何引用关联,所以原数据每5秒更新时,不会影响到编辑用的副本。
  • v-model实现双向绑定,你在输入框里的修改只会同步到这个独立副本,不会污染原数据,同时原数据的更新也不会反向影响输入框。

备注:内容来源于stack exchange,提问作者Drake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 18:19:32