Sort list with vue

1

Hello, ladies and gentlemen, I am a beginner with vue and I am creating a list, but I am having difficulty understanding how I will sort the list by clicking on the following title column:

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><divclass="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 you click on the name of the order, by email, and by email, where do I start?

    
asked by anonymous 12.06.2017 / 21:40

2 answers

4

You get the sort method that arrays have in JavaScript. This method returns a function where you define how to compare a pair of a and b values. It should return a value less than zero if a is less than b , zero if 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 sort .

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

In your case, you can do this:

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><divid="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 -->
    
12.06.2017 / 22:00
3

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

In the example, I placed according to the documentation, I commented the code and also inserted an additional feature, the reverse 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><scriptsrc="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>
    
14.06.2017 / 14:37