简体   繁体   English

编辑时更新输入的绑定值

[英]Updating an input's bound value when edited

I'm working on a basic to-do application.我正在开发一个基本的待办事项应用程序。 Each to-do/task item gets listed as an input item in a Vue <list-item> component, and the <list-item> s are displayed with a v-for pointing to a tasks array.每个待办事项/任务项都被列为 Vue <list-item>组件中的输入项,并且<list-item>显示为带有指向任务数组的 v-for。

I'm trying to allow the user to edit each task input, and upon changing the value, have this update the array item (rather than just the input itself).我试图让用户编辑每个任务输入,并在更改值后,更新数组项(而不仅仅是输入本身)。 My @change event on the input is firing, but I'm at a loss as to what to do after this point.我在输入上的@change 事件正在触发,但我不知道在此之后该怎么做。

https://jsfiddle.net/xbxm7hph/ https://jsfiddle.net/xbxm7hph/

HTML: HTML:

<div class="app">

    <div class="add-control-area columns is-mobile is-multiline">

        <responsive-container>

            <div class="field is-grouped">
                <div class="control is-expanded">
                    <input class="input add-control-text" type="text" placeholder="New Task" v-model="newTask" v-on:keyup.enter="addTask">
                </div>
                <div class="control">
                    <a class="button is-white add-control-button" @click="addTask" :disabled="!isThereText">Add Task</a>
                </div>
            </div>

        </responsive-container>

        <responsive-container>

            <list-item v-for="task, index in tasks" :item="task" :index="index" @task-completed="completeTask(index)" @task-deleted="deleteTask(index)" ></list-item>

        </responsive-container>

    </div>

</div>

JS: JS:

Vue.component('list-item', {
    props: ['item', 'index'],
    template: `<div class="task-wrapper">

<input class="task" :value="item" @change="updateTask()">

    <div class="task-control delete-task" @click="deleteTask()"></div>
    <div class="task-control complete-task" @click="completeTask()"></div>

</div>
  `,
  methods: {
    completeTask: function() {
      this.$emit('task-completed', this.index);
    },
    deleteTask: function() {
      this.$emit('task-deleted', this.index);
    },
    updateTask: function() {
      console.log('changed');
    }
  }
});

Vue.component('responsive-container', {
  template: `
    <div class="column is-4-desktop  is-offset-4-desktop is-10-tablet is-offset-1-tablet is-10-mobile is-offset-1-mobile">
            <div class="columns is-mobile">
                <div class="column is-12">
                  <slot></slot>
                </div>
            </div>
  </div>
  `
});

var app = new Vue({
    el: '.app',
  data: {
        tasks: [],
    completedTasks: [],
    newTask: ''
  }, 
  methods: {
    addTask: function() {
      if(this.isThereText) {
        this.tasks.push(this.newTask);
        this.newTask = '';
        this.updateStorage();
      }
    },
    completeTask: function(index) {
      this.completedTasks.push(this.tasks[index]);
      this.tasks.splice(index, 1);
      this.updateStorage();
    },
    deleteTask: function(index) {
      this.tasks.splice(index, 1);
      this.updateStorage();
    },
    updateStorage: function() {
      localStorage.setItem("tasks", JSON.stringify(this.tasks));
    }
  },
  computed: {
    isThereText: function() {
      return this.newTask.trim().length;
    }
  },

  // If there's already tasks stored in localStorage,
  // populate the tasks array
  mounted: function() {
    if (localStorage.getItem("tasks")) {
      this.tasks = JSON.parse(localStorage.getItem("tasks"));    
    }
  }
});

Use a v-model directive on your <list-item> component, instead of passing in an item property.<list-item>组件上使用v-model指令,而不是传入item属性。 You will also need to pass in a reference from the array ( tasks[index] ), because task in this scope is a copy that is not bound to the element of the array:您还需要从数组 ( tasks[index] ) 中传递一个引用,因为此范围内的task是未绑定到数组元素的副本:

<list-item v-for="task, index in tasks" v-model="tasks[index]"></list-item>

In your component definition for the list item, you'll need to now take in a value prop (this is what gets passed when using v-model ) and set a data property item to that value.在列表项的组件定义中,您现在需要接受一个value属性(这是使用v-model时传递的内容)并将数据属性item设置为该值。 Then, emit an input event on the change to pass the item value (this is what the component is listening for when using v-model ):然后,在更改时发出input事件以传递item值(这是组件在使用v-model时正在侦听的内容):

Vue.component('list-item', {
  props: ['value'],
  template: `<div class="task-wrapper">
    <input class="task" v-model="item" @change="updateTask"></div>
  </div>
  `,
  data() {
    return {
      item: this.value,
    }
  },
  methods: {
    updateTask: function() {
      this.$emit('input', this.item);
    }
  }
});

Here's a fiddle with those changes.这是这些变化的一个小技巧。


  • As Bert Evans mentioned, even though this works, Vue requires that components using the v-for directive also use a key attribute (you will get a warning from Vue otherwise):正如 Bert Evans 所提到的,即使这有效,Vue 要求使用v-for指令的组件也使用key属性(否则你会收到来自 Vue 的警告):

     <list-item v-for="task, index in tasks" :key="index" v-model="tasks[index]" ></list-item>
  • Also, realize that the index variable in a v-for scope can change, meaning that the item at index 1 might change to index 4 and this can pose some problems as the application gets more complex.此外,要意识到v-for范围内的index变量可以更改,这意味着索引 1 处的项目可能会更改为索引 4,这可能会随着应用程序变得更加复杂而带来一些问题。 A better way would be to store items as an object with an id property.更好的方法是将items存储为具有id属性的对象。 This way you can have an immutable id associated with the item.这样,您就可以拥有与该项目关联的不可变 id。

You can pass the index and new value to your change event handler:您可以将索引和新值传递给您的更改事件处理程序:

<input class="task" :value="item" @change="updateTask(index, $event)">

Then access them accordingly:然后相应地访问它们:

updateTask: function(index, event) {
    console.log(index);          
    console.log(event.target.value);  
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 编辑输入文本框时获取其内容 - Get the content of an input textbox when it's edited Angular 7-当mat-datepicker的值绑定到可选输入参数时,如何处理其更改事件 - Angular 7 - How to handle a change event for a mat-datepicker when it's value is bound to an optional input parameter jQuery:编辑值时更改表单输入的颜色 - jQuery: Change color of form input when value was edited 编辑屏蔽输入时如何获得正确的值(自定义屏蔽) - How to get the correct value when a masked input is edited(custom masking) 将输入值更新为用户输入 - Updating Value of Input to user's Input 编辑/更新使用Knockout可观察数组绑定的jqxGrid的行值时的问题,替换使用javascript对象编辑的可观察对象 - Issue when Editing/Updating row values of jqxGrid bound with a Knockout observable array, replace observable object edited with a javascript object 记录数据更改时更新ExtJS按钮绑定到公式 - Updating ExtJS Button Bound to Formula when Record's Data Changes 更改时Kendo单选按钮绑定的可观察值未更新 - Kendo Radio Button Bound Observable Not Updating Value When Change Is Made 使用“keyup”上的输入值更新元素的 innerText - Updating element's innerText with input value on 'keyup' 使用 Jquery/PHP/Mysql 更新编辑值 - Updating Edited Value Using Jquery/PHP/Mysql
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM