Что такое директива v-model в Vue.js?

Если вы, как и я, разработчик Vue.js, вы наверняка слышали об очень интересной директиве v-model.

Директива v-model — это очень полезный и чистый подход как для привязки любых изменений к значению, так и для прослушивания изменений, влияющих на это значение. Или, говоря техническими словами, вы можете сказать, что v-model — это мощная директива, предоставляемая VueJS для добавления двусторонней привязки данных в vanilla Vue.js.

Реализация директивы v-model с вычисляемым свойством

Прежде чем приступить к реализации V-модели, мы должны понять внутреннюю работу директивы V-модели.

Хотя v-model="dataProperty" на первый взгляд кажется волшебством, на самом деле это сокращение для

<input :value="dataProperty" @input=dataProperty = $event.target.value" />

По умолчанию v-модель оценивается каждый раз, когда запускается ввод событие (т. е. при нажатии клавиши или вставке). Если вы хотите подождать, пока пользователь закончит печатать и размоет поле ввода (щелкните за пределами поля ввода), вы можете использовать модификатор lazy над v-моделью.

<input v-model.lazy="value" />

В файле CoustomSearchInput.vue создайте пользовательский компонент, который принимает свойства — value, optionsArr и placeholderValue.

<template>
  <div class="container">
    <input ref="inputField" v-model="inputVal" class="val-input" type="text" :placeholder="placeholderValue />
<!-- options Dropdown -->
<div class="data-options" v-if="filterOptionArray.length > 0" :class="{ 'd-none': openFlag }" >
      <div ref="dataDiv" class="general-modal-scroll-bar">
        <li
          v-for="option in filterOptionArray"
          :key="option"
          class="item"
          @click=" inputVal = option;
            $emit('input', option); " >
          {{ option }}
        </li>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "SearchInput",
  props: {
    optionsArr: {
      type: Array,
      default: () => [],
    },
    value: {
      type: String,
      default: "",
    },
    placeholderValue: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      inputVal: "",
      openFlag: true,
    };
  },
mounted() {
    this.inputVal = this.value;
    // Closing the options panel on load of the component
    document.addEventListener("click", this.close);
  },
  beforeDestroy() {
    // Closing the options panel on leaving the component
    document.removeEventListener("click", this.close);
  },
// this computed property is responsible for the fitering the array according input value
  computed: {
    filterOptionArray() {
      if (this.inputVal.length === 0) {
        return this.optionsArr;
      } else {
        return this.optionsArr.filter((option) => {
          let temp = option.toLowerCase();
          return temp.match(this.inputVal);
        });
      }
    },
  },
// keep a watch on inputVal if it's value change then we close the options Panel
  watch: {
    inputVal(newVal) {
      this.openFlag = false;
    },
  },
  methods: {
    // Options Panel close method
    close(e) {
      if (
        e.target !== this.$refs.dataDiv &&
        e.target !== this.$refs.inputField
      ) {
        this.openFlag = true;
      }
    },
  },
};
</script>

Итак, мы получаем value в качестве реквизита от родительского компонента. В соответствии с шаблоном проектирования Vue 2 нам не разрешалось напрямую манипулировать данными реквизита. Чтобы решить эту проблему, мы создаем локальное свойство данных inputVal и сохраняем данные реквизита value в inputVal, а после этого привязываем inputVal к полю ввода.

Теперь мы создаем вычисляемое свойство filterOptionArray, которое отвечает за параметры, доступные для выбора из раскрывающегося списка, в зависимости от ввода пользователя. Это вычисляемое свойство возвращает массив, который мы используем для отображения раскрывающегося списка.

Когда пользователь clicks находится в любом элементе раскрывающегося списка, это emits событие, чтобы информировать своего родителя об изменениях.

В родительском компоненте — файл App.js.

<template>
  <div id="app">
    <CustomSearchInput
      :optionsArr="arr"
      v-model="selected"
      placeholderValue="Enter start typing to get options"
    />
<div class="display-data" v-if="selected.length > 0" >Selected Value: {{ selected }}</div>
  </div>
</template>
<script>
import CustomSearchInput from "./components/CoustomSearchInput";
export default {
  name: "App",
  components: { CustomSearchInput },
  data() {
    return {
      arr: ["jhon", "jay", "shiv", "jani", "shawn", "shelly", "bob", "carry", "Alex", "Anthoney" ],
      selected: "",
    };
  },
};
</script>

Поиграйте с кодом здесь

Мы можем использовать этот метод для объединения вычисляемых свойств и v-модели, чтобы написать самый надежный и лучший код на Vue.js.

Дополнительные примечания:

  • Если вы хотите преобразовать пользовательский ввод в число вместо строки, добавьте модификатор v-model.number.
  • Модификатор v-model.trim удалит начальные или конечные пробелы из связанной строки. (нельзя использовать вместе с v-model.number).

О себе:

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

Не стесняйтесь связаться со мной:
LinkedIn
Github

Спасибо, продолжайте кодировать