簡體   English   中英

編輯時更新輸入的綁定值

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

我正在開發一個基本的待辦事項應用程序。 每個待辦事項/任務項都被列為 Vue <list-item>組件中的輸入項,並且<list-item>顯示為帶有指向任務數組的 v-for。

我試圖讓用戶編輯每個任務輸入,並在更改值后,更新數組項(而不僅僅是輸入本身)。 我在輸入上的@change 事件正在觸發,但我不知道在此之后該怎么做。

https://jsfiddle.net/xbxm7hph/

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:

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"));    
    }
  }
});

<list-item>組件上使用v-model指令,而不是傳入item屬性。 您還需要從數組 ( tasks[index] ) 中傳遞一個引用,因為此范圍內的task是未綁定到數組元素的副本:

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

在列表項的組件定義中,您現在需要接受一個value屬性(這是使用v-model時傳遞的內容)並將數據屬性item設置為該值。 然后,在更改時發出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);
    }
  }
});

這是這些變化的一個小技巧。


  • 正如 Bert Evans 所提到的,即使這有效,Vue 要求使用v-for指令的組件也使用key屬性(否則你會收到來自 Vue 的警告):

     <list-item v-for="task, index in tasks" :key="index" v-model="tasks[index]" ></list-item>
  • 此外,要意識到v-for范圍內的index變量可以更改,這意味着索引 1 處的項目可能會更改為索引 4,這可能會隨着應用程序變得更加復雜而帶來一些問題。 更好的方法是將items存儲為具有id屬性的對象。 這樣,您就可以擁有與該項目關聯的不可變 id。

您可以將索引和新值傳遞給您的更改事件處理程序:

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

然后相應地訪問它們:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM