Когда я раньше видел этот односторонний поток данных в документе 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);
}
})