vue项目通讯录_vue组件--通讯录
简介
在移动端开发中,通讯录是个很常见的需求。
通讯录通常要实现以下功能
首字母导航
滚动到一定位置首字母固定
布局
通讯录是典型的上下两栏布局,上面是header,下面是内容区,我们这里采用flexbox来实现。
html,body,.page{height: 100%}
.page{display: flex}
.page-header{height: 44px}
.page-content{
flex: 1;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.navs {
z-index: 2;
position: fixed;
right: 10px;
top: 50px;
bottom: 30px;
text-align: center;
color: #5d9ed3;
font-size: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
span {
cursor: pointer;
}
}
OK。上面的代码已经足够定义一个页面的雏形,
page-header 高度44,
page-content 占据剩余的全局的高度,并做内部的滚动。-webkit-overflow-scrolling: touch 会在容器里面开启高性能滚动。
设置导航
页面布局完成之后,可以初始化导航条了,为了方便起见,我们默认通讯录里面包含了从A到Z的全部姓名。
文章默认使用 vue单文件组 件开发,如果您使用其他框架,请自行转换代码
{{item}}
data () {
return {
navs: "abcdefghijklmnopqrstuvwxyz".split("").map(i => i.toUpperCase());
}
}
建立索引
建立索引实际上是用js操作dom,获取通讯录内容区域内每个首字母出现的位置并存储起来,方便做跳转和滚动监听。
moutend() {
// 因为要获取dom属性,所以要在组件render后执行
this.$nextTick(()=>{
this.body = this.$refs.content;
const navsEles = [...this.$refs.navs.querySelectorAll("span")]
const itemsEles = [...this.$refs.items.querySelectorAll(".item")]
// 获取导航栏字母的高度信息,方便做点击放大功能
this.navsOffset = navsEles.map(item=>{
return item.offsetTop || 0
})
// 获取通讯录内容区的首字母位置,方便做跳转和滚动监听
this.itemsOffset = itemsEles.map(item=>{
return item.offsetTop || 0
})
})
},
data () {
return {
body: null,
itemsOffset: [],
navsOffset: []
}
}
监听跳转
监听跳转比较简单,在 .page-navs span 标签上绑定click事件即可处理
{{item}}
methods: {
jump(index) {
// 因为offsetTop属性是相对整个视口,而scrollTop是相对滚动容器,所以需要减去44px(header的高度)
const offset = this.itemsOffset[index] - 44;
this.body.scrollTop = offset;
}
},
data () {
return {
navs: "abcdefghijklmnopqrstuvwxyz".split("").map(i => i.toUpperCase());
}
}
监听滚动
因为是在page-content元素内部滚动,所以可以通过在该元素上绑定scroll方法监听页面的滚动。局部滚动的好处是组件销毁时事件监听也移除了,不像监听body的滚动还需要在销毁前手动removeEventListenr。
在执行滚动监听之前,我们还需要做两件事情
对 itemsOffset 进行分组,划定监听的区间
在页面顶部创建一个展示 当前联系人首字母 的组件
// 当前联系人首字母组件
// 在这个组件里面也创建一个列表,用来做滚动的动画
// 对 `itemsOffset` 进行分组,划定监听的区间
mounted() {
this.$nextTick(() => {
let offsetCalc = this.offset.slice();
offsetCalc.forEach((item, index) => {
this.offsetList.push([item, offsetCalc[index + 1]]);
});
});
}
data() {
return {
currentIndex: -1,
offsetList: []
}
}
在准备工作做好之后,就开始监听容器的滚动行为,当滚动到通讯录之中的首字母部分时, 联系人首字母组件 也会自动滚动到里面相应的字母位置。
点击右侧导航,也会触发滚动事件。
// html模板部分
// js部分
methods: {
scroll() {
this.currentIndex = this.getArea(this.body.scrollTop);
},
getArea(scrollTop) {
// 80是首字母标组件的高度+通讯录首字母的高度
scrollTop += 80;
let index = -1;
for (let i = 0, size = this.offsetList.length; i < size; i++) {
let [start, end] = this.offsetList[i];
if (scrollTop >= start && scrollTop < (end || 999999)) {
index = i;
break;
}
}
return index
},
}
更多
点击右侧导航,有时候还要求在附近显示一个放大的字母,用于提醒点击了那个字母,通过前面获取的 navsOffset ,可以很方便的实现这个需求。至此,整个通讯录功能就基本完成了。
vue项目通讯录_vue组件--通讯录相关推荐
- vue 项目难点_Vue 项目里戳中你痛点的问题及解决办法
一.先总结出如下几点vue项目开发中常见的问题及解决办法. 列表进入详情页的传参问题. 本地开发环境请求服务器接口跨域的问题 API接口的统一管理 UI库的按需加载 定时器问题 rem文件的导入问题 ...
- vue 项目总结一组件开发的配置和例子
原文地址:https://segmentfault.com/a/1190000012410259?_ea=2993723 先上 src 文件夹的结构图: 文件及文件夹作用 App.vue App.vu ...
- vue项目引入vux组件
搭建好vue项目后,这边主要做的手机端,综合比较后决定引入vux组件 1.安装vux npm install vux --save 或者使用 yarn yarn add vux // 安装 yarn ...
- vue项目 - 封装loding组件
一.需求问题 在vue项目中,当在页面内容进行加载的时候,会进行请求数据,然后显示页面.在这个等待的过程中,会出现一段时间的白屏,我们可以通过加一个loading的效果,进行过渡,然后显示页面. &l ...
- Vue项目中components组件的使用笔记
目录 前言 一.components和component的区别? 二.components使用的步骤 1.创建组件vue文件 2.引入组件 3.注册组件 4.应用组件 总结 前言 本文章,只是初步了解 ...
- Vue项目中使用组件库cube-ui
(一)创建一个vue项目 (1) (安装全局vue-cli,通过vue -V查看版本) npm install -g vue-cli (2)vue init 你用的模板工具 项目名称 (这里采用web ...
- vue项目调用通用组件_详细解析:uniapp项目|vue组件形式实现的科技感loading纯CSS动效...
前言 本人是一枚并不安分守己的后端程序猿,一直对前端开发"垂涎三尺",所以,一有机会就会"不务正业"一番.最近,发现了一个非常好的学习资料,于是乎,我的老毛病又 ...
- vue 项目, 父组件中每次点击按钮重新加载子组件,(重新生成dom 元素)
vue是组件化开发的项目,很多情况下会把公共组件提取出来,来减少代码量,提高开发效率,和以后更好的可维护性.很多情况下,父组件中都会引用子组件这种情况.通过给在父组件中引用的子组件标签上添加属性,来渲 ...
- vue变量传值_vue组件与组件之间传值
目录 一.父组件向子组件传值 二.子组件向父组件传值 三.兄弟组件之间的传值 如上图所示,2是1的子组件,1是3的父组件,2和3是兄弟组件 一.父组件向子组件传值: html代码: <div i ...
- before vue路由钩子_vue组件级路由钩子函数介绍,及实际应用
正如其名,vue-router 提供的导航钩子主要用来拦截导航,让它完成跳转或取消. 有多种方式可以在路由导航发生时执行钩子:全局的.单个路由独享的.或者组件级的. 一.全局钩子 你可以使用 rout ...
最新文章
- Python 闭包、单个装饰器、多个装饰器、装饰器修饰类、应用场景
- DateTime格式大全
- java 最大线程数 设定_Java8 parallelStream 修改默认的线程数量
- 将你一张表的值覆盖_精准度可达亚米级,山东“北斗一张网”向社会免费开放...
- 无侵入性的在日志中打印对象的关键字段
- Docker学习二:Docker镜像与容器
- Katalon Recorder录制脚本
- micropython教程nucleo-f767zi开发板_教你做CMSIS-DAP仿真器(基于Nucleo-F767ZI)
- Eclisp配置Maven(基础简易版)
- Access链接表的使用
- gbk编码在线转换工具_珍藏的4个PDF格式转换网站「在线工具,无需下载,还免费哦。」...
- asp.net扩展Forms验证
- C语言程序设计教材九斗验证,C语言实验报告参考答案(原)
- VSCode下载安装和修改插件下载位置(配置右键菜单)和更换终端
- 【数据结构】NOJ016—计算二叉树叶子结点数目
- 单片机c51语言考试试题,51单片机基础知识试题题库(考试用含答案)
- 苹果电脑怎么登录邮件服务器,Mac系统中的邮箱怎么创建126邮箱帐户?
- 访问 github.com 的请求遭到拒绝您未获授权,无法查看此网页解决办法
- python破解有道词典加密参数,简单GUI可视化界面操作(2020年5月)
- 新阿阳发卡网完整运营源码
热门文章
- 如何从JFrog Artifactory下载资源到本地
- 3dm下载的都是linux游戏,3DM的游戏怎么下载和安装(没智商的小白用户)
- WinDbg蓝屏分析入门
- Java基础——集合List+Set+泛型+Map
- 基础算法(三)---二分排序(Java)
- 可曾听闻【大话】二字
- Diamond3.5软件的使用--(2)新建工程并生成可烧录文件
- 装饰模式【设计模式学习-03】
- java实训文献_java实训论文参考文献写作指导
- linux创建2g文件,嵌入式 创建一个2G的空文件(Linux命令dd)