前言
近期闲来无事,想着闲着也是闲着,不如给自己搞点事情做!敢想敢做,于是选择了给微信小程序做个 仿iPhone通讯录 效果的自定义组件。
先来整理一下,瞧瞧需要实现的核心功能。
- 按照第一个字的首字母排序;
- 实现输入搜索功能;
- 侧边栏字母导航;
基本上分为3块:
- 顶部的搜索区域;
- 内容的展示区域;
- 侧边字母导航栏区域;
// index.wxml <view class="main"> <!-- 顶部搜索区域 --> <view class="header"> </view> <!-- 内容区域 --> <scroll-view class="scroll"> </scroll-view> <!-- 侧边导航 --> <view class="sub_nav"> </view> </view>
【顶部的搜索区域】
一目了然就直接贴代码了。
<view class="header"> // 这里或许有人要问,为啥不用小程序的label组件呢。"label"> <icon></icon> <input type="text" placeholder="搜索" /> </view> </view>
【内容的展示区域】
再说一目了然会不会被打呢?:joy:
根据图片就可以看出来,存在2个区域。
- 红框包围的外框,负责圈定展示的范围;
- 绿框包围的范围,包含有字母标题和对应的子项。
代码如下:
<scroll-view class="scroll"> <view class="dl"> <view class="dt">这里是字母标题。</view> <view class="dd"> <span>这里当然是展示的内容啦。</span> </view> </view> </scroll-view>
【侧边字母导航栏区域】
为了节省一下文章的篇幅,这里就不贴图了,很简单,就是并排下来就好了。
<view class="sub_nav"> <view class="option">这里是输出字母。</view> </view>
接下来是wxss的样式了。
考虑到wxss的样式较多,我就直接贴 代码链接 吧,有兴趣的童鞋可以瞧瞧。
完成之后,是时候贴个效果图了。(不许吐槽丑,宝宝会不开心的!:pensive:)
结构样式弄完了,也贴一下自定组件的基础文件
// index.json
{
"component": true
}
// index.js
Component({
properties: {}, // 组件的对外属性
data: {}, // 组件的内部数据
lifetimes: {}, // 生命周期
methods: {} // 事件
});
现在开始实现功能了!!!
按照第一个字的首字母排序
说实话,实现这块功能呢,我是没啥头绪的,所以这个时候就要求助伟大的“度娘/Google”了。
经过楼主“遍寻网络”,查找到如下页面的源码参考:
因楼主问题,遗忘了该网址,如有知道的童鞋,贴个链接告诉下楼主,楼主立马麻溜的加上。 源码的原理大概描述下:
收录 20902 个汉字和 375 个多音字的 Unicode 编码,然后用JS切割首字母并转换成 Unicode 进行对比,最后返回对应首字母的拼音。
// 汉字对应的Unicode编码文件
// oMultiDiff = 多音字 | firstLetterMap = 汉字
import firstStore from './firstChineseLetter';
// 获取首字母拼音
function getFirstLetter (val) {
const firstVal = val.charAt(0);
if (/.*[\u4e00-\u9fa5]+.*/.test(firstVal)) {
// 处理中文字符
// 转换成Unicode编码,与firstStore里面的数据进行对比,然后返回对应的参数
const code = firstVal.charCodeAt(0); // 转换成Unicode编码
return code in firstStore.oMultiDiff "_blank" href="https://github.com/nobitas/select-view/blob/master/src/firstChineseLetter.js">firstChineseLetter.js地址
获取首字母的方法有了之后,就该对数据进行处理了。
首先定义一下组件所需要的参数。
Component({
// 组件的对外属性
properties: {
data: { type: Array, value: [], }, // 组件外传递进来的数据
attr: { type: String, value: 'label' }, // 需要进行首字母处理的属性,默认是"label"
},
...
})
然后,针对组件外传递进来的数据,做一次转换。
// 静态数据的存储
const Static = {
list: []
}
Component({
...
methods: {
// 初始/重置数据
init () {
const { data, attr } = this.properties;
let changeData = [], // 转换后的数据
inChangeData = {}; // 存储转换后的数据对应字母的索引值
data.map(v => {
// 获取首字母拼音
let firstLetter = this.getFirstLetter(v[attr]);
// 循环对比检测
firstLetter.split('').map(str => {
if (str in inChangeData) {
// 有首字母相同的项,
// 则添加入已有的项里面
changeData[inChangeData[str]].list.push(v);
} else {
// 没有首字母相同的项,
// 则在尾部追加一条新的数据,
// 储存对应的字母值(firstLetter),
// 同时存储该字母对应的索引
changeData.push({ firstLetter: str, list: [v] });
inChangeData[str] = changeData.length - 1;
}
});
});
// 此时转换后的数组属于乱序,
// 需要对乱序的数组进行排序
changeData.sort((pre, next) => pre.firstLetter < next.firstLetter "htmlcode">
Component({
lifetimes: {
// 在组件实例进入页面节点树时执行初始化数据
attached () {
this.init();
}
},
observers: {
// 考虑到组件传递的数据存在变更的可能,
// 在数据变更的时候,也要做一次初始化
'data, attr, icon' (data, attr) {
this.init();
}
},
})
接下来是搜索功能啦~
先给页面搜索框加个监听事件(input)
<view class="main">
...
<view class="header">
<view class="label">
<icon></icon>
<input type="text" placeholder="搜索" value="{{ search }}" bindinput="searchData" />
</view>
</view>
...
</view>
接着是JS的事件
const Static = {
list: []
}
Component({
...
methods: {
searchData (e) {
const { value } = e.detail; // 用户输入的值
const { list } = Static; // init存储的静态数据,用来做数据对比
const { attr } = this.properties; // 要对比的属性值
let result = [], tem = {};
// 没有搜索内容,返回全部内容
if (value.length === 0) { this.setData({ list: Static.list }); return; }
// 检索搜索内容
list.map(v => {
// 获取所有跟value匹配上的数据
const searchList = v.list.filter(v => v[attr].indexOf(value) !== -1);
if (searchList.length > 0) {
// 此处原理类似楼上init的对比,此处不细说,
// 反正我懒我有理(0.0)
if (v.firstLetter in tem) {
const _list = result[tem[v.firstLetter]].lish;
result[tem[v.firstLetter]].lish = [..._list, ...searchList];
} else {
result.push({ firstLetter: v.firstLetter, list: [...searchList] });
tem[v.firstLetter] = result.length - 1;
}
}
});
// 存储数据
this.setData({ list: result, search: value });
}
},
...
});
侧边栏字母导航
(突然觉得,写文好累啊!!!)
写这块的时候呢,楼主发现了iPhone通讯录侧边导航栏有个问题, 手指在字母导航栏上滑动的时候,有时候很难确认自己滑到了哪个区域?!
然鹅这个问题呢,楼主发现了微信的通讯录,针对这块添加了手指滑动的时候,添加了个结构来帮助用户确认目前所处的区域。
楼主本着学习的精神,借(chao)鉴(xi)了这个效果,来个效果图。
贴一下新的wxml结构
<!-- 侧边导航 -->
<view class="sub_nav" id="subNav" catchtouchstart="subTouchStart" catchtouchmove="subTouchMove" catchtouchend="subTouchEnd">
<view class="option" wx:for="{{ list }}" data-firstLetter="{{ item.firstLetter }}" wx:key="firstLetter">
{{ item.firstLetter }}
<!-- 以下这块就是新增的结构啦 S -->
<view
class="max {{ item.firstLetter === scrollIntoView && subNavHint "
data-desc="{{ item.firstLetter }}"
></view>
<!-- 以上这块就是新增的结构啦 E -->
</view>
</view>
const Static = {
list: [],
timer: null
}
Component({
...
data: {
scrollIntoView: '', // 标记当前处于哪个字母
subNavHint: false, // 控制借(chao)鉴(xi)微信效果的元素
},
methods: {
subTouchStart () {
this.setData({ subNavHint: true, scrollIntoView: '' });
},
subTouchEnd () {
this.setData({ subNavHint: false });
},
subTouchMove (e) {
// 获取字母导航栏元素对应的值
const query = this.createSelectorQuery();
query.select('#subNav').boundingClientRect();
query.selectViewport().scrollOffset();
query.exec(res => {
const { clientY } = e.touches[0]; // Y轴的位置
const DomTop = res[0].top; // 导航元素距离顶部的位置
const { list } = this.data;
// 计算索引,
// 或许看到这里有人会疑问,为什么是除以20?
// 因为样式里面,我写的高度是20px,所以每个字母的区域是20px。
let index = Math.round((clientY - DomTop) / 20);
index = index >= list.length "color: #ff0000">结语
文章写到这呢,基本上核心的功能都已经实现啦~ :stuck_out_tongue_closed_eyes:(终于写完了...)
通过自己封装组件,楼主还是有挺大收获的!
当然,这个组件还有很多可以继续完善的地方,有兴趣的童鞋呢,可以提出你的优化建议,楼主有时(xing)间(qu)的话,会继续完善下去。
最后,还是推一下这个组件啦,希望它能帮到有需要的童鞋。
github地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
标签:
小程序通讯录,小程序通讯录选择
蝙蝠岛资源网 Design By www.hbtsch.com
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]






