电商小程序 留住用户秘诀
发布于 1 年前 作者 fangzhao 3310 次浏览 来自 分享

你是否也收到这样的用户反馈?

  • 商品列表滚动区域太小,很难找到想要的商品。
  • 头部的搜索广告占据了半个屏幕,挤占了实际空间。
  • 在我手机这样小的屏幕上,展示区域太小了,能否把它放大点?

在电商页面中,我们需要向用户展示众多的商品、广告等信息。

然而,如何在有限的屏幕空间中更好地展示它们,是一个需要我们深入思考的问题。


由于小程序 webview 渲染框架在技术存在一定的局限性,我们需要在不同的设计之间进行抉择。

  • 当广告具有较高的优先级时,我们会考虑突出广告的展示,同时减小商品列表在界面中所占比例。
  • 当商品列表具有较高的优先级时,我们会考虑优先展示商品,而放弃广告的展示。

但是当广告和商品列表同样重要的情况下,要怎么办呢?

常见的一种设计方式是设计一个隐藏按钮,当用户不想看广告的时候把广告隐藏掉,隐藏之后商品列表就有更多展示空间

但是这种情况也只是针对愿意手动点击隐藏按钮的情况下,还是有一定的局限性。

那么,有没有办法做到在无形中隐藏广告呢?

说到这里,当然是可以的啦✌️

1、吸顶布局 + worklet 轻松实现

在常见的电商小程序首页,通常是顶部展示类目、接着展示商品详情,商品详情顶部也有热门等等的分类。

当页面滚动的时候,我们希望商品详情热门分类可以吸在顶部,便于切换。

这里我们用到了 scroll-view 的 sticky-header、sticky-section 吸顶布局容器即可轻松实现。

<scroll-view
 type="custom"
 scroll-y
 show-scrollbar="{{false}}"
 worklet:onstartstart="handleScrollStart"
 worklet:onscrollupdate="handleScrollUpdate"
 worklet:onscrollend="handleScrollEnd"
>
	<sticky-section push-pinned-header="{{false}}">
		<sticky-header>
			<!-- 搜索框 -->
			...
		</sticky-header>
		<!-- 类目展示 -->
	</sticky-section>

	<sticky-section push-pinned-header="{{false}}" padding="{{[0, 16, 0, 16]}}">
		<sticky-header>
			<!-- 商品详情热门分类 -->
			...
		</sticky-header>
		<grid-view cross-axis-count="2" type="masonry">
			<!-- 两列的瀑布流 -->
			...
		</grid-view>
	</sticky-section>
</scroll-view>


当 scroll-view 滚动的时候,根据滚动位置把搜索框放到标题的位置,可以再节省一点空间

attached() {
	// nav-bar 隐藏或展示
	this.applyAnimatedStyle('.nav-bar', () => {
	'worklet'
	return {
		opacity: this.navBarOpactiy.value
	}
	})

	// 改变搜索框宽度
	this.applyAnimatedStyle('.search', () => {
	'worklet'
	return {
		width: `${this.searchBarWidth.value}%`,
	}
	})
},

// scroll-view 监听函数
handleScrollUpdate(evt) {
	'worklet'
	const maxDistance = 60
	const scrollTop = clamp(evt.detail.scrollTop, 0, maxDistance)
	const progress = scrollTop / maxDistance
	const EasingFn = Easing.cubicBezier(0.4, 0.0, 0.2, 1.0)
	this.searchBarWidth.value = lerp(100, 70, EasingFn(progress))
	this.navBarOpactiy.value = lerp(1, 0, progress)
},


2、手势 + worklet 操作更灵活

小程序新渲染框架支持了手势系统,手势在这里可以发挥大作用~

我们可以使用手势协商让小程序页面中的广告、商品等无缝切换和更好的展示

// .wxml
<pan-gesture-handler
	tag="pan"
	simultaneousHandlers="{{['scroll-view']}}"
	shouldResponseOnMove="shouldPanResponse"
	onGestureEvent="handlePan"
>
	<view class="page">
		<vertical-drag-gesture-handler
			tag="scroll-view"
			native-view="scroll-view"
			simultaneousHandlers="{{['pan']}}"
			shouldResponseOnMove="shouldScrollViewResponse"
        >
          	<scroll-view
				class="product-list"
				type="custom"
				scroll-y
				show-scrollbar="{{false}}"
				adjustDecelerationVelocity="adjustDeceleration"
				bindscroll="handleScroll"
			>
			...
			</scroll-view>
        </vertical-drag-gesture-handler>
	</view>
</pan-gesture-handler>

// .js
handlePan(e) {
      'worklet'
      ...

      if (e.state === GestureState.ACTIVE) {
        if (this._interactionState.value === InteractionState.UNFOLD) {
          // 展开状态下,往上滑才折叠起来
          if (e.absoluteY - this._startY.value < 0) {
            this._interactionState.value = InteractionState.ANIMATING
            this._translY.value = timing(0.0, { duration: 250 }, () => {
              'worklet'
              this._interactionState.value = InteractionState.RESET
            })
          }
        } else {
          // 其它情况,跟随手指滑动
          this._translY.value = e.absoluteY - this._startY.value
        }
      }

      // 其他状态下的处理
	  ...
},


加入手势之后,除了可以隐藏广告,我们还可以将一些头部信息隐藏

在用户查看商品列表时,隐藏大部分无用信息,将商品列表展示区域最大化

// 最外层 .page 往上挪
this.applyAnimatedStyle('.page', () => {
	'worklet'
	const translY = clamp(this._translY.value, -this._tabsTop.value, 0)
	return {
		transform: `translateY(${translY}px)`
	}
})

// 改变 .navigation-bar 背景色
this.applyAnimatedStyle('.navigation-bar', () => {
	'worklet'
	const translY = clamp(this._translY.value, -this._tabsTop.value, 0)
	const opacity = translY / -this._tabsTop.value
	return {
		backgroundColor: `rgba(255, 255, 255, ${opacity})`
	}
})
	
// 输入框:改变宽度并且展示
this.applyAnimatedStyle('.search-input', () => {
	'worklet'
	const translY = clamp(this._translY.value, -this._tabsTop.value, 0)
	const percentage = translY / -this._tabsTop.value
	return {
		width: `${percentage * 60 + 40}%`,
		opacity: percentage,
	}
})


除此之外,我们这里可以利用手势来展示商家的一些信息

当在商品列表往下拉到顶部时,触发整个列表下拉展示出商家信息

再往上滑动则商品列表重新展示~

// 商品详情往下拉
this.applyAnimatedStyle('.main', () => {
	'worklet'
	const translY = clamp(this._translY.value, 0, Number.MAX_VALUE)
	console.log(222, translY)
	return {
		transform: `translateY(${translY}px)`
	}
})

// 简单的 header 渐隐
// 商品详情展示时,仅显示简单的 header:学堂名称和几个标签
this.applyAnimatedStyle('.header-shop-info-simple', () => {
	'worklet'
	const min = 50
	const max = 100
	const translY = clamp(this._translY.value, min, max) - min
	return {
		opacity: 1 - (translY / (max - min))
	}
})

// 复杂的 header 渐显
// 商品详情下拉,显示复杂 header:展示热门活动、公告等等信息
this.applyAnimatedStyle('.header-shop-info-detail', () => {
	'worklet'
	const min = 100
	const max = 150
	const translY = clamp(this._translY.value, min, max) - min
	return {
		opacity: translY / (max - min)
	}
})


加入手势动画之后,我们的页面展示对比之前有了以下的优势:

  • 更加自然:更符合用户操作习惯,用户自然滚动屏幕时不会感到突兀
  • 更节省空间:滚动隐藏更为灵活、省空间,使页面更清爽
  • 更高效的展示:可以将要展示的内容更好的展示,无需做取舍


借助手势动画,我们可以优化小程序界面展示、提升用户体验,从而获得更高的商业价值。


如果你也想更好的留住用户,mark 下这个 源码 [ 瀑布流页面 / 分类页面 ] 直接接到到你的小程序吧~

4 回复

超赞的,源码 mark 下来!

吸顶这个功能,也适用多条件搜索,顶部搜索条件占用太多区域的问题

回到顶部