【问题标题】:Dinamically modify data in Vue instance based on input element根据输入元素动态修改Vue实例中的数据
【发布时间】:2021-11-12 22:06:03
【问题描述】:

我是 Vue 和 JS 的初学者,我正在努力根据用户输入更新 Vue 实例的数据属性。这是我作为 Vue 组件的模板(位于 taskTemplate 变量内):

<div>
  <input type="text" placeholder="Insert your task" v-model="desc"/>
  <p>{{ desc }}</p>
</div>

Vue组件定义如下:

Vue.component("task-item", {
  props: {
    id: Number,
    desc: String,
  },
  template: taskTemplate
});

这在 HTML 中填充如下:

<div id="task-list">
  <task-item
    v-for="item in taskList"
    v-bind="item"
  ></task-item>
  <div id="add-more">
    <button v-on:click="newTask" type="button">Add a new task</button>
  </div>
</div>

使用 Vue 实例创建任务列表的位置:

var app = new Vue({
  el: "#task-list",
  data: {
    taskList: [
      { id: 1, desc: "" },
      { id: 2, desc: "" },
    ]
  },
  methods: {
    newTask() {
      this.taskList.push({ id: this.taskList.length + 1, desc: "" })
    }
  }
});

我的问题是更新网页中的input元素后,组件的属性会更新,但如果我在控制台输入app.taskList[0].desc,它仍然返回一个空字符串。

最终目标是发送用户在 API 调用中引入的数据,所以如果我可以访问 Vue 组件而不是 data 属性中的 taskList,那仍然可以。我也想知道这里的最佳做法。

【问题讨论】:

标签: javascript html vue.js vuejs2


【解决方案1】:

不应在双向绑定中使用道具。相反,将它们的值绑定到输入 :value,并将任何更改发送到父组件。

<div>
  <input 
     type="text" 
     placeholder="Insert your task" 
     :value="desc"
     @input="$emit('update:desc', $event.target.value)"
  />
  <p>{{ desc }}</p>
</div>

在父组件中你必须监听update事件并更新源值:

<div id="task-list">
  <task-item
    v-for="item in taskList"
    :key="item.id" // do not forget about key
    v-bind="item"
    @update:desc="item.desc = $event"
    // or you can use the sync modifier to listen to update events for all item's props.
    // v-bind.sync="item"
  ></task-item>
  <div id="add-more">
    <button v-on:click="newTask" type="button">Add a new task</button>
  </div>
</div>

【讨论】:

    【解决方案2】:

    尝试使用:value@input 代替v-model

    Vue.component('task-item', {
      template: `
        <div>
          <input type="text" 
                 placeholder="Insert your task" 
                 :value="desc"
                 @input="$emit('update', $event.target.value)"/>
          <p>{{ desc }}</p>
        </div>
      `,
      props: {
        id: Number,
        desc: String,
      },
      //template: taskTemplate
    })
    
    new Vue({
      el: '#demo',
      data: {
        taskList: [
          { id: 1, desc: "" },
          { id: 2, desc: "" },
        ]
      },
      methods: {
        newTask() {
          this.taskList.push({ id: this.taskList.length + 1, desc: "" })
        }
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="demo">
      <div id="task-list">
        <task-item
          v-for="(item, index) in taskList"
          :key="index"
          v-bind="item"
          @update="item.desc = $event"
        ></task-item>
        <div id="add-more">
          <button v-on:click="newTask" type="button">Add a new task</button>
        </div>
      </div>
    </div>

    【讨论】:

      猜你喜欢
      • 2021-03-19
      • 2017-05-17
      • 1970-01-01
      • 1970-01-01
      • 2019-03-12
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      相关资源
      最近更新 更多