Vue.js 中的多个 .includes 已计算?

Multiple .includes in Vue.js computed?

我试图在我的 Vue.js 计算中使用多个 .includes 和 .filters 过滤器,但无法成功。
HTML:

<input class="searchbar" v-model="filterByName" placeholder="Search By Name" oninput="handleInput(event)">
<button type="button" class="btn btn-lg btn-primary">Advanced [BETA]</button>

<div class="padded">
  <p>
    All 9mm & 9×19mm are 9×19mm Parabellum unless otherwise stated. All Rate of Fire are SEMI-AUTOMATIC unless otherwise
    stated.
  </p>
  <p>** - Still in testing phase (test place)</p>
</div>

<table class="ui celled table">
  <thead>
    <tr>

      <th @click="sortBy='name'">Name</th>
      <th @click="sortBy='cal'">Caliber</th>
      <th @click="sortBy='r'">Range (max-min)(studs)</th>
      <th @click="sortBy='dmg'">Damage</th>
      <th @click="sortBy='cap'">Capacity</th>
      <th @click="sortBy='rpm'">Rate of Fire</th>
      <th @click="sortBy='multi'">Damage Multiplier (Head/Torso)</th>
      <th @click="sortBy='desc'">Description</th>
      <th @click="sortBy='rank'">Rank Unlock</th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="(list, index) in sortedlists" :key="index">

      <td>{{list.name}}</td>
      <td>{{list.cal}}</td>
      <td>{{list.r}}</td>
      <td>{{list.dmg}}</td>
      <td>{{list.cap}}</td>
      <td>{{list.rpm}}</td>
      <td>{{list.multi}}</td>
      <td>{{list.desc}}</td>
      <td>{{list.rank}}</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th colspan="100%">{{sortedlists.length}} guns</th>
    </tr>
  </tfoot>
</table>

JS

function handleInput(e) {
  var ss = e.target.selectionStart
  var se = e.target.selectionEnd
  e.target.value = e.target.value.toUpperCase()
  e.target.selectionStart = ss
  e.target.selectionEnd = se
}

new Vue({
  el: "#main",
  data: {
    heading: "PF Gun List (WIP)",
    lists: [
      {
        name: "M9",
        cal: "9×19mm",
        dmg: "35-10",
        cap: "15+1 / 105",
        rpm: "780",
        multi: "1.50/1.10",
        desc:
          "A 9mm Italian pistol. One of the first 'wonder nines'. High capacity with deep reserves, light recoil, and high velocity. ",
        r: "40-80",
        rank: "0",
      },
      {
        name: "GLOCK 17 (G17)",
        cal: "9×19mm",
        dmg: "34-10",
        cap: "17+1/102",
        rpm: "780",
        r: "40-90",
        multi: "1.50/1.10",
        desc:
          "A 9mm Austrian pistol renowned for its simplicity and ruggedness. Compared to the M9, it has a higher capacity, but less muzzle velocity.",
        rank: "0",
      },
      {
        name: "M1911",
        cal: ".45 ACP",
        dmg: "48-29",
        cap: "8+1/56",
        rpm: "720",
        r: "55-90",
        multi: "1.40/1.15",
        desc:
          "A classic American pistol brought into the modern age. Very high damage up close, with poor velocity and small magazine size.",
        rank: "8",
      },
      {
        name: "DESERT EAGLE (DEAGLE) L5",
        cal: ".44 MAGNUM",
        dmg: "56-32",
        cap: "8+1/40",
        rpm: "400",
        r: "50-80",
        multi: "2.00/  1.30",
        desc:
          "A modern version of the iconic Israeli-American pistol. This specific model has been lightened as well as upgraded with dual Picatinny rails and a much-needed muzzle brake. Very high damage with the capacity to instantly kill to the head up close, with rough recoil.",
        rank: "18",
      },
      {
        name: "M45A1",
        cal: ".45 ACP",
        dmg: "45-28",
        cap: "10+1/60",
        rpm: "670",
        r: "50-95",
        multi: "1.40/1.15",
        desc:
          "A modern American pistol with many custom parts. High damage, medium capacity, strong recoil.",
        rank: "34",
      },

      {
        name: "FIVE SEVEN",
        cal: "5.7×28mm",
        dmg: "29-22",
        cap: "20+1/100",
        rpm: "800",
        r: "80-120",
        multi: "1.40/1.20",
        desc:
          "A modern Belgian pistol firing a unique caliber. Poor close-in performance, with great ranged performance, high velocity, large magazine, wall penetration and deep reserves.",
        rank: "57",
      },
      {
        name: "ZIP 22",
        cal: ".22 LONG RIFLE",
        dmg: "15-12",
        cap: "10+1/180",
        rpm: "1000 SEMI",
        r: "30-60",
        multi: "2.80/1.00",
        desc:
          "A modern American 'pistol' with questionable quality. Abysmal damage, but with deep reserves and a high headshot multiplier. A weapon so bad it killed a million dollar company. 3 shots to the head at all ranges.",
        rank: "61",
      },
      {
        name: "DESERT EAGLE (DEAGLE) XIX",
        cal: ".50 ACTION EXPRESS",
        dmg: "72-37",
        cap: "7+1/21",
        rpm: "400",
        r: "40-82",
        multi: "2.50/1.40",
        desc:
          "Finally, a gun that lets you make a statement. This semi-automatic hand cannon is chambered in .50 Action Express. It'll probably pulverize your wrists with its recoil, but hey, you can't argue with the stopping power. And you've got the king of mayhem...",
        rank: "102",
      },
      {
        name: "GLOCK 18 (G18)",
        cal: "9×19mm",
        dmg: "30-20",
        cap: "19+1/57",
        rpm: "1100 AUTO",
        multi: "1.40/1.00",
        r: "20-60",
        desc:
          "A 9mm Austrian machine pistol. Fast fire rate with relatively stable handling characteristics.",
        rank: "17",
      },
    ],
    sortBy: "rank",
    filterByName: "",
    counter: 0,
  },

  computed: {
    sortedlists() {
      return this.lists
        .filter((list) => list.name.includes(this.filterByName))
        .sort((a, b) => a[this.sortBy] - b[this.sortBy])
    },
  },
})

所以我尝试使用多个 .includes 和 .filter 过滤器(我想要另一个像 list => list.name.includes(this.filterByCal) 这样的过滤器,并添加另一个带有“v-model='filterByCal'”的输入 叹息 那么有什么有用的答案吗?请? 最后一个有助于安排,但不是我想要的。所以我真的很想得到帮助!

排序函数错误地假设所有值都是数字:

.sort((a, b) => a[this.sortBy] - b[this.sortBy]) ❌ values are not numbers

这些值实际上是字符串,减去一个字符串得到 NaN,因此排序中断。

要解决此问题,您可以检查字符串中的数字,然后才使用数值的差异。否则,使用String.prototype.localeCompare进行比较:

.sort((a, b) => {
  const aVal = a[this.sortBy]
  const bVal = b[this.sortBy]

  // only check difference when values are numbers
  if (/^\d+$/.test(aVal) && /^\d+$/.test(bVal)) {
    return aVal - bVal
  } else {
    return aVal.localeCompare(bVal)
  }
})

demo