Heim > Artikel > WeChat-Applet > Lassen Sie uns darüber sprechen, wie Sie eine abgeschnittene Wasserfall-Flow-Komponente in einem kleinen Programm implementieren
Wie implementiert man eine abgeschnittene Wasserfall-Flusskomponente in einem Miniprogramm? Im folgenden Artikel erfahren Sie, wie Sie ein WeChat-Applet implementieren, das die Wasserfall-Flow-Komponente kürzen kann. Ich hoffe, dass es Ihnen hilfreich sein wird.
Wasserfallfluss ist eine gängige Layoutmethode. Es gibt viele Möglichkeiten, ihn zu implementieren, z. B. die direkte Aufteilung in zwei Spalten und die anschließende Steuerung des Hinzufügens von Elementen in der linken und rechten Spalte Seiten durch absolute Positionierung. [Verwandte Lernempfehlungen: Mini-Tutorial zur Programmentwicklung]
Der in diesem Artikel vorgestellte Wasserfallfluss unterscheidet sich vom herkömmlichen, da der Wasserfallfluss in der Mitte möglicherweise abgeschnitten ist:
Für das obige Layout , wenn die Aufteilung in zwei Spalten erzwungen wird Es ist nicht für das Layout geeignet, daher habe ich für das Layout die absolute Positionierung verwendet Da die Höhe der Elemente im Wasserfallfluss nicht festgelegt ist, muss ich einen Weg finden, die Höhe zu ermitteln jedes Elements und bestimmen Sie dann, ob das Element eine ganze Zeile ist, entweder links oder rechts.
Werfen wir zunächst einen Blick auf die Implementierung des Vorlagenteils:
<view class="container" style="height:{{height}}px;"> <view wx:for="{{list}}" wx:key="index" style="{{item.style}}" class="wrapper"> <abstract item="{{item}}"/> </view> </view> <view wx:if="{{tmp}}" class="computed-zone"> <view class="wrapper"> <abstract item="{{tmp}}"/> </view> </view>
Die Vorlage ist relativ einfach, ein container
-Container, durchläuft dann das Array und rendert eine Menge Wrapper
Container flach. container
容器,然后循环数组,平级渲染出一堆 wrapper
容器。
wrapper
容器是一个绝对定位的包裹元素,wrapper
容器里面需要放置需要实际渲染的组件,为了灵活性更高一点,我把这个渲染组件设置成了虚拟节点,在使用组件的时候可以指定实际渲染的自定义组件。
因为 wrapper
元素是绝对定位的,因此我们需要手动去维护整个 container
容器的高度。
这里有个问题是,我们怎么获取里面元素的高度呢?模板中的 computed-zone
就是来解决这个问题的,在将元素放置到数组之前,我们先把元素在 computed-zone
中进行渲染,然后通过 WXML api 来获取其中元素的实际渲染尺寸,这样我们就可以知道这个元素实际渲染的宽高度了。
有了每个元素的渲染尺寸信息之后,我们需要确认元素到底是占满整行,还是占半边:
如果元素的渲染宽度跟容器一样,那么就可以判断这个元素沾满一整行,需要将包裹容器 wrapper
设置为一整行的宽度;
如果不满足1条件,那么就需要基于左右元素的总高度,将 wrapper
放在左侧或者右侧。
分析下来,需要稍微写点儿逻辑的就是对 wrapper
计算偏移量,处理到底放左边还是放右边,亦或者占满整行,核心的代码实现如下:
{ // 将 setData Promise 化,方便使用 $setData(data) { return new Promise(resolve => { this.setData(data, () => { resolve(); }); }); }, // 获取元素的渲染尺寸 getRect(item) { return this.$setData({ tmp: item, }).then(() => { return new Promise((resolve, reject) => { const query = this.createSelectorQuery(); // 注意要使用 this,不要再使用 wx 前缀了 query.select('.computed-zone .wrapper').boundingClientRect(); query.exec(ret => { if (ret[0]) { resolve(ret[0]); } else { reject('not found dom!'); } }); }); }); }, // 添加元素,内部使用 addItem(item) { let tick = this.tick; return this.getRect(item).then(rect => { if (tick !== this.tick) { return Promise.reject('tick'); } const { margin } = this.data; let { height, width } = rect; const windowWidth = this.sysInfo.windowWidth; let [ leftTotal, rightTotal ] = this.height; // leftTotal 左侧栏高度,rightTotal 右侧栏高度, let marginPx = this.sysInfo.getPx(margin); let style = ''; if (Math.abs(width - windowWidth) < 3) { // 占满屏幕宽度 style = `left:0;top:${ Math.max(leftTotal, rightTotal) }px;width:100%;`; leftTotal = rightTotal = Math.max(leftTotal + height, rightTotal + height); } else if (rightTotal < leftTotal) { // 放入右边 style = `right:${ marginPx }px;top:${ rightTotal }px;`; rightTotal += height; } else { // 放入左边 style = `left:${ marginPx }px;top:${ leftTotal }px;`; leftTotal += height; } const { list = [] } = this.data; const targetKey = `list[${list.length}]`; // 利用直接操作数组下标的方式来触发数组修改,性能有很大提升 this.height = [leftTotal, rightTotal]; // 记录最新的左右侧高度 return this.$setData({ [targetKey]: { data: item, style, }, height: Math.max(leftTotal, rightTotal), }); }); }, // 实际添加元素使用,自建Promise队列,保证顺序一致 add(item) { let pending = this.pending || Promise.resolve(); return this.pending = pending.then(() => { return this.addItem(item); }).catch(err => { console.error(err); this.pending = null; throw err; }); }, clear() { this.tick = tick++; this.height = [0, 0]; this.pending = null; this.setData({ list: [], height: 0, }); }, }
在使用该组件的时候我们就不能直接通过赋值数组的方式来渲染元素了,而是得通过组件实例方法add(item)
wrapper
Der Container ist ein absolut positioniertes Wrapper-Element. Die Komponenten, die tatsächlich gerendert werden müssen, müssen im wrapper
-Container platziert werden, um flexibler zu sein. Ich habe diese Rendering-Komponente festgelegt. Es ist zu einem virtuellen Knoten geworden, und Sie können die benutzerdefinierte Komponente angeben, die tatsächlich gerendert wird, wenn Sie die Komponente verwenden. Da das wrapper
-Element absolut positioniert ist, müssen wir die Höhe des gesamten container
-Containers manuell beibehalten. Die Frage hier ist, wie wir die Höhe des Elements im Inneren ermitteln? computed-zone
in der Vorlage soll dieses Problem lösen, bevor wir die Elemente im Array platzieren. Zuerst rendern wir die Elemente in computed-zone
und verwenden dann die WXML-API, um sie abzurufen die tatsächliche gerenderte Größe des Elements, sodass wir die tatsächlich gerenderte Breite und Höhe dieses Elements kennen können. Nachdem wir die Informationen zur Rendering-Größe jedes Elements erhalten haben, müssen wir bestätigen, ob das Element die gesamte Zeile oder die Hälfte davon einnimmt:
wrapper
auf die Breite einer ganzen Zeile einstellen ; li>
wrapper
links oder rechts platzieren, basierend auf der Gesamthöhe des linken und rechten Elements.
wrapper
zu berechnen und zu entscheiden, ob er links oder rechts platziert werden soll sollte die gesamte Zeile einnehmen. Der Kerncode ist wie folgt implementiert: rrreeeBei Verwendung dieser Komponente können wir Elemente nicht direkt durch Zuweisung von Arrays rendern, sondern müssen die Komponenteninstanzmethode add(item)
verwenden. Da ich eine Warteschlange implementiert habe, kann ich das Hinzufügen direkt in einer Schleife durchführen. Wenn Ihnen der Status wichtig ist, stellen Sie einfach fest, ob der Hinzufügungsvorgang des letzten Elements abgeschlossen ist. 🎜🎜Die auf diese Weise erzielte Flexibilität des Wasserfallflusses ist relativ hoch, der Leistungsverbrauch ist jedoch nicht gering. Sie müssen die tatsächliche Rendergröße der Elemente einzeln ermitteln, wenn Sie die Größenänderung des Fensters unterstützen möchten. Der Verbrauch ist schrecklich. 🎜🎜Für Schüler, die die Details des Codes sehen müssen, habe ich die eigentliche Demo auf 🎜Github🎜 und 🎜WeChat-Codeschnipsel🎜 eingestellt. Schüler in Not können es ausprobieren. 🎜🎜Basierend auf dem oben genannten Modell kann es tatsächlich so optimiert werden, dass nur Elemente innerhalb des sichtbaren Bereichs gerendert werden, was die Leistung des Wasserfallflusses erheblich verbessern kann. Ich hoffe, dass Schüler, die Zeit haben, es verbessern können o( ̄▽ ̄ )d🎜🎜Weitere Kenntnisse zum Thema Programmierung finden Sie unter: 🎜Programmiervideo🎜! ! 🎜Das obige ist der detaillierte Inhalt vonLassen Sie uns darüber sprechen, wie Sie eine abgeschnittene Wasserfall-Flow-Komponente in einem kleinen Programm implementieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!