В предыдущем посте я писал о своей одержимости перетасовкой массивов JavaScript в контексте Vue.js. В последнее время я увлекся методами предотвращения внедрения повторяющихся значений в массивы. Поэтому основное внимание в этой статье будет уделено тому, как использовать различные методы JavaScript для предотвращения дублирования значений массива в проектах на основе Vue.

Для этого проекта мы создадим простой интерфейс Vue 3/TailwindCSS, который предлагает пользователю вводить числовые значения, которые, в свою очередь, помещаются в массив. Затем значения массива назначаются 5 слотам на экране. Если пользователь попытается ввести одно и то же значение дважды, он увидит предупреждение с надписью Дубликаты не допускаются!, прежде чем продолжить ввод дополнительных данных. В этой статье мы рассмотрим 3 различных конфигурации метода массива, которые разработчики могут использовать для предотвращения дублирования значений массива (при необходимости) в Vue 3.

Давайте начнем!

Настройка проекта

Для этого проекта мы будем использовать простую конфигурацию Vue 3 на основе CDN с TailwindCSS вместо настройки Tailwind + Vite, описанной в других моих постах.

Сначала откройте IDE, скопируйте и вставьте следующий код шаблона в HTML-файл:

<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.tailwindcss.com"></script>

<div id="demo" class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8 bg-gray-100">
  <div class="px-4 py-6 sm:px-0">
    <input v-model="number" type="number" class="border-solid border-2 px-5 py-1.5 mr-2 mb-2 rounded" />
    <button @click="submit" type="submit" class="text-white bg-blue-700 hover:bg-blue-800 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2">
      Submit
    </button>
      
    <div class="flex items-center justify-center py-16 mt-12">
      <div v-for="num in finalArray" :key="num.id" class="w-72 h-72 m-2">
        <div class="flex justify-center items-center w-full h-full p-8 text-9xl rounded-md shadow-lg border-solid border-2 border-sky-500">
            {{ num.val }}
        </div>
      </div>
    </div>
  </div>
</div>

Затем настройте следующий блок сценария под шаблоном:

<script>
  const { ref } = Vue
  const app = Vue.createApp({
    setup() {
      // functionality goes here

      return {
        // properties
      };
    }
  })
  app.mount('#demo')
</script>

Внутри функции setup() и блока возврата добавьте свойства привязки и функцию submit(), которые будут использоваться для упрощения ввода и передачи значений в массив:

<script>
  const { ref } = Vue
  const app = Vue.createApp({
    setup() {

      const numberValue = ref(null)
      const numberArray = ref([])
      const finalArray = ref([
        {val: ''},
        {val: ''},
        {val: ''},
        {val: ''},
        {val: ''},
      ])

      const submit = () => {

        // add functionality to prevent duplicates here

        finalArray.value = [
          {val: numberArray.value[0]},
          {val: numberArray.value[1]},
          {val: numberArray.value[2]},
          {val: numberArray.value[3]},
          {val: numberArray.value[4]},
        ]

        numberValue.value = ""
      }

      return {
        numberValue, numberArray, finalArray, submit
      };
    },
  })
  app.mount('#demo')
</script>

На данный момент у нас есть свойство numberValue, привязанное к полю ввода. Каждое введенное значение будет передано в массив с именем numberArray. Затем мы установим каждое значение numberArray для отдельных объектов, составляющих finalArray, таким образом позволяя каждому значению numberArray занимать отдельный слот в пользовательском интерфейсе (см. скриншот выше).

Теперь, когда у нас есть основная настройка, давайте рассмотрим 3 примера того, как предотвратить дублирование значений массива!

1. метод найти()

В первом примере, который мы рассмотрим, используется метод find() внутри функции submit() для поиска существующих значений в numberArray.

const submit = () => {

  //Example 1
  const existingValue = numberArray.value.find(item => item === numberValue.value)
  if (existingValue) {
    alert('No Duplicates Allowed!');
    return
  }
  numberArray.value.push(numberValue.value);

  numberArray.value = [...numberArray.value.slice(0,5)]

  finalArray.value = [
    {val: numberArray.value[0]},
    {val: numberArray.value[1]},
    {val: numberArray.value[2]},
    {val: numberArray.value[3]},
    {val: numberArray.value[4]},
  ]

  numberValue.value = ""
}

Метод find() возвращает первый элемент в numberArray, удовлетворяющий условию item === numberValue.value. Если пользователь попытается ввести существующее значение в массиве, появится предупреждающее сообщение. Возврат внутри условного выражения existingValue не позволит функции поместить повторяющееся значение в numberArray.

Поскольку мы имеем дело только с 5 слотами значений в пользовательском интерфейсе, мы можем предотвратить передачу более 5 значений в numberArray, добавив в конце метод slice() массива. Затем мы воспользуемся оператором spread (…), чтобы установить значения numberArray в новой копии этого массива. Мы будем использовать аналогичную настройку для предотвращения более 5 значений в массиве в следующих двух примерах.

Последний блок скрипта с примером 1 выглядит следующим образом:

<script>
  const { ref } = Vue
  const app = Vue.createApp({
    setup() {

      const numberValue = ref(null)
      const numberArray = ref([])
      const finalArray = ref([
        {val: ''},
        {val: ''},
        {val: ''},
        {val: ''},
        {val: ''},
      ])

      const submit = () => {

        //Example 1
        const existingValue = numberArray.value.find(item => item === numberValue.value)
        if (existingValue) {
          alert('No Duplicates Allowed!');
          return
        }
        numberArray.value.push(numberValue.value);

        numberArray.value = [...numberArray.value.slice(0,5)]

        finalArray.value = [
          {val: numberArray.value[0]},
          {val: numberArray.value[1]},
          {val: numberArray.value[2]},
          {val: numberArray.value[3]},
          {val: numberArray.value[4]},
        ]

        numberValue.value = ""
      }

      return {
        numberValue, numberArray, finalArray, submit
      };
    },
  })
  app.mount('#demo')
</script>

2. метод filter()

В этом примере мы будем использовать метод filter() для создания нового массива с уникальными значениями.

const submit = () => {

  //Example 2
  numberArray.value.push(numberValue.value)
  const uniqueArray = numberArray.value.filter((value, index, array) => array.indexOf(value) === index);

  if (numberArray.value.indexOf(numberValue.value) !== numberArray.value.lastIndexOf(numberValue.value)) {
    alert('No Duplicates Allowed!');
  }

  numberArray.value = [...uniqueArray.slice(0,5)]

  finalArray.value = [
    {val: numberArray.value[0]},
    {val: numberArray.value[1]},
    {val: numberArray.value[2]},
    {val: numberArray.value[3]},
    {val: numberArray.value[4]},
  ]

  numberValue.value = ""
}

Внутри метода filter() мы будем использовать метод indexOf() для нацеливания на первый индекс заданного значения в numberArray. Если пользователь помещает только один экземпляр значения в numberArray, тогда array.indexOf(value) === index внутри метода filter() будет равно, в то время как значение добавляется к uniqueArray.

Между тем, если пользователь попытается поместить в массив еще один экземпляр существующего значения, то array.indexOf(value) вернет индекс первого экземпляра значения в массиве, а index возвращает индекс второго экземпляра. В этом случае array.indexOf(value) === index НЕ будет равен, и второй экземпляр существующего значения НЕ будет добавлен в uniqueArray. Затем мы будем использовать оператор расширения (…), чтобы установить значения uniqueArray в новой копии массива, в свою очередь назначив эту копию числовой массив.

Наконец, мы будем использовать условное выражение для обработки alert() при обнаружении дубликатов. Внутри условного выражения мы будем использовать indexOf() для определения индекса первого экземпляра заданного значения, а lastIndexOf(), как вы, вероятно, догадались, индекс последнего экземпляра того же значения. Если они не равны, это означает, что значение, на которое нацелена функция lastIndexOf(), является повторяющимся значением. Затем сработает alert().

Последний блок скрипта с примером 2 выглядит следующим образом:

<script>
  const { ref } = Vue
  const app = Vue.createApp({
    setup() {

      const numberValue = ref(null)
      const numberArray = ref([])
      const finalArray = ref([
        {val: ''},
        {val: ''},
        {val: ''},
        {val: ''},
        {val: ''},
      ])

      const submit = () => {

        //Example 2
        numberArray.value.push(numberValue.value)

        const uniqueArray = numberArray.value.filter((val, idx, arr) => arr.indexOf(val) === idx);

        if (numberArray.value.indexOf(numberValue.value) !== numberArray.value.lastIndexOf(numberValue.value)) {
          alert('No Duplicates Allowed!');
        }

        numberArray.value = [...uniqueArray.slice(0,5)]

        finalArray.value = [
          {val: numberArray.value[0]},
          {val: numberArray.value[1]},
          {val: numberArray.value[2]},
          {val: numberArray.value[3]},
          {val: numberArray.value[4]},
        ]

        numberValue.value = ""
      }

      return {
        numberValue, numberArray, finalArray, submit
      };
    },
  })
  app.mount('#demo')
</script>

3. Установить объект

В последнем примере мы будем использовать объект Set для создания набора уникальных значений на основе значений, помещенных в numberArray.

const submit = () => {

  //Example 3
  numberArray.value.push(numberValue.value)
  if (numberArray.value.indexOf(numberValue.value) !== numberArray.value.lastIndexOf(numberValue.value)) {
    alert('No Duplicates Allowed!');
  }
  numberArray.value = [...new Set(numberArray.value.slice(0,5))]

  finalArray.value = [
    {val: numberArray.value[0]},
    {val: numberArray.value[1]},
    {val: numberArray.value[2]},
    {val: numberArray.value[3]},
    {val: numberArray.value[4]},
  ]

  numberValue.value = ""
}

Если вы не знакомы с этой концепцией, JavaScript Set представляет собой набор уникальных значений, в котором каждое значение может встречаться только один раз. Передача numberArray в new Set позволит нам вернуть новую копию numberArray с уникальными значениями (без дубликатов). Мы также будем использовать условное выражение indexOf()/lastIndexOf(), как в примере 2, для обработки ошибки Дубликаты не допускаются! предупреждение.

Последний блок скрипта с примером 3 выглядит следующим образом:

<script>
  const { ref } = Vue
  const app = Vue.createApp({
    setup() {

      const numberValue = ref(null)
      const numberArray = ref([])
      const finalArray = ref([
        {val: ''},
        {val: ''},
        {val: ''},
        {val: ''},
        {val: ''},
      ])

      const submit = () => {

        //Example 3
        numberArray.value.push(numberValue.value)
        if (numberArray.value.indexOf(numberValue.value) !== numberArray.value.lastIndexOf(numberValue.value)) {
          alert('No Duplicates Allowed!');
        }
        numberArray.value = [...new Set(numberArray.value.slice(0,5))]

        finalArray.value = [
          {val: numberArray.value[0]},
          {val: numberArray.value[1]},
          {val: numberArray.value[2]},
          {val: numberArray.value[3]},
          {val: numberArray.value[4]},
        ]

        numberValue.value = ""
      }

      return {
        numberValue, numberArray, finalArray, submit
      };
    },
  })
  app.mount('#demo')
</script>

Мы дошли до конца! Теперь вы знаете несколько способов предотвратить дублирование значений массива в Vue 3!

Я очень надеюсь, что это поможет. Если вам нравится этот контент, пожалуйста, найдите время, чтобы похлопать, прокомментировать и подписаться!

Другие сообщения этого автора: