Официальный сайт:qiu8310.github.io/minapp/
автор:Mora
При разработке нативных апплетов поток данных односторонний и не может быть привязан в двух направлениях, но реализовать функцию двусторонней привязки достаточно просто!
Ниже приведен небольшой каркас программы.minappПринцип двустороннего связывания реализован вminapp, вам просто нужно добавить имя атрибута к компоненту в шаблоне wxml
.sync
Двусторонняя привязка может быть достигнута. Для того, чтобы объяснить его принцип, процесс может быть немного сложнее, но на самом делеminappFramework разобрался с этими сложными деталями!
первый,Чтобы сделать данные двусторонними, следует избегать слишком большого количества источников данных.. 在数据从上到下自然流动的情况下,如果每个组件中都维护它们自己的数据,而又要保持它们数据值的一致,这虽然可以做到,但实现过程并不会简单。 但是也没必要说为了有一个统一的数据源就使用mobxилиreduxЧтобы управлять данными глобально, это немного похоже на убийство курицы ножом. Поскольку двусторонняя привязка существует только между родительским и дочерним компонентами, а данные передаются от родительского к дочернему, данные в родительском компоненте могут использоваться в качестве источника данных в первую очередь. Каждый раз, когда дочерний компонент обновляет данные, он не обновляет свои собственные внутренние данные, а запускает родительский компонент для обновления своих данных через механизм событий, и после того, как родительский компонент обновляет данные, он естественным образом передает обновленные данные дочернему компоненту. компонент. Это обеспечивает двусторонний поток данных!
Не все данные должны быть двусторонним привязкой, не все данные являются внешними, подсагматическими также могут иметь свои внутренние данные. Таким образом, второй вопрос, который относится к тому, что мы говорим:Различать, какие данные требуют двусторонней привязки, какие данные требуют, чтобы подкомпоненты поддерживали себя.
использовалvueВсем следует знать, что для достижения двусторонней привязки в vue в шаблоне необходимо выполнить специальную обработку. Например, родительский компонентparentAttr
Двусторонняя привязка к дочерним компонентамchildAttr
, вам нужно написать это в шаблоне родительского компонента:
<child childAttr.sync="parentAttr" />
Но у апплета не такой простой синтаксис, и даже такие символы, как «.», не допускаются в имени атрибута языка wxml апплета. Вернемся к нашему вопросу,Подсборки должны знать, для каких свойств требуется двусторонняя привязка, для которых требуется собственное обслуживание свойств.,
Добавьте поле в шаблон (syncAttrMap
) специально для того, чтобы сообщить подкомпонентам, что набора данных, который необходимо связать в обоих направлениях, достаточно. Например, приведенный выше пример можно написать так, как это поддерживает апплет WeChat:
<child childAttr="{{parentAttr}}" syncAttrMap="childAttr=parentAttr" />
<!--
如果同时存在多个双向绑定和不需要双向绑定的属性时,可以写成下面这样:
p1, p2 分别双向绑定到子组件的 c1, c2,而 p3 单向绑定到 c3 上
-->
<child c1="{{p1}}" c2="{{p2}}" c3="{{p3}}" syncAttrMap="c1=p1&c2=p2" />
Далее необходимо обработатьПроблема с обновлением данных подкомпонентаТеперь в дочернем компоненте есть две части данных: одна — внутренние данные, а другая — данные родительского компонента.
Дочерние компоненты могут читать свойстваsyncAttrMap
Чтобы получить, какие данные являются внутренними данными, какие данные являются данными родительского компонента, и может знать соответствующий
Каково ключевое имя данных в родительском компоненте. Благодаря нативному компонентному подходуsetData
不会管你是内部数据,还是父组件中的数据,只要
你调用它去更新数据,它只会更新内部的数据。所以需要另外实现一个新的方法,来自动判断数据源,如果是内部数据,
позвонить напрямуюsetData
; Если это данные родительского компонента в двусторонней привязке, вы можете инициировать событие, чтобы уведомить родительский компонент об обновлении соответствующего значения.
Таким образом, согласно приведенному выше описанию, родительский компонент должен иметь функцию прослушивания, а дочерний компонент должен иметь интеллектуальную функцию.setData
функция. Не препятствовать функции слушателя родительского компонента
названныйonSyncAttrUpdate
, который устанавливает интеллект дочернего компонентаsetData
функция с именемsetDataSmart
, вы можете иметь следующий код:
// 父组件
Component({
methods: {
onSyncAttrUpdate(e) {
this.setData(e.detail) // 子组件传来的需要更新的数据
}
}
})
<!-- 父组件的模板 -->
<child childAttr="{{parentAttr}}" syncAttrMap="childAttr=parentAttr" bind:syncAttrUpdate="onSyncAttrUpdate" />
// 子组件
Component({
properties: {
childAttr: String,
syncAttrMap: String
},
methods: {
// 子组件更新数据时,只要调用此方法即可,而不是 `setData`
setDataSmart(data) {
// splitDataBySyncAttrMap 函数的实现过程就不说了,只是将对象拆分,大家应该都能实现
let {parentData, innerData} = splitDataBySyncAttrMap(data, this.data.syncAttrMap)
// 内部数据使用 setData 更新
if (Object.keys(innerData).length) {
this.setData(innerData) // setData 中还支持 callback 的回调,为了简化代码,这里不讨论
}
// 双向绑定的父组件数据触发事件让父组件自己去更新
if (Object.keys(parentData).length) {
this.triggerEvent('syncAttrUpdate', parentData)
}
}
}
})
На этом простая функция двусторонней привязки завершена. Однако, поскольку дочерний компонент может также содержать другие компоненты, то есть дочерний компонент также может быть родительским компонентом, а родительский компонент также
Может быть подкомпонентом. Итак, вышеonSyncAttrUpdate
setDataSmart
Функция должна быть реализована в каждом компоненте, поэтому не препятствуйте
определить публичный объектBaseComponent
Для достижения всех вышеперечисленных функций, таких как:
// BaseComponent
const BaseComponent = {
properties: {
syncAttrMap: String
},
methods: {
setDataSmart() {
// ...
},
onSyncAttrUpdate() {
// ...
}
}
}
Далее можно мининить BaseComponent в объект каждого компонента, кроме того, в апплете есть специальный компонент:Page, хотя структуры страницы и компонента различаются,
Но его тоже следует рассматривать как компонент, но он должен быть родительским компонентом и не может быть дочерним компонентом других компонентов, поэтому необходимо добавитьonSyncAttrUpdate
Метод написан во всех определениях Page.
все этоminappОсновной принцип двустороннего связывания.
Подождите, последнее:шаблон wxml, нельзя позволять пользователям писать такие сложные операторы каждый раз, когда они пишут двустороннюю привязку? Конечно, нет,minappВо время компиляции шаблон просто трансформируется:
<child childAttr.sync="parentAttr" />
<!-- 由于属性名 syncAttrMap 是固定的,所以完全可以通过编译手段,将上面的模板转成下面这个模板 -->
<child childAttr="{{parentAttr}}" syncAttrMap="childAttr=parentAttr" />
Спасибо, это конец статьи, прошу обратить вниманиеminapp: новое определение разработки мини-программ WeChat
В 2019 году оригинальная новая книга iKcamp «Практика разработки Koa и Node.js» была продана на JD.com, Tmall, Amazon и Dangdang!