>  기사  >  위챗 애플릿  >  작은 프로그램에서 잘린 폭포수 흐름 구성 요소를 구현하는 방법에 대해 이야기해 보겠습니다.

작은 프로그램에서 잘린 폭포수 흐름 구성 요소를 구현하는 방법에 대해 이야기해 보겠습니다.

青灯夜游
青灯夜游앞으로
2022-01-24 10:32:312607검색

미니 프로그램에서 잘린 폭포 흐름 구성 요소를 구현하는 방법은 무엇입니까? 다음 글에서는 워터폴 흐름 구성 요소를 차단할 수 있는 WeChat 애플릿을 구현하는 방법을 소개하겠습니다. 도움이 되길 바랍니다.

작은 프로그램에서 잘린 폭포수 흐름 구성 요소를 구현하는 방법에 대해 이야기해 보겠습니다.

폭포 흐름을 구현하는 방법에는 여러 가지가 있습니다. 예를 들어 직접 두 개의 열로 나눈 다음 왼쪽과 오른쪽 열의 요소 추가를 제어하는 ​​또 다른 방법은 두 가지를 모두 배치하는 것입니다. 절대 위치 지정을 통해 측면. [관련 학습 추천 : 미니 프로그램 개발 튜토리얼]

이 글에서 소개할 워터폴 흐름은 기존의 워터폴 흐름과 다릅니다. 왜냐하면 워터폴 흐름이 중간에 잘릴 수 있기 때문입니다:

작은 프로그램에서 잘린 폭포수 흐름 구성 요소를 구현하는 방법에 대해 이야기해 보겠습니다.

위 레이아웃의 경우 , 강제로 두 개의 열로 나누어야 하는 경우 레이아웃에 적합하지 않아 레이아웃에 절대 위치 지정을 사용했습니다. 폭포 흐름의 요소 높이가 고정되어 있지 않기 때문에 높이를 구할 수 있는 방법을 찾아야 합니다. 각 요소의 높이를 결정한 다음 왼쪽이나 오른쪽에 전체 행을 배치합니다.

먼저 템플릿 부분의 구현을 살펴보겠습니다.

<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>

템플릿은 상대적으로 간단하며 컨테이너 컨테이너입니다. 그런 다음 배열을 반복하고 여러 를 렌더링합니다. 래퍼 컨테이너를 평평하게 만듭니다. 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(&#39;.computed-zone .wrapper&#39;).boundingClientRect();
				query.exec(ret => {
					if (ret[0]) {
						resolve(ret[0]);
					} else {
						reject(&#39;not found dom!&#39;);
					}
				});
			});
		});
	},
	// 添加元素,内部使用
	addItem(item) {
		let tick = this.tick;
		return this.getRect(item).then(rect => {
			if (tick !== this.tick) {
				return Promise.reject(&#39;tick&#39;);
			}
			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 = &#39;&#39;;

			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 컨테이너는 절대적으로 배치된 래핑 요소입니다. 실제로 렌더링해야 하는 구성 요소는 보다 유연하게 배치되어야 합니다. 이 렌더링 컴포넌트를 설정했는데 가상 노드가 되었고, 해당 컴포넌트를 사용할 때 실제로 렌더링되는 커스텀 컴포넌트를 지정할 수 있습니다.

wrapper 요소는 절대 위치에 있으므로 전체 container 컨테이너의 높이를 수동으로 유지해야 합니다.

여기서 질문은 내부 요소의 높이를 어떻게 구하느냐는 것입니다. 템플릿의 computed-zone은 이 문제를 해결하기 위해 사용되었습니다. 요소를 배열에 배치하기 전에 먼저 computed-zone의 요소를 렌더링한 다음 WXML API를 사용합니다. 요소의 실제 렌더링 크기를 가져오면 이 요소의 실제 렌더링된 너비와 높이를 알 수 있습니다. 각 요소의 렌더링 크기 정보를 얻은 후 요소가 전체 행을 차지하는지 아니면 절반을 차지하는지 확인해야 합니다.

  • 요소 렌더링 너비가 컨테이너와 동일하면 이 요소가 전체 줄을 채운다고 판단할 수 있으며 래핑 컨테이너 wrapper를 전체 줄의 너비로 설정해야 합니다

    li>

  • 그렇지 않은 경우 조건 1이 충족되면 왼쪽 요소와 오른쪽 요소의 전체 높이를 기준으로 wrapper를 왼쪽 또는 오른쪽에 배치해야 합니다.

분석 후 조금 작성해야 할 것은 wrapper의 오프셋을 계산하여 왼쪽에 놓을지 오른쪽에 넣을지 또는 넣을지 결정하는 것입니다. 핵심 코드는 다음과 같이 구현됩니다. rrreee이 컴포넌트를 사용할 때 배열을 할당하여 요소를 직접 렌더링할 수는 없지만, 컴포넌트 인스턴스 메소드 add(item)를 사용해야 합니다. 대기열을 구현했기 때문에 추가를 직접 반복할 수 있습니다. 상태에 관심이 있다면 마지막 요소의 추가 작업이 완료되었는지 확인하면 됩니다. 🎜🎜이런 방식으로 달성된 폭포 흐름의 유연성은 상대적으로 높지만 성능 소모는 낮지 않습니다. 창 크기 조정을 지원하려면 요소의 실제 렌더링 크기를 하나씩 가져와야 합니다. 소비가 끔찍해요. 🎜🎜코드의 세부 사항을 확인해야 하는 학생들을 위해 🎜Github🎜 및 🎜WeChat 코드 스니펫🎜에 실제 데모를 올려두었습니다. 🎜🎜위 모델을 기반으로 실제로 가시 영역 내의 요소만 렌더링하도록 최적화할 수 있으므로 폭포 흐름의 성능을 크게 향상시킬 수 있습니다. 시간이 있는 학생들이 개선해 볼 수 있기를 바랍니다~ o( ̄▽ ̄ )d🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 비디오🎜를 방문하세요! ! 🎜

위 내용은 작은 프로그램에서 잘린 폭포수 흐름 구성 요소를 구현하는 방법에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제