根据输入元素动态修改Vue实例中的数据

Posted

技术标签:

【中文标题】根据输入元素动态修改Vue实例中的数据【英文标题】:Dinamically modify data in Vue instance based on input element 【发布时间】: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,那仍然可以。我也想知道这里的最佳做法。

【问题讨论】:

你不应该改变道具:你应该在浏览器控制台中收到警告。相反,让您的任务项组件向数据源所在的父级发出更改。见:vuejs.org/v2/guide/components.html#Using-v-model-on-Components 【参考方案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>

【讨论】:

以上是关于根据输入元素动态修改Vue实例中的数据的主要内容,如果未能解决你的问题,请参考以下文章

Vue表单输入绑定

vue-lazyload 源码解析

vue指令v-model

Vue基础(表单输入绑定)

Vue 实例中的生命周期钩子

VueJS 从根 Vue 实例中的组件访问数据