Высшее благо подобно воде, а вода хороша для всего без борьбы. - «Дао Дэ Цзин»
Введение
При нормальной разработке часто используется некоторая связь между компонентами родитель-потомок, которая часто используетсяprops
,vuex
Подождите, вот еще три способа записиv-model
,sync
Как его использовать, и как реализовать, собственноv-model
,sync
Это все синтаксический сахар. а также$attrs
,$listener
Реализовать связь между родительскими и дочерними компонентами.
Как использовать
v-model
2.2.0+ Новый
v-mode1
По сути, это синтаксический сахар, по умолчанию он будет использовать имяvalue
изprops
и назвалinput
событий, но такие элементы ввода, как радиокнопки, флажки и т. д., могут говоритьvalue
Черты используются для разных целей.
v-model
сценарии использования: когдаПодсборкаНеобходимо изменить родительский компонент черезprops
входящее значение
родительский компонент
- родительский компонент через
v-model
значение привязки - Согласно с
v-model
Входящее значение изменяется и запускает другие обновления, пожалуйста, передайтеwatch
входящее значение
Подсборка
- утверждение
model
событие набора объектовevent
а такжеprop
поле - пройти через
porps
Принять значение, переданное родительским компонентом - Модификация проходит через
this.$emit
трансляция события
Пример кода:
код родительского компонента
<template>
<children v-model="message"></children>
</template>
<script>
import children from "./children.vue";
export default {
components: {
children
},
data() {
return {
message: "parent"
};
},
watch: {
// 监听message变化
message(newV, oldV) {
console.log(newV, oldV);
}
}
};
</script>
код подкомпонента
<template>
<h1>{{ message }}</h1>
</template>
<script>
export default {
model: {
prop: "message", //这个字段,是指父组件设置 v-model 时,将变量值传给子组件的 msg
event: "input" //这个字段,是指父组件监听 parent-event 事件
},
props: {
message: String //此处必须定义和model的prop相同的props,因为v-model会传值给子组件
},
mounted() {
//这里模拟异步将msg传到父组件v-model,实现双向控制
setTimeout(_ => {
this.$emit("input", "children");
//将这个值通过 emit 触发parent-event,将some传递给父组件的v-model绑定的变量
}, 1500);
}
};
</script>
Приведенный выше пример выполняетсяv-model
Реализовано, следующее не проходитv-model
добиться такого же эффекта.
Реализовано без v-модели
Пример кода выглядит следующим образом:
Модификация кода родительского компонента
<template>
<Children :message="message" @input="(event) => { message = event }"/>
</template>
<script>
// 不变
</script>
Модификация кода субкода
<template>
// 不变
</template>
<script>
export default {
props: {
message: String
},
mounted() {
setTimeout(() => {
this.$emit("input", "children");
}, 1500);
}
};
</script>
просто поставьv-model
разделить наprops
а также@input
События, подкомпоненты не нужно настраиватьmodel
, просто примиprops
и черезthis.$emit
Просто транслируйте событие.
Конечно, это относительноv-model
Этот метод относительно прост, но существует множество проверок гибкости, и выбор зависит от личных предпочтений.
Интернет-адрес:
не могу поставитьiframe
Просто поставь ссылкуЭтот пример кода
sync
2.3.0+ Новый
В некоторых случаях нам может понадобитьсяprop
провести**«Двусторонняя привязка». К сожалению, настоящийДвусторонняя привязка ** вызовет проблемы с обслуживанием, поскольку дочерний компонент может модифицировать родительский компонент, а очевидного источника изменений в родительском и дочернем компонентах нет.
Вот почему мы рекомендуемupdate:myPropName
Событие модального триггера заменено. Также возможно пройтиsync
модификатор для реализации.
Приведенный выше код примерно изменен следующим образом:
родительский компонент
- Инициировать события, изменяя
input
дляupdate:myPropName
добиться такого же эффекта
Подсборка
- путем изменения
this.$emit(update:myPropName)
код показывает, как показано ниже:
Модификация кода родительского компонента
// 修改如下
<Children :message="message" @update:input="(event) => { message = event }"/>
Модификация кода подкомпонента
// 其他不变
this.$emit("update:input", "children");
реализация синхронизации
Приведенный выше код может быть выполнен с помощьюsync
Сокращенный до следующего кода:
Модификация кода родительского компонента
// 修改如下
<Children :messag.sync="message"/>
Модификация кода подкомпонента
// 其他不变
this.$emit("update:messag", "children");
в то же времяsync
Объекты также поддерживаются, сотрудничатьv-bind
Реализация может быть сокращена как:
, но обратите внимание на следующие две особенности этого объекта:
Примечание с
.sync
модификаторv-bind
нельзя использовать с выражениями (например,v-bind:title.sync=”doc.title + ‘!’”
это недействительно). Вместо этого вы можете указать только имя свойства, которое хотите связать, напримерv-model
. Будуv-bind.sync
используется на буквальном объекте, например.v-bind.sync=”{ title: doc.title }”
, не будет работать, потому что при анализе такого сложного выражения необходимо учитывать множество пограничных случаев.
listeners
$attrs
2.4.0 Новый
- Типы:
{ [key: string]: string }
- только чтение
- подробно:
содержит бездействие в родительской области
prop
Распознанные (и приобретенные) привязки функций (class
а такжеstyle
Кроме). Когда компонент не объявляет никакихprop
, это будет включать все привязки родительской области (class
а такжеstyle
кроме), и может пройтиv-bind="$attrs"
Передача внутренних компонентов — полезно при создании высокоуровневых компонентов.
$listeners
2.4.0 Новый
- Типы:
{ [key: string]: Function | Array<Function> }
- только чтение
- подробно:
Входит в родительскую область (исключая
.native
модификатор)v-on
прослушиватель событий. это может пройтиv-on="$listeners"
Передача внутренних компонентов — полезно при создании компонентов более высокого уровня.
включить связь
Реализовать связь между родительскими и дочерними компонентами
код родительского компонента
<template>
<div class="parent">
<Children
:message="message"
@upDate="upDate"
type="del"
@input="(event) => { message = event }"
/>
</div>
</template>
<script>
import Children from "./Children";
export default {
components: {
Children
},
data() {
return {
message: "parent",
type: "del"
};
},
methods: {
upDate (event) {
console.log(event);
this.type = event;
}
},
watch: {
message: function() {
console.log("更新message值为" + this.message);
}
}
};
</script>
код подкомпонента
<template>
<div v-bind="$attrs" v-on="$listeners" class="children">{{message}} <span @click="$listeners.upDate('data')">{{$attrs.type}}</span></div>
</template>
<script>
export default {
props: {
message: String
},
mounted() {
// console.log(this.$attrs);
// console.log(this.$listeners);
setTimeout(() => {
this.$emit("input", "children");
this.$emit('upDate', 'add')
}, 1500);
}
};
</script>
в то же время$attrs
,$listeners
Оба могут быть междоменными компонентами «родитель-потомок» и могут передаваться между компонентами «родитель-потомок», подобноreact
серединаcontext
, но часть концепции дизайна та же.
Суммировать
На самом деле выявляется.sync
модификатор, вcomplier
Этап будет компилироваться и генерировать несколькоprop
, генерируя несколько事件
. На самом деле вот такинструкция,модификатор,пользовательская директивавсе вvue
Компиляция разбивается наv8исполняемый код.
Будь тоvue
,babel
,react
изcomplier
Фаза компиляции условно делится на три этапа:
- путем лексического разбора
parse
порождающая абстракцияAST
или抽象代码树
- оптимизация
AST
,Напримерvue
пометить статические узлы,babal
Извлечение статического кода изoptimize
или优化AST树
- существует
AST
На этапе кода генерируется исполняемый код, этот процесс можно назватьcodegen
v-model
,sync
Может быть достигнута связь между родительским и дочерним компонентами, и значение, переданное родительским компонентом, может быть изменено в дочернем компоненте. Эти два метода можно использовать при обычном входе в рынок, а выбор конкретного метода зависит от личных предпочтений. существуетelement-ui
этоinput
Компоненты также используют связанные свойства.