最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - Object Value Returning 'Undefined' in Array in vue.js - Stack Overflow

matteradmin8PV0评论

I am trying to better myself at JavaScript OOP, and I'm learning vue.js as well. I am building a simple task list to teach myself, and I have most of it done except for the remove task function. I originally was just using the .remove() option, but it was not updating my v-if and v-else statement on my front end, even with another function checking the length of the array. So, I decided to try and splice my array, but I'm a bit lost since it's returning undefined. As each element in the array is an object, I'm sure it's the way I'm trying to call the value, but I'm not too sure how to do so.

Here is the HTML:

<div class="form-group">

      <input type="text" id='task-entry' class='px-2' @keyup.enter="addTask">
      <a href="#" class='btn btn-info' id='task-button' @click="addTask">Add Task</a>

    </div> <!-- form-group -->

    <hr class='hr my-5 bg-dark'>

    <div class="task-list py-3 bg-white mx-auto w-75">

      <ul v-if='taskList.length > 0' class='mb-0 px-2'>

        <li v-for="tasks in taskList" class='text-dark p-3 task-item text-left clearfix'>
          <div class='task-name float-left'>
              <span>{{ tasks.task }}</span>
          </div>

          <a href="#" class="btn btn-danger remove-task float-right" @click='removeTask'>Remove Task</a>

        </li>

      </ul>

      <div v-else>
        You currently have no tasks.
      </div>

And here is the JavaScript:

new Vue({
  el: '#app',
  data: {
    title: 'To Do List',
    taskList: [],
    showError: false
  },
  methods: {
    addTask: function () {

      var task = document.getElementById('task-entry');

      if (task.value !== '' && task.value !== ' ') {
        this.error(1);
        this.taskList.push({
          task: task.value
        });
        task.value = '';
      } else {
        this.error(0);
      }
    },
    removeTask: function (e) {
      if(e.target.classList.contains('remove-task')) {

        var targetElement = e.target.parentElement;

        var test = targetElement.querySelector('span').innerText;

        console.log(test);
        console.log(this.taskList[{task: test}]);

      } else {
        e.preventDefault;
      }
    },
    error: function (value) {
      if (value === 0) {
        this.showError = true;
      } else {
        this.showError = false;
      }
    }
  }
});

I am trying to better myself at JavaScript OOP, and I'm learning vue.js as well. I am building a simple task list to teach myself, and I have most of it done except for the remove task function. I originally was just using the .remove() option, but it was not updating my v-if and v-else statement on my front end, even with another function checking the length of the array. So, I decided to try and splice my array, but I'm a bit lost since it's returning undefined. As each element in the array is an object, I'm sure it's the way I'm trying to call the value, but I'm not too sure how to do so.

Here is the HTML:

<div class="form-group">

      <input type="text" id='task-entry' class='px-2' @keyup.enter="addTask">
      <a href="#" class='btn btn-info' id='task-button' @click="addTask">Add Task</a>

    </div> <!-- form-group -->

    <hr class='hr my-5 bg-dark'>

    <div class="task-list py-3 bg-white mx-auto w-75">

      <ul v-if='taskList.length > 0' class='mb-0 px-2'>

        <li v-for="tasks in taskList" class='text-dark p-3 task-item text-left clearfix'>
          <div class='task-name float-left'>
              <span>{{ tasks.task }}</span>
          </div>

          <a href="#" class="btn btn-danger remove-task float-right" @click='removeTask'>Remove Task</a>

        </li>

      </ul>

      <div v-else>
        You currently have no tasks.
      </div>

And here is the JavaScript:

new Vue({
  el: '#app',
  data: {
    title: 'To Do List',
    taskList: [],
    showError: false
  },
  methods: {
    addTask: function () {

      var task = document.getElementById('task-entry');

      if (task.value !== '' && task.value !== ' ') {
        this.error(1);
        this.taskList.push({
          task: task.value
        });
        task.value = '';
      } else {
        this.error(0);
      }
    },
    removeTask: function (e) {
      if(e.target.classList.contains('remove-task')) {

        var targetElement = e.target.parentElement;

        var test = targetElement.querySelector('span').innerText;

        console.log(test);
        console.log(this.taskList[{task: test}]);

      } else {
        e.preventDefault;
      }
    },
    error: function (value) {
      if (value === 0) {
        this.showError = true;
      } else {
        this.showError = false;
      }
    }
  }
});
Share Improve this question asked Oct 19, 2018 at 1:25 valtro05valtro05 812 silver badges8 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

Try this: (I implement the remove function in VueJS way, it's really simple)

new Vue({
  el: '#app',
  data: {
    title: 'To Do List',
    taskList: [],
    showError: false
  },
  methods: {
    addTask: function() {
      var task = document.getElementById('task-entry');
      if (task.value !== '' && task.value !== ' ') {
        this.error(1);
        this.taskList.push({
          task: task.value
        });
        task.value = '';
      } else {
        this.error(0);
      }
    },
    removeTask: function(tasks) {
      this.taskList.splice(this.taskList.indexOf(tasks), 1)
    },
    error: function(value) {
      if (value === 0) {
        this.showError = true;
      } else {
        this.showError = false;
      }
    }
  }
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn./bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.js"></script>

<div id="app">
  <div class="form-group">
    <input type="text" id='task-entry' class='px-2' @keyup.enter="addTask">
    <a href="#" class='btn btn-info' id='task-button' @click="addTask">Add Task</a>
  </div>
  <!-- form-group -->
  <hr class='hr my-5 bg-dark'>
  <div class="task-list py-3 bg-white mx-auto w-75">
    <ul v-if='taskList.length > 0' class='mb-0 px-2'>
      <li v-for="tasks in taskList" class='text-dark p-3 task-item text-left clearfix'>
        <div class='task-name float-left'>
          <span>{{ tasks.task }}</span>
        </div>
        <a href="#" class="btn btn-danger remove-task float-right" @click='removeTask(tasks)'>Remove Task</a>
      </li>
    </ul>
    <div v-else>
      You currently have no tasks.
    </div>
  </div>


There are two small steps to make your code work as expected:

S1: In the template change the event handler to @click='removeTask(tasks)', like this:

<a href="#" class="btn btn-danger remove-task float-right" @click='removeTask(tasks)'>Remove Task</a>

S2: In the script, re-write the remove method like so:

removeTask: function(tasks) {
   this.taskList.splice(this.taskList.indexOf(tasks), 1)
}

There's a much more Vue-specific way to go about what you're trying to achieve and you definitely don't need to be querying the DOM for values.

Let's start with your removeTask method.

Array.prototype.splice() uses an index to remove / insert values from an array. You can get this index from v-for using something like

<li v-for="(tasks, index) in taskList">

Now your remove link can use this index

<a @click.prevent="removeTask(index)">

and your method can use

removeTask (index) {
  this.taskList.splice(index, 1)
}

For adding tasks, I remend using v-model to bind the new task to your input, eg

<input type="text" v-model="newTask" @keyup.enter="addTask">

and

data: {
  title: 'To Do List',
  taskList: [],
  showError: false,
  newTask: '' // added this
},
methods: {
  addTask () {
    if (this.newTask.trim().length > 0) {
      this.error(1)
      this.taskList.push({ task: this.newTask })
      this.newTask = ''
    } else {
      this.error(0)
    }
  }
}
Post a comment

comment list (0)

  1. No comments so far