[Переосмысление Vue] Является ли принцип ответа данных действительно двусторонней привязкой?

Vue.js
[Переосмысление Vue] Является ли принцип ответа данных действительно двусторонней привязкой?

Недавно автор Ant Design Vue, Тан Цзиньчжоу, начал курс на определенной платформе, и на протяжении всего курса он систематически описывал реальное развитие Vue. В восьмой лекции я представил проблему двусторонней привязки Vue.Здесь я организую некоторые данные и проанализирую их объективно.Является ли принцип ответа данных Vue двусторонней привязкой?.


Многие студенты понимают принцип ответа данных Vue как двустороннюю привязку, когда они понимают Vue, но на самом деле это неточно.Отклик данных, о котором мы упоминали ранее, управляется изменениями данных для изменения представлений DOM.В дополнение к DOM, управляемому данными , двусторонняя привязка, в свою очередь, влияет на данные, что является двусторонней связью.В Vue мы можем передатьv-modelдля достижения двусторонней привязки.

Есть два способа отразить роль двусторонней привязки в Vue.Перед анализом давайте представим разницу между этими двумя способами использования.

1) атрибут v-модели

2) модификатор .sync

v-model

2.2.0+ Новый

на компонентеv-modelПо умолчанию будет использоватьсяvalueОпора и имяinputсобытий, но элементы управления вводом, такие как радиокнопки, флажки и т. д., могутvalueЧерты используются для разных целей.modelЧтобы избежать таких конфликтов, можно использовать параметры:

ChildBox.vue

<template>
  <input type="checkbox"
         :checked="checked"
         @change="$emit('change', $event.target.checked)"/>
</template>

<script>
export default {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  }
}
</script>

Index.vue

<template>
  <div>
    <ChildBox v-model="val"/>
    <!-- 解析后 -->
    <ChildBox :value="val"
              @change="data => (val = data)"/>
  </div>
</template>

Проанализируйте код выше. Файл ChildBox.vue просто инкапсулирует флажок и предоставляет проверенный параметр. Файл Index.vue является родительским компонентом, а ChildBox упоминается как собственный дочерний компонент, поэтому вам нужно обратить на это внимание. Привязка значений val использует v-model вместо v-bind:checkbox. В начале мы упомянули, что существует два способа двусторонней привязки: один — v-model, а другой — .sync (об этом позже). Если используется v-модель, реквизиты дочернего компонента должны устанавливать значение value, а проход вверх должен быть $emit('input'). Итак, вот еще один важный момент,modelэффект.

model

2.2.0 Новый

Разрешить использование пользовательского компонентаv-modelПри настройке реквизита и событий. По умолчанию в компонентеv-modelположитvalueкак опора и положитьinputИспользуется как событие, но некоторые типы ввода, такие как переключатели и кнопки-флажки, могут захотеть использоватьvalueреквизит для разных целей. использоватьmodelВарианты могут избежать конфликтов, возникающих в этих ситуациях.

модификатор .sync

2.3.0+ Новый

В некоторых случаях нам может понадобиться «двусторонняя привязка» реквизита. К сожалению, истинное двустороннее связывание создает проблемы сопровождения, поскольку дочерние компоненты могут изменять родительский компонент, а очевидных источников изменений как в родительском, так и в дочернем компонентах нет.

Вот почему мы рекомендуемupdate:myPropNameСобытие модального триггера заменено. Например, в содержащемtitleВ гипотетическом компоненте реквизита мы можем выразить свое намерение присвоить ему новое значение следующими способами:

ChildBox.vue

<template>
  <input type="checkbox"
         :checked="checked"
         @change="$emit('update:checked', $event.target.checked)"/>
</template>

<script>
export default {
  props: {
    checked: Boolean
  }
}
</script>

Index.vue

<template>
  <div>
    <ChildBox :checked.sync="val"/>
    <!-- 解析后 -->
    <ChildBox :checked="val"
              @update:checked="data => (val = data)"/>
  </div>
</template>

Проанализируйте, что изменилось в приведенном выше коде, родительском компонентеv-modelодеяло:checked.syncзаменять. Подкомпоненты не применимы из-заv-model, поэтому конфигурация модели не требуется. изменить функцию наemit('update:checked',событие.цель.проверено).

анализ исходного кода v-модели

с помощьюРаскрыта технология Ustbhuangyi Vue.js. Здесь проводится только сводное сравнение, а подробный процесс анализа можно посмотреть по ссылке.

В качестве примера возьмем следующий код:

let vm = new Vue({
  el: '#app',
  template: '<div>'
  + '<input v-model="message" placeholder="edit me">' +
  '<p>Message is: {{ message }}</p>' +
  '</div>',
  data() {
    return {
      message: ''
    }
  }
})

устанавливается на входной элементv-modelсобственность, связаннаяmessage, когда мы набираем что-то на входе,messageтакже изменится в то же время.

Функция генерации исходного кода:

function generate (
  ast,
  options
) {
  var state = new CodegenState(options);
  var code = ast ? genElement(ast, state) : '_c("div")';
  return {
    render: ("with(this){return " + code + "}"),
    staticRenderFns: state.staticRenderFns
  }
}

Для нашего примера в результатеrenderкод показывает, как показано ниже:

with(this) {
  return _c('div',[_c('input',{
    directives:[{
      name:"model",
      rawName:"v-model",
      value:(message),
      expression:"message"
    }],
    attrs:{"placeholder":"edit me"},
    domProps:{"value":(message)},
    on:{"input":function($event){
      if($event.target.composing)
        return;
      message=$event.target.value
    }}}),_c('p',[_v("Message is: "+_s(message))])
    ])
}

что в конечном итоге переводится как:

<input
  v-bind:value="message"
  v-on:input="message=$event.target.value">

динамически связанныйinputизvalueуказал наmessgaeпеременная и запускinputКогда событие переходит в динамикуmessageУстановите целевое значение, чтобы двусторонняя привязка данных была фактически завершена, так сказатьv-modelНа самом деле это синтаксический сахар.

ustbhuangyiПринцип реализации v-модели в компонентах также подробно описан в обзоре технологии Vue.js, поэтому я не буду подробно описывать его здесь.

Суммировать

мы понимаем, чтоv-modelЭто реальная реализация двусторонней привязки Vue, но по сути это синтаксический сахар, который может поддерживать как собственные элементы формы, так и пользовательские компоненты. В реализации компонента мы можем настроить подкомпонент на получениеpropимя и имя отправленного события.

Последний вопросv-modelа также.syncОба могут добиться эффекта двусторонней привязки данных, так какой из них более разумен? Добро пожаловать, чтобы ответить, чтобы выразить свое мнение.

Желаю прогресса в учебе

Дэн Вэньбинь

21 марта 2019 г.