国内b2b网站有哪些/湖北搜索引擎优化
概述
最近在开发小程序的过程中,有一个需求是左滑删除的功能,我用的是vant-weapp组件库 + 原生小程序开发的模式,心想直接使用vant-weapp中的SwipeCell组件就好啦,一顿开撸,结果在真机上的效果并不理想,特别卡顿,惨不忍睹。在网上搜索了解决方案,有用scroll-view实现的,也有用movable-view(可移动的视图容器)实现的。综合考虑了一下,我决定使用movable-view来实现。但是movable-view也有诸多坑,比如你必须要预先定义好movable-view的尺寸,这个对于组件封装来说那肯定是有缺陷的,因为你无法确定你的使用场景是否水平铺满屏幕,更不能确定视图的高度,理论上应该是动态计算。在网上搜索了半天,没有任何一个合适的解决方案,微信社区论坛里面提出的相关问题,官方没有一个正确的回复(这里不得不吐槽一下微信社区论坛的确是不活跃,官方也不靠谱)。不过最终在自己不停的尝试之下缺陷得以解决。
效果
先给大家展示一下最终的效果,当然还有一些缺陷,比如滑动不到一半松手自动回弹效果,这个功能就留给大家自行拓展吧。

「movable-view 参考」:https://developers.weixin.qq.com/miniprogram/dev/component/movable-view.html
问题
「1. 如何设置movable-view尺寸?」
这个问题是困扰我最久的地方,为了方便使用,我准备封装一个slide-cell组件,该组件的根节点是 movable-area(官方提示:movable-view必须在 movable-area 组件中,并且必须是直接子节点,否则不能移动)。开发完以后发现子组件并不能撑起movable-area的高度,后来细看官方文档,才看到movable-view 必须设置width和height属性,不设置默认为10px。我心想,我们可以参照设计图的尺寸,通过properties传递并设置是不是就可以了呢?然而现实是并没什么作用,翻阅了大量的文档,没有一个说到重点,在不断的尝试之下,发现如果数据定义在data里面,是可以设置的。所以我的处理方式是,调用组件时通过properties传递尺寸,然后在attached生命周期函数里将properties的值再赋值给data进行设置就搞定了(有的时候我真的佩服我自己,^_^)。
「2. 如何处理删除?」
通常我们会在列表中使用slide-cell组件,那就意味着会用到列表渲染,我们可以将遍历出来的index传递给slide-cell组件,然后当用户点击删除按钮时,再将这个index传给监听者即可。
onDelete() {
this.triggerEvent('delete', { index: this.properties.index })
}
「3. 你真的会使用 wx:key
么?」
我发现一个问题,很多小伙伴在列表渲染中使用 wx:key
的时候并没有正确设置,他们大多是这样设置的:
<slide-cell wx:for="{{list}}" wx:key="index">
...
slide-cell>
然后在处理删除的时候会发现删除的节点被复用渲染了,因为 key 永远是 index 指向的 undefined 值。这里大家肯定会很诧异,为什么是undefined?这是因为 key 的值是一个字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。这样一解释是不是就很清晰了,显然我们的list的item中没有index这个字段,所以全部指向了undefined,或者说他们的key都是一样的值,所以被复用渲染了呀。
实现
代码里面我给出了详细的注释,有任何不懂的地方可留言。
「1. 创建slide-cell组件」
「2. 脚本部分」
Component({
properties: {
// 标识删除位置的下标
index: {
type: Number,
},
// 距离屏幕左右两侧的间距/默认0rpx
spacing: {
type: Number,
value: 0
},
// 容器高度/默认200rpx
height: {
type: Number,
value: 200
},
// 删除按钮宽度/默认158rpx
rightWidth: {
type: Number,
value: 158,
}
},
data: {
rW: 0, // 接收删除按钮宽度
kH: 0, // 接收容器高度
kSpacing: '' // 接收左右两侧的间距
},
lifetimes: {
attached() {
// 获取属性并设置data值
const { rightWidth, height, spacing } = this.properties;
this.setData({
rW: rightWidth,
kH: height,
// 因为在wxml模板中通过calc计算的时候会被转换成px,
// 所以这里我先直接计算左右两边间距所占的宽度
// 便于在wxml中通过calc(100% - kSpacing)的形式来计算宽度
kSpacing: spacing * 2 + 'rpx'
});
}
},
methods: {
// 处理删除操作
onDelete() {
// 将index参数发送给delete事件监听者
// 用于判断删除数据所对应的下标
this.triggerEvent('delete', { index: this.properties.index })
}
}
});
「3. 视图部分」
<movable-area class="slide-cell__wrapper" style="height: {{kH}}rpx; width: calc(100% - {{kSpacing}})">
<movable-view class="slide-cell__scroll" direction="horizontal" inertia="true" out-of-bounds="true" style="width: calc(100% + {{rW}}rpx)">
<view class="slide-cell__contents" style="width: calc(100% - {{rW}}rpx)">
<slot />
view>
<view class="slide-cell__delete" style="width: {{rW}}rpx" bind:tap="onDelete">
删除
view>
movable-view>
movable-area>
「4. 样式部分」
.slide-cell__wrapper {
overflow: hidden;
margin: 0 auto 20rpx;
}
.slide-cell__scroll {
height: 100%;
display: flex;
}
.slide-cell__contents {
height: 100%;
}
.slide-cell__delete {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #FF2626;
color: #FFFFFF;
border-radius: 24rpx;
}
调用
「1. 引入组件」
"usingComponents": {
"list": "../../components/list/list",
"guide-item": "../../components/guide-item/guide-item",
"slide-cell": "../../components/slide-cell/slide-cell"
}
「2. 调用组件」
<list bind:load="onLoadMore" height="{{listHeight}}px">
<slide-cell wx:for="{{list}}" wx:key="id" height="{{200}}" spacing="{{20}}" index="{{index}}" bind:delete="onDelete">
<guide-item data="{{item}}" />
slide-cell>
list>
「3. 处理删除逻辑」
onDelete(e) {
const index = e.detail.index;
const catList = this.data.catList;
catList.splice(index, 1);
this.setData({
catList
})
}
❝上面用到的
❞list
组件和guide-item
组件为开发中封装的业务组件。