Массив сортировки Vue с последующим индексом ( 0, 1, 2, 3 … )

#javascript #arrays #vue.js #sorting

Вопрос:

Я новичок в vue и пытался отсортировать свой массив по имени. У меня есть кнопка, которая должна сортировать имя игрока по имени. Но когда я нажимаю на кнопку, она выдает ошибку, подобную этой.todos.функция player_name.sort() не является функцией. Вот мой код на

JsFiddle = https://jsfiddle.net/ujjumaki/r6wp38yj/77/

Вид

 <div id="app">
  <table>
    <tr>
      <th><b>First Name  amp;nbsp;</b></th>
      <th><b> Last Name amp;nbsp;</b> </th>
      <th><b> ID </b> </th>
    </tr>
    <tr v-for="fetchName in todos.player_name">
      <td>{{fetchName.first_name}}</td>
      <td>{{fetchName.last_name}}</td>
      <td>{{fetchName.id}}</td>
    </tr>
  
  </table>
  <br>
  <button v-on:click=alertName()>Sort by first name</button>
</div>
 

Методы

 new Vue({
  el: "#app",
  data(){
  return{
    todos: {
        mission:1,
      player_name:[
        {   
            first_name: "Harry", last_name: "Kui" , id:'103',
        },
        {
            first_name: "Ali", last_name: "Kui", id:'107',
        },
        {
            first_name: "Bee", last_name: "Hui", id:'99',
        }
      ]
    }
  }
  },
  methods: {
    alertName: function(){
        this.todos.player_name.sort(); /** sort function is throwing an error here **/
      console.log(this.todos.player_name); /** and this does not format array objects followed by first name **/
    }
  }
})
 

Ответ №1:

Это происходит потому, что просто вызов Array.prototype.sort() без какой-либо функции компаратора приведет к поведению по умолчанию:

элементы массива преобразуются в строки, затем сортируются в соответствии со значением кодовой точки каждого символа в Юникоде.

…а это не то, чего ты хочешь. Вместо этого вы захотите сравнить только значения, возвращаемые first_name ключом, используя String.prototype.localeCompare вместо этого, т. Е.:

 this.todos.player_name.sort((a,b) => a.first_name.localeCompare(b.first_name));
 

См. Доказательство концепции ниже:

 new Vue({
  el: "#app",
  data(){
  return{
    todos: {
        mission:1,
      player_name:[
        {   
            first_name: "Harry", last_name: "Kui" , id:'103',
        },
        {
            first_name: "Ali", last_name: "Kui", id:'107',
        },
        {
            first_name: "Bee", last_name: "Hui", id:'99',
        }
      ]
    }
  }
  },
  methods: {
    alertName: function(){
        this.todos.player_name.sort((a,b) => a.first_name.localeCompare(b.first_name));
    }
  }
}) 
 body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <table>
    <tr>
      <th><b>First Name  amp;nbsp;</b></th>
      <th><b> Last Name amp;nbsp;</b> </th>
      <th><b> ID </b> </th>
    </tr>
    <tr v-for="fetchName in todos.player_name">
      <td>{{fetchName.first_name}}</td>
      <td>{{fetchName.last_name}}</td>
      <td>{{fetchName.id}}</td>
    </tr>
  
  </table>
  <br>
  <button v-on:click=alertName()>Sort by first name</button>
</div>