微信小程序通讯录功能;uni-app微信小程序通讯录单选;uni-app微信小程序通讯录多选;uni-app微信小程序通讯录好友功能;uni-indexed-list使用;通讯录高度修改;

介绍:项目使用的是uni-app做的微信小程序;uni-app里原来就用一个组件uni-indexed-list,是用来做通讯录的;可以直接看官方案例也就是hello-uniapp-master下的导航栏;但是官方这个是多选,且没有默认选中功能;故本文是在使用官方组件同时,修改原组件的代码来达到单选和默认选中功能
在这里插入图片描述

解决思路:

1.将uni_modules包下的通讯录组件uni-indexed-list复制一份在公共组件components下;

在这里插入图片描述

2.在你自己的页面中,引入这个公共的通讯录组件uni-indexed-list;

3.如果是想要单选用户和具有默认选中某个用户功能,就去修改uni-indexed-list.vue文件(本文只是完成这一需求);针对如果是多选,就不需要改任何代码,可以直接按照官方的demo去做(本文暂未做);

4.修改uni-indexed-list.vue,如果需要单选功能就在onClick方法里,加上以下代码:

在这里插入图片描述

如果想要默认选中某个用户,就在setList方法下添加以下代码:

在这里插入图片描述

5.官方的demo下通讯录,是自适应高度的;如果想要将右侧的ABC字母高度修改成固定的;需要注意修改uni-indexed-list.vue两个地方;

例如我的是将右侧通讯录单个高度设为18px:

5.1设置高度
在这里插入图片描述

5.2 修改触发滑动或者点击时候,对应的触发对应区域(共有三个地方需要修改 搜索 let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight) 进行修改即可 ):
在这里插入图片描述

6.各文件代码:可以直接复制使用,没有调用接口,注意需要修改自己的通讯录数据引入以及自己的通讯录数据格式字段等;筛选输入框需要配合后端返回通讯录数据;保存按钮的事件需要自己写;通讯录组件uni-indexed-list默认是绝对定位的,修改样式需要注意;

6.1自己的页面文件,在这里引入通讯录组件的;  address-list.vue:
<template><view class="address-list"><view class="header"><view class="input-view"><uni-icons type="search" size="22" color="#666666" /><!-- 详见uni-app的  input组件 --><!-- confirm-type设置键盘右下角按钮的文字 send search next go done,仅在 type="text" 时生效。 --><!-- type 有效值 text number idcard digit tel --><input type="text" v-model="real_name" confirm-type="search" class="input-first" placeholder="搜索筛选可以借助后端接口" placeholderStyle="color:#ccc;" @input="changeInput" @blur="searchBtn" @confirm="searchBtn"><!-- #ifndef H5 --><uni-icons v-if="real_name" class="input-uni-del" @tap.stop="closeInput(e)" type="closeempty" size="22" color="#ccc" /><!-- #endif --></view></view><!-- 使用通讯录组件 --><uni-indexed-list :options="list" :show-select="true" @click="bindClick" :select_city="select_city" /><view class="bottom_box"><button @click="updataCity">保存</button></view></view>
</template><script>
import airport from '@/common/airport.js'
// 注意:一定是引入自己 复制在公共组件components下的通讯录组件(自己修改成单选和默认值)
import uniIndexedList from '@/components/uni-indexed-list/components/uni-indexed-list/uni-indexed-list'
export default {// 引入组件components: {uniIndexedList},data () {return {list: airport.list,// 引入的通讯录数据---一般是通过后端接口返回的select_city: '阿里昆莎机场',//默认选中的 --  一般是某个id  值需要父传子给通讯录组件real_name: '',//搜索筛选框的字段  --  为了配合后端做筛选}},methods: {bindClick (e) {console.log('点击item,返回数据' + JSON.stringify(e))},// 点击确认搜索等事件searchBtn (e) {uni.showToast({title: '筛选需后端配合返回数据',icon: 'success',})},// 输入事件changeInput (e) {console.log(e.target.value)},closeInput (e) {this.real_name = ''console.log('清空刷新')},updataCity () {uni.showToast({title: '修改机场成功',icon: 'success',mask: true})}}
}
</script><style lang="less" scope>
.address-list {//原生的input-first框.header {/* #ifndef APP-NVUE */display: flex;/* #endif */flex-direction: row;padding: 17rpx 40rpx;align-items: center;border-top-width: 1px;border-top-color: #f5f5f5;border-top-style: solid;background-color: #ffffff;.input-view {/* #ifndef APP-NVUE */display: flex;/* #endif */align-items: center;flex-direction: row;height: 70rpx;line-height: 70rpx;border: 1px solid #ddd;border-radius: 35rpx;padding: 0 10px;flex: 1;.input-first {flex: 1;padding: 0 5px;height: 70rpx;line-height: 70rpx;font-size: 14px;background-color: transparent;}}}// 通讯录 原本就是用的绝对定位.uni-indexed-list {width: 98% !important;top: 126rpx !important;bottom: 152rpx !important; //影响右侧的XYZ显示}/* 解决小程序和app滚动条的问题 */::-webkit-scrollbar {display: none;}.bottom_box {width: 100%;position: fixed !important;bottom: 0;background-color: #fff;z-index: 999 !important;padding: 30rpx;box-sizing: border-box;button {height: 94rpx;background-color: #108ee9;font-family: PingFangSC-Regular;font-size: 36rpx;color: #ffffff;text-align: center;line-height: 94rpx;}}
}
</style>
6.2需要修改的公共罪案components下的通讯录组件uni-indexed-list.vue
<template><view class="uni-indexed-list" ref="list" id="list"><!-- #ifdef APP-NVUE --><list class="uni-indexed-list__scroll" scrollable="true" show-scrollbar="false"><cell v-for="(list, idx) in lists" :key="idx" :ref="'uni-indexed-list-' + idx"><!-- #endif --><!-- #ifndef APP-NVUE --><scroll-view :scroll-into-view="scrollViewId" class="uni-indexed-list__scroll" scroll-y><view v-for="(list, idx) in lists" :key="idx" :id="'uni-indexed-list-' + idx"><!-- #endif --><indexed-list-item :list="list" :loaded="loaded" :idx="idx" :showSelect="showSelect" @itemClick="onClick"></indexed-list-item><!-- #ifndef APP-NVUE --></view></scroll-view><!-- #endif --><!-- #ifdef APP-NVUE --></cell></list><!-- #endif --><view class="uni-indexed-list__menu" :class="touchmove ? 'uni-indexed-list__menu--active' : ''" @touchstart="touchStart" @touchmove.stop.prevent="touchMove" @touchend="touchEnd" @mousedown.stop="mousedown" @mousemove.stop.prevent="mousemove" @mouseleave.stop="mouseleave"><view v-for="(list, key) in lists" :key="key" class="uni-indexed-list__menu-item"><text class="uni-indexed-list__menu-text" :class="touchmoveIndex == key ? 'uni-indexed-list__menu-text--active' : ''">{{ list.key }}</text></view></view><view v-if="touchmove" class="uni-indexed-list__alert-wrapper"><text class="uni-indexed-list__alert">{{ lists[touchmoveIndex].key }}</text></view></view>
</template>
<script>
import indexedListItem from './uni-indexed-list-item.vue'
// #ifdef APP-NVUE
const dom = weex.requireModule('dom')
// #endif
// #ifdef APP-PLUS
function throttle (func, delay) {var prev = Date.now()return function () {var context = thisvar args = argumentsvar now = Date.now()if (now - prev >= delay) {func.apply(context, args)prev = Date.now()}}
}function touchMove (e) {let pageY = e.touches[0].pageYlet index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)if (this.touchmoveIndex === index) {return false}let item = this.lists[index]if (item) {// #ifndef APP-NVUEthis.scrollViewId = 'uni-indexed-list-' + indexthis.touchmoveIndex = index// #endif// #ifdef APP-NVUEdom.scrollToElement(this.$refs['uni-indexed-list-' + index][0], {animated: false})this.touchmoveIndex = index// #endif}
}
const throttleTouchMove = throttle(touchMove, 40)
// #endif/*** IndexedList 索引列表* @description 用于展示索引列表* @tutorial https://ext.dcloud.net.cn/plugin?id=375* @property {Boolean} showSelect = [true|false] 展示模式* 	@value true 展示模式* 	@value false 选择模式* @property {Object} options 索引列表需要的数据对象* @event {Function} click 点击列表事件 ,返回当前选择项的事件对象* @example <uni-indexed-list options="" showSelect="false" @click=""></uni-indexed-list>*/
export default {name: 'UniIndexedList',components: {indexedListItem},props: {options: {type: Array,default () {return []}},showSelect: {type: Boolean,default: false},select_city: {type: String,default: ''}},data () {return {lists: [],winHeight: 0,itemHeight: 0,winOffsetY: 0,touchmove: false,touchmoveIndex: -1,scrollViewId: '',touchmovable: true,loaded: false,isPC: false}},watch: {options: {handler: function () {this.setList()},deep: true}},mounted () {// #ifdef H5this.isPC = this.IsPC()// #endifsetTimeout(() => {this.setList()}, 50)setTimeout(() => {this.loaded = true}, 300)},methods: {setList () {let index = 0this.lists = []this.options.forEach((value, index) => {if (value.data.length === 0) {return}let indexBefore = indexlet items = value.data.map(item => {let obj = {}obj['key'] = value.letterobj['name'] = itemobj['itemIndex'] = indexindex++obj.checked = item.checked ? item.checked : falsereturn obj})this.lists.push({title: value.letter,key: value.letter,items: items,itemIndex: indexBefore})})//----------------------自己添加的部分 目的是 将默认选中的机场 便利后就将其checked设置未true 这样显示就会是选中 (一般被选中的给的是id 而不是字符串name)this.lists.forEach(ele => {ele.items.forEach(val => {if (val.name == this.select_city) {val.checked = true}})})//----------------------自己添加的部分 目的是 将默认选中的机场 便利后就将其checked设置未true 这样显示就会是选中 (一般被选中的给的是id 而不是字符串name)// #ifndef APP-NVUEuni.createSelectorQuery().in(this).select('#list').boundingClientRect().exec(ret => {this.winOffsetY = ret[0].topthis.winHeight = ret[0].heightthis.itemHeight = this.winHeight / this.lists.length})// #endif// #ifdef APP-NVUEdom.getComponentRect(this.$refs['list'], (res) => {this.winOffsetY = res.size.topthis.winHeight = res.size.heightthis.itemHeight = this.winHeight / this.lists.length})// #endif},touchStart (e) {this.touchmove = truelet pageY = this.isPC ? e.pageY : e.touches[0].pageYlet index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)let item = this.lists[index]if (item) {this.scrollViewId = 'uni-indexed-list-' + indexthis.touchmoveIndex = index// #ifdef APP-NVUEdom.scrollToElement(this.$refs['uni-indexed-list-' + index][0], {animated: false})// #endif}},touchMove (e) {// #ifndef APP-PLUSlet pageY = this.isPC ? e.pageY : e.touches[0].pageYlet index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)if (this.touchmoveIndex === index) {return false}let item = this.lists[index]if (item) {this.scrollViewId = 'uni-indexed-list-' + indexthis.touchmoveIndex = index}// #endif// #ifdef APP-PLUSthrottleTouchMove.call(this, e)// #endif},touchEnd () {this.touchmove = falsethis.touchmoveIndex = -1},/*** 兼容 PC @tian*/mousedown (e) {if (!this.isPC) returnthis.touchStart(e)},mousemove (e) {if (!this.isPC) returnthis.touchMove(e)},mouseleave (e) {if (!this.isPC) returnthis.touchEnd(e)},// #ifdef H5IsPC () {var userAgentInfo = navigator.userAgentvar Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"]var flag = truefor (let v = 0; v < Agents.length - 1; v++) {if (userAgentInfo.indexOf(Agents[v]) > 0) {flag = falsebreak}}return flag},// #endifonClick (e) {//----------------------自己添加的部分 目的是 将选择客户B时候 将之前选中的其他客户A等的状态全部清空未false 后面再单独给B设置选中true -- 这样就可以控制单选一人this.lists.forEach((ele, i) => {ele.items.forEach((val, j) => {val.checked = false})})//----------------------自己添加的部分 目的是 将选择客户B时候 将之前选中的其他客户A等的状态全部清空未false 后面再单独给B设置选中true -- 这样就可以控制单选一人let {idx,index} = elet obj = {}for (let key in this.lists[idx].items[index]) {obj[key] = this.lists[idx].items[index][key]}let select = []if (this.showSelect) {// 这一步是原来就有的 目的是给当前选择的用户 标记为选中状态truethis.lists[idx].items[index].checked = !this.lists[idx].items[index].checkedthis.lists.forEach((value, idx) => {value.items.forEach((item, index) => {if (item.checked) {let obj = {}for (let key in this.lists[idx].items[index]) {obj[key] = this.lists[idx].items[index][key]}select.push(obj)}})})}this.$emit('click', {item: obj,select: select})}}
}
</script>
<style lang="scss" scoped>
.uni-indexed-list {position: absolute;left: 0;top: 0;right: 0;bottom: 0;/* #ifndef APP-NVUE */display: flex;/* #endif */flex-direction: row;
}.uni-indexed-list__scroll {flex: 1;
}.uni-indexed-list__menu {width: 24px;background-color: lightgrey;/* #ifndef APP-NVUE */display: flex;/* #endif */flex-direction: column;
}.uni-indexed-list__menu-item {/* #ifndef APP-NVUE */display: flex;/* #endif */flex: 1;align-items: center;justify-content: center;/* #ifdef H5 */cursor: pointer;/* #endif */
}.uni-indexed-list__menu-text {line-height: 20px;font-size: 12px;text-align: center;color: #aaa;
}.uni-indexed-list__menu--active {background-color: rgb(200, 200, 200);
}.uni-indexed-list__menu-text--active {color: #007aff;
}.uni-indexed-list__alert-wrapper {position: absolute;left: 0;top: 0;right: 0;bottom: 0;/* #ifndef APP-NVUE */display: flex;/* #endif */flex-direction: row;align-items: center;justify-content: center;
}.uni-indexed-list__alert {width: 80px;height: 80px;border-radius: 80px;text-align: center;line-height: 80px;font-size: 35px;color: #fff;background-color: rgba(0, 0, 0, 0.5);
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/403545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推荐! el-input 输入框类型;只能输入数字的输入框;保留两位小数输入框;只能输入正整数和0的输入框;手机号正则校验;车牌号码正则校验

去除多余的0看这篇 以下代码可直接复制使用&#xff1a; 以下代码可直接复制使用&#xff01; <template><div><a href"https://baike.baidu.com/item/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1700215?fraladdin#10">百度正则</a&…

Java多线程之JUC包:Semaphore源码学习笔记

若有不正之处请多多谅解&#xff0c;并欢迎批评指正。 请尊重作者劳动成果&#xff0c;转载请标明原文链接&#xff1a; http://www.cnblogs.com/go2sea/p/5625536.html Semaphore是JUC包提供的一个共享锁&#xff0c;一般称之为信号量。 Semaphore通过自定义的同步器维护了一个…

在vue项目中操作元素ref案例;

原博主链接 <!--* Description:会动的词云* Author: Vergil* Date: 2021-08-25 14:17:45* LastEditTime: 2021-08-25 17:08:15* LastEditors: Vergil --> <template><div class"wordCloud" ref"wordCloud"></div> </template&…

【C->Cpp】深度解析#由C迈向Cpp(2)

目录 &#xff08;一&#xff09;缺省参数 全缺省参数 半缺省参数 缺省参数只能在函数的声明中出现&#xff1a; 小结&#xff1a; &#xff08;二&#xff09;函数重载 函数重载的定义 三种重载 在上一篇中&#xff0c;我们从第一个Cpp程序为切入&#xff0c;讲解了Cpp的…

Session机制详解

虽然session机制在web应用程序中被采 用已经很长时间了&#xff0c;但是仍然有很多人不清楚session机制的本质&#xff0c;以至不能正确的应用这一技术。本文将详细讨论session的工作机制并且对在 Java web application中应用session机制时常见的问题作出解答。 一、术语ses…

element-ui的表单校验;el-form表单校验;el-form表单自定义校验;手机号校验;车牌号校验;车牌号正则校验;手动校验表单某一项;手动清空表单的某一项校验结果

示例&#xff1a;代码在末尾 可以直接复制使用 一、基本属性认知&#xff1a; 1. required: true 会有 * &#xff0c; 但仅是触发最后点击提交按钮时&#xff0c;校验某一项位必填&#xff1b;与输入事件或者选择或者失焦时候 怎么校验无关 &#xff08;这时候的校验取决于是…

Eclipse For JavaSE安装、配置、测试

Eclipse For JavaSE安装、配置、测试(win7_64bit) 目录 1.概述 2.本文用到的工具 3.安装与配置 4.JavaSE开发测试 5.ADT安装与Android开发测试 6.注意事项 7.相关博文 >>看不清的图片可在新标签打开查看大图 1.概述 eclipse应该是Java开发界家喻户晓的IDE了&#xff0c;通…

epoll的两种模式

From: http://haoningabc.iteye.com/blog/1432958 linux异步IO浅析 http://hi.baidu.com/_kouu/blog/item/e225f67b337841f42f73b341.html epoll有两种模式,Edge Triggered(简称ET) 和 Level Triggered(简称LT).在采用这两种模式时要注意的是,如果采用ET模式,那么仅当状态发生…

关闭eslint检验;vue-cli3搭建的vue项目关闭eslint;脚手架3关闭eslint;

本文是解决关闭eslint的问题&#xff1b;如果想要开启eslint和配置&#xff0c;可以查看这篇开启eslint检验&#xff1b; 我们使用vue-cli3脚手架搭建vue项目时候&#xff0c;会默认选中eslint风格代码&#xff1b;如果想要关闭eslint检验&#xff0c;有如下两种方案&#xff…

转一篇关于并发和并行概念的好文,附带大神评论

转自&#xff1a;https://laike9m.com/blog/huan-zai-yi-huo-bing-fa-he-bing-xing,61/ 还在疑惑并发和并行&#xff1f; OK&#xff0c;如果你还在为并发&#xff08;concurrency&#xff09;和并行&#xff08;parallesim&#xff09;这两个词的区别而感到困扰&#xff0c;那…

MySQL索引背后的数据结构及算法原理-转

转 http://www.codinglabs.org/html/theory-of-mysql-index.html 摘要 本文以MySQL数据库为研究对象&#xff0c;讨论与数据库索引相关的一些话题。特别需要说明的是&#xff0c;MySQL支持诸多存储引擎&#xff0c;而各种存储引擎对索引的支持也各不相同&#xff0c;因此MySQL…

vue项目通过directives指令实现vue实现盒子的移动;vue拖拽盒子;vue移动;

vue项目&#xff1a;点击拖拽盒子&#xff1b;移动盒子&#xff1b; 代码可直接复制&#xff1a;&#xff08;注意需要在移动的盒子上添加 v-指令 注意采用固定定位&#xff09; <template><div class"far_box"><div>{{ msg }}</div><!-…

SuperAgent 中文乱码星号问号问题

看到星号问号了么&#xff0c;SuperAgent 爬取时中文乱码星号&#xff0c;只有中文是乱码&#xff0c;其它都是对的&#xff0c;肯定需要转义&#xff0c;找了两个小时&#xff0c;最后度娘看到个帖子 https://cloud.tencent.com/developer/article/1445392试了试&#xff0c;…

制作 Windows8   to Go

制作 Windows to Go 将准备好的 Windows 8 的镜像文件&#xff08;ISO 格式&#xff09;加载到虚拟光驱中去&#xff1b;将准备好的 USB 存储设备插入&#xff1b;打开控制面板&#xff0c;点击“Windows To Go”&#xff1b;在接下来的选项中按照步骤提示选择对应的 Win 8 的镜…

vue监听浏览器刷新和关闭;

注意&#xff1a;区分不了浏览器是触发了刷新还是关闭&#xff0c;而且提示的弹框是无法自定义的&#xff1b;如果有大佬有方法能区分&#xff0c;还请评论学习一下&#xff01;感谢&#xff01; 代码可直接复制&#xff1a; <template><div><div /></di…

计算文件的md5;vue计算文件md5值;计算图片的md5值;

github链接 1.先下载 npm i browser-md5-file -S2.在使用的vue页面引入和声明方法 import BMF from browser-md5-file const bmf new BMF()3.使用方法&#xff1a; function handle(e) {const file e.target.files[0];bmf.md5(file,(err, md5) > {console.log(err:, err);…

【转】【天道酬勤】 腾讯、百度、网易游戏、华为Offer及笔经面经

面试完毕&#xff0c;已跟网易游戏签约。遂敲一份笔经面经&#xff0c;记录下面试经过。类似于用日记记录自己&#xff0c;同时希望对师弟师妹有一定帮助。不是炫耀&#xff0c;只是希望攒RP&#xff0c;希望各位不要鄙视我。正所谓“饮水思源”。小弟来自广州华南理工大学&…

⭐️ vue项目使用微信表情;vue引入微信表情emoji;vue中使用微信表情包emoji;

以下的表情是通过引入emoji-vue插件做的&#xff1b;如果只是简单的显示个别表情&#xff0c;其实还可以用html的emoji的标签来完成 &#x1f61d;&#x1f64a;&#x1f47f;&#x1f525;&#x1f335;&#x1f344;&#x1f349;&#x1f1e8;&#x1f1f3;&#x1f61a;&am…

奈奎斯特采样定理:

&#xff08;1&#xff09;奈奎斯特采样定理&#xff1a; 当采样频率fs.max大于信号中最高频率fmax的2倍时&#xff0c;即&#xff1a;fs.max>2fmax,则采样之后的数字信号完整地保留了原始信号中的信息&#xff1b; 转载于:https://www.cnblogs.com/jocobHerbertPage/archiv…

vue项目引入字体图标iconfont

直接将icon下载成图片使用或者通过import方式移入url使用&#xff0c;看此篇 本文介绍两种使用方案&#xff1a;1.使用Font class引入字体图标&#xff08;推荐&#xff09; 2.使用Symbol 引用 如果是分批次的下载了好几次字体图标&#xff0c;那么可以将解压的代码css等文件放…