Sort list with Vue

Asked

Viewed 1,804 times

2

Ba late gentlemen, I’m beginner with Vi and I’m creating a list, but I’m having a hard time understanding how I will sort list by clicking on the column title follow example:

new Vue({
  el: "#lista",
  data:{
    users :[
      {nome: "Marcos Santos", email: "[email protected]"},
      {nome: "Lennon Bueno", email: "[email protected]"}
    ]
  }
})
<!DOCTYPE html>
	<html lang="pt-br">
	<head>
		<meta charset="UTF-8">
		<title>Vue 1</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://unpkg.com/vue"></script>
	</head>
	<body>
		<div class="container">
			<div id="lista">
				<table class="table table-bordered">
					<tr>
						<th><a href="#">Nome</a></th>
						<th><a href="#">Email</a></th>
					</tr>
					<tr v-for="item in users">
						<td>{{item.nome}}</td>
						<td>{{item.email}}</td>
					</tr>
				</table>
			</div> <!-- #lista -->
		</div> <!-- .container -->
		<script>
			
		</script>
	</body>
</html>

I would like when I click on name I sort by name, and by email I sort by email, where I start?

  • 1

    Just sort the data array. Your question is about how to sort, or how to run a function (like sorting) from one click?

  • @bfavaretto how to run ordering from cllick

2 answers

6


You start with the method sort that arrays have in Javascript. This method returns a function where you define how to compare a pair of values a and b. It must return a value less than zero if a is less than b, zero if they are equal, or a value greater than zero if a is greater than b. And to compare strings the method localeCompare conveniently returns a value compatible with the sort.

To tie an event in Vue, just use the attributes @evento="..." (or v-on:evento="...") in the target element, and record the method to be executed in the list of methods of the app or component.

In your case, you can do so:

new Vue({
  el: "#lista",
  data:{
    users :[
      {nome: "Marcos Santos", email: "[email protected]"},
      {nome: "Lennon Bueno", email: "[email protected]"}
    ]
  },
  methods: {
    sortUsers: function(chave) {
      this.users.sort(function(a, b) {
        return a[chave].localeCompare(b[chave])
      });
    }
  }
});
<script src="https://unpkg.com/vue"></script>

<div id="lista">
  <table class="table table-bordered">
    <tr>
      <th><a href="#" @click="sortUsers('nome')">Nome</a></th>
      <th><a href="#" @click="sortUsers('email')">Email</a></th>
    </tr>
    <tr v-for="item in users">
      <td>{{item.nome}}</td>
      <td>{{item.email}}</td>
    </tr>
  </table>
</div> <!-- #lista -->

4

As recommended by Vue documentation, use a computed property and library Lodash. Documentation link.

In the example, I put according to the documentation, I left commented the code and also inserted an additional feature, to reverse the order of the columns, example of A-Z and Z-A.

new Vue({
    el: "#lista",
    data: {
        // Coluna padrão para ordernar
        colunaSort: 'nome',

        // Opção de ascendente ou descendente, padrão inicia como asc
        colunaOrder: 'asc',

       // Itens para ordenar
        users: [
            {nome: "Marcos Santos", email: "[email protected]"},
            {nome: "Zeus Bueno", email: "[email protected]"}
        ]
    },
    methods: {

        // Metodo que define qual a coluna que será ordernada
        // Também define se é  ascendente ou descendente 
        sort: function(coluna) {

            // Se é a mesma coluna que está setando, então vai inverter a orderm de exibição
            if (this.colunaSort == coluna) {
                this.colunaOrder = (this.colunaOrder == 'asc') ? 'desc' : 'asc';
            }

            // Se é uma coluna diferente, seta a coluna e define como ascendente          
            else
            {               
                this.colunaSort = coluna;
                this.colunaOrder = 'asc';
            }
        }
    },
    computed: {
        // Metódo que faz o sort das colunas, definindo o nome da coluna e a ordem
        orderedUsers: function() {
            return _.orderBy(this.users, this.colunaSort, this.colunaOrder)
        }
    }
});
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/lodash"></script>

<div id="lista">
  <table class="table table-bordered">
    <tr>
      <th><a v-on:click.prevent="sort('nome')">Nome</a></th>
      <th><a v-on:click.prevent="sort('email')">Email</a></th>
    </tr>
    <tr v-for="item in orderedUsers">
      <td>{{item.nome}}</td>
      <td>{{item.email}}</td>
    </tr>
  </table>
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.