[Vuejs]-Toggle Class for individual elements in Vue JS

3👍

Using the axios API i get the todos and pragmatically loop over the individual todos and apply an isActive prop to all of them.
These props can now be toggled via toggleTodo when passing the todo’ id to the method. 🙂

Notice i have applied a v-if="todo.isActive" upon the ul this can also be translated to :class="{active: todo.isActive}" if you were wanting to apply some styling i.e for transitions etc.

By using this approach you can use the same logic to create methods such as completeTodo and removeTodo etc

I have added a showList prop in order to show/hide the actual full list.

I noticed you are using v-bind and v-on – this is absolutely valid but VUE ^2.0 can handle shorthand binding 🙂

I also noticed you are using single quotes for your HTML attributes… Although this does not break your markup i think it’s best practice to keep them as double quotes.

var vm =  new Vue({
  el: '#app',
  data: {
    todos: [],
    showList: false
  },
  mounted () {
    this.getTodos()
  },
  methods: {
    getTodos () {
      axios.get('https://jsonplaceholder.typicode.com/todos')
      .then(res => {
        res.data = res.data.map(todo => {
          todo.isActive = false
          return todo
        })

        this.todos = res.data
      })
    },
    showTodos () { this.showList = !this.showList },
    toggleTodo (id) {
      this.todos = this.todos.map(todo => {
        if (todo.id === id) {
          todo.isActive = !todo.isActive
        }
        return todo
      })
    }
  }
})
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.15/dist/vue.js"></script>


<div id="app">
  <button @click="showTodos()">{{this.showList ? 'Hide' : 'Show'}} Todos</button>
  <div v-if="todos.length && showList" v-for="todo in todos">
    <button id="btn" @click="toggleTodo(todo.id)">Toggle Todo</button>

    <ul v-if="todo.isActive" :class="{active: todo.isActive}">
      <li>{{todo.title}} </li>
      <li id="status"> Task Status : {{todo.completed}} </li>
    </ul>
  </div>
</div>

<style lang="css">
  .active {
    border: 2px solid green;
  }
</style>

1👍

isActive is one for the entire instance, not every individual todo.

What you’ll need to do is to to populate the todo list either by mapping the response data or simply use the response data’s completed property.

{
    "userId": 10,
    "id": 193,
    "title": "rerum debitis voluptatem qui eveniet tempora distinctio a",
    "completed": true
}

Every item of the response’s todo has the completed prop, so you can use that.

That’s how you’d go about doing it:

var vm = new Vue({
  el: '#app',
  data() {
    return {
      todos: []
    }
  },
  methods: {
    getTodo: function() {
      axios.get('https://jsonplaceholder.typicode.com/todos')
        .then((response) => {
          this.todos = response.data;
        })
    },
    toggleCompleted: function(todo) {
      todo.completed = !todo.completed;
    }
  }

})
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.15/dist/vue.js"></script>
<div id="app">
  <button id="btn" v-on:click='getTodo'>Show Todo</button>
  <div id="jsonData" v-for='todo in todos'>
    <ul v-bind:class='{active: todo.completed}' v-on:click='toggleCompleted(todo)'>
      <li>{{todo.title}} </li>
      <li id="status"> Task Status : {{todo.completed ? 'Completed' : 'Active'}} </li>
    </ul>
  </div>
</div>
👤Phiter

Leave a comment