Глубокое понимание одностороннего потока данных Vue

Vue.js MVVM
Глубокое понимание одностороннего потока данных Vue

Когда я раньше видел этот односторонний поток данных в документе vue, я был немного озадачен, я потер его, не является ли vue двусторонней привязкой, что это за хрень, и я прочитал документ, что есть два случая изменить реквизит План обработки. Все еще немного подозрительно. Отсюда и эта статья.

Начните с v-модели

1. v-модель используется на входном элементе

v-model очень похожа на двухстороннюю привязку при использовании (на самом деле...), но Vue — это поток данных с одним элементом, а v-model — это просто синтаксический сахар:

<input v-model="something" />
<input v-bind:value="something" v-on:input="something = $event.target.value" />

Первая строка кода на самом деле просто синтаксический сахар для второй строки. Тогда вторую строку кода можно сократить как:

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

Чтобы понять эту строку кода, вы должны сначала знать, что сам элемент ввода имеет событие oninput, которое недавно добавлено в HTML5, аналогично onchange.Каждый раз, когда содержимое поля ввода изменяется, oninput будет запущен, и последнее значение будет передано в событие $event.something.

Внимательно наблюдаем за двумя строчками кода синтаксического сахара и оригинальным синтаксисом и можем сделать вывод: При добавлении атрибута v-model к элементу ввода значение используется как атрибут элемента по умолчанию, а затем событие «ввод» используется в качестве значения передачи значения в реальном времени.

2. v-модель используется на компонентах

v-model можно использовать не только на входе, но и на компонентах, посмотрите демо на официальном сайте.

<currency-input v-model="price"></currency-input>
Vue.component('currency-input', {
  template: '\
    <span>\
      $\
      <input\
        ref="input"\
        v-bind:value="value"\
        v-on:input="updateValue($event.target.value)"\
      >\
    </span>\
  ',
  props: ['value'], // 为什么这里要用 value 属性,value在哪里定义的?
  methods: {
    // 不是直接更新值,而是使用此方法来对输入值进行格式化和位数限制
    updateValue: function (value) {
      var formattedValue = value
        // 删除两侧的空格符
        .trim()
        // 保留 2 位小数
        .slice(
          0,
          value.indexOf('.') === -1
            ? value.length
            : value.indexOf('.') + 3
        )
      // 如果值尚不合规,则手动覆盖为合规的值
      if (formattedValue !== value) {
        this.$refs.input.value = formattedValue
      }
      // 通过 input 事件带出数值
      // <!--为什么这里把 'input' 作为触发事件的事件名?`input` 在哪定义的?-->
      this.$emit('input', Number(formattedValue))
    }
  }
})

Если вы знаете ответы на эти два вопроса, то поздравляю, вы действительно освоили v-model, если не поняли, то можете посмотреть на этот код:

<currency-input v-model="price"></currency-input>
所以在组件中使用时,它相当于下面的简写:
//上行代码是下行的语法糖
<currency-input :value="price" @input="price = arguments[0]"></currency-input>

Поэтому при добавлении атрибута v-model к компоненту значение будет использоваться как атрибут компонента по умолчанию, а затем значение «вход» будет использоваться как имя события при привязке событий к компоненту. Это особенно полезно при написании компонентов.

3. Недостатки и решения v-модели

При создании общих компонентов, таких как флажки или радио, v-модель работает плохо.

<input type="checkbox" v-model="something" />

<input type="checkbox" :checked="value" @change="change(value, $event)"

<checkbox v-model="value"></checkbox>

Vue.component('checkbox', {
  tempalte: '<input type="checkbox" @change="change" :checked="currentValue"/>'
  props: ['value'],
  data: function () {
        return {
            //这里为什么要定义一个局部变量,并用 prop 的值初始化它。
            currentValue: this.value
        };
    },
  methods: {
    change: function ($event) {
      this.currentValue = $event.target.checked;
      this.$emit('input', this.currentValue);  
    }
})