网易首页 > 网易号 > 正文 申请入驻

组件封装之输入框下拉列表

0
分享至

点击⬆️方“逆锋起笔”,公众号回复 编程资源

领取大佬们推荐的学习资料

作者:Tokiya

来源:SegmentFault 思否社区

前言

项目开发的时候刚好遇到一个需求,需要在输入框输入名字的时候,弹出相应的人员列表提供选择,然后将数据赋值给输入框。项目是使用iview组件的,一开始想着在自定义iview的下拉选择,后来发现效果并不理想。为了实现功能,就在iview输入框的基础上进行了组件封装,下面就来讲下组件封装的过程。

思路:

对于组件封装,首先需要确定功能,组件的整体结构,后面再去处理组件的数据交互逻辑。

过程:

组件的结构以及样式:

话不多说,先把组件基本的结构样式贴出来。

组件布局:

"selectInput">

"input-box">
type= "text" />

"input-dropdown">

"dropdown-title">
您可能需要查找

"dropdown-content">

  • "content-list">
  • "list-item">
    "item-avatar">李
    "item-name">李四

"content-msg">
暂无数据

既然是输入下拉,就需要一个输入框以及一个下拉列表。

样式:

.selectInput {
position: relative;
.input-dropdown {
min-width: 200px;
position: absolute;
top: 35px;
left: 0;
border: 1px solid #cfcfcf;
border-radius: 5px;
.dropdown-title {
padding: 5px 10px;
color: #e1e1e1;
background-color: #f8f8f8;
}
.dropdown-content {
.content-list {
margin: 0;
padding: 0;
.list-item {
margin: 0;
padding: 5px 10px ;
list-style: none;
&:hover {
cursor: pointer;
background-color: #f7f5f5;
}
.item-avatar {
display: inline-block;
width: 30px;
height: 30px;
line-height: 30px;
color: #ffffff;
background-color: #b6c4de;
border-radius: 50%;
text-align: center;
margin-right: 10px;
}
.item-name {
display: inline-block;
color: #666666;
}
}
}
.content-msg {
padding: 10px;
color: #cccccc;
}
}
}
}

写完布局以及样式之后的效果:

组件的功能逻辑: 1. 确定父子组件数据传递的props

props: {
// 父组件传递的输入框初始值
value: {
type: String,
default: ''
},
// 下拉列表的标题
dropdownTitle: {
type: String,
default: '您可能要找'
},
// 下拉列表搜索数据为空时的提示
dropdownMsg: {
type: String,
default: '数据为空!'
},
// 下拉列表的初始数组
dropdownList: {
type: Array,
default: () => []
},
// 输入框的提示
placeholder: {
type: String,
default: '请输入名字'
},
}


2. 定义组件的data

data() {
return {
// 控制下拉列表显示
dropdownShow: false,
// 控制下拉列表数据为空提示显示
dropdownMsgShow: false,
// 输入框值
inputValue: '',
// 搜索后的下拉列表,用于渲染下拉
searchDataList: []
}
}


3. 下拉列表的搜索逻辑

"selectInput">

"input-box">
"placeholder" v-model= "inputValue" @input.native= "handleInput" type= "text" />

"dropdownShow"input-dropdown">

"dropdown-title">
{{ dropdownTitle }}

"dropdown-content">

  • "content-list">
  • "(item, index) in searchDataList" :key= "index" @click= "handleChoose(item.name)"list-item">
    "item-avatar">{{ item.avatar }}
    "item-name">{{ item.name }}

"dropdownMsgShow"content-msg">
{{ dropdownMsg }}

通过dropdownShow去控制下拉列表的显示隐藏,给输入框绑定一个inputValue值和一个input事件。

// 输入框输入处理函数
handleInput: debounce( function () {
let _this = this;
_this.searchDataList = [];
if (_this.inputValue === '') {
_this.dropdownShow = false;
} else {
_this.dropdownList.map(v => {
if (v.name.indexOf(_this.inputValue) >= 0) {
_this.searchDataList.push(v);
}
});
_this.searchDataList.length > 0 ? _this.dropdownMsgShow = false : _this.dropdownMsgShow = true;
_this.dropdownShow = true;
}
})

handleInput 我做了防抖处理,在这个函数里面通过监听输入框输入事件,判断输入框的 inputValue 是否为空,若为空则直接隐藏下拉列表。不为空则循环迭代从父组件传递过来的 dropdownList ,并将符合条件的 item 存进 searchDataList ,然后在组件中通过 v-for 渲染出数据(微信搜索公众号 逆锋起笔,关注后回复 编程资源,领取各种经典学习资料)。


最后通过判断 searchDataList 的长度给 dropdownMsgShow 赋值,来控制搜索数据的提示信息。

4. 搜索后的点击选择处理

给下拉列表的每一项 li 绑定一个点击事件 handleChoose

// 下拉选择处理函数
handleChoose: function (val) {
let _this = this;
_this.inputValue = val;
_this.dropdownShow = false;
}

点击之后对输入框进行赋值,并隐藏下拉列表。

5. 给组件添加一个clickoutside指令

自定义 clickoutside 指令,当点击组件外的区域时隐藏下拉列表。

directives: {
// 自定义指令用于处理点击组件区域之外的click事件
clickoutside: {
bind(el, binding, vnode) {
function documentHandler(e) {
if (el.contains(e.target)) {
return false;
}
if (binding.expression) {
binding.value(e);
}
}
el.__vueClickOutSize__ = documentHandler;
document.addEventListener( "click", documentHandler);
},
unbind(el, binding) {
document.removeEventListener( "click", el.__vueClickOutSize__);
delete el.__vueClickOutSize__;
},
},
},

给指令绑定一个关闭事件 handleClose

// 下拉列表隐藏处理函数
handleClose: function() {
let _this = this;
if (_this.dropdownShow) {
if (_this.searchDataList.length === 1) {
_this.inputValue = _this.searchDataList[0].name;
} else {
_this.inputValue = '';
}
}
_this.dropdownShow = false;
},

在这个函数里我做了一个处理,当点击的时候,搜索列表有数据时,会默认选中第一个,否则清空输入框。

关于函数防抖以及 clickoutside ,网上有大佬发了一些关于这些的文章,我在这里就不进行赘述了。

至此,组件封装完成,组件的大体思路是这样子,具体的逻辑处理可以根据实际情况进行相应的调整。

最后附上整个组件的代码:
调用代码:

"blog">
"personnelList">

组件代码:

"handleClose"selectInput">

"input-box">
"placeholder" v-model= "inputValue" @input.native= "handleInput" type= "text" />

"dropdownShow"input-dropdown">

"dropdown-title">
{{ dropdownTitle }}

"dropdown-content">

  • "content-list">
  • "(item, index) in searchDataList" :key= "index" @click= "handleChoose(item.name)"list-item">
    "item-avatar">{{ item.avatar }}
    "item-name">{{ item.name }}


"dropdownMsgShow"content-msg">
{{ dropdownMsg }}

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
王志文被封杀的“前因后果”,媒体:劣迹斑斑!

王志文被封杀的“前因后果”,媒体:劣迹斑斑!

文刀万
2024-11-28 06:00:03
皇马输球的原因找到了,姆巴佩在更衣室被冷落,赛后一举动引争议

皇马输球的原因找到了,姆巴佩在更衣室被冷落,赛后一举动引争议

姜大叔侃球
2024-11-29 11:06:18
正式告别!奥斯卡发声官宣重要决定,上港俱乐部批准,球迷送祝福

正式告别!奥斯卡发声官宣重要决定,上港俱乐部批准,球迷送祝福

小海要说球
2024-11-28 20:13:00
比北欧便宜一半不止!全球看极光最便宜的地方!电子签0拒签,去纯净雪国,实现帝王蟹自由!

比北欧便宜一半不止!全球看极光最便宜的地方!电子签0拒签,去纯净雪国,实现帝王蟹自由!

马蜂窝旅游攻略
2024-11-27 17:59:10
停止搬迁计划!永久关闭!补偿总额或超27亿元

停止搬迁计划!永久关闭!补偿总额或超27亿元

FM93浙江交通之声
2024-11-29 10:07:38
23.59万元起?小米SUV起售价曝光,明年3月上市,外观神似法拉利

23.59万元起?小米SUV起售价曝光,明年3月上市,外观神似法拉利

泡泡网
2024-11-29 14:59:20
16助攻,19助攻,22助攻,抱歉约基奇:你的助攻王悬了

16助攻,19助攻,22助攻,抱歉约基奇:你的助攻王悬了

篮球大视野
2024-11-29 12:30:46
72岁唐国强近照,嘴巴紧闭脸部发黑,老到认不出,走路小心翼翼

72岁唐国强近照,嘴巴紧闭脸部发黑,老到认不出,走路小心翼翼

老鹈爱历史
2024-11-28 11:05:12
友谊小船说翻就翻,以色列撕开停火协议

友谊小船说翻就翻,以色列撕开停火协议

那山星火
2024-11-29 07:30:25
动真格了! 中方出手了,这次不仅仅是警告!

动真格了! 中方出手了,这次不仅仅是警告!

星辰故事屋
2024-11-29 11:36:31
活久见!青岛最烂网约车走红网络,网友:别嘲笑人家,这是她饭碗

活久见!青岛最烂网约车走红网络,网友:别嘲笑人家,这是她饭碗

火山诗话
2024-11-28 06:40:16
52岁巩俐直言“每周四次”,70岁米歇尔体检证明自己:我跟得上

52岁巩俐直言“每周四次”,70岁米歇尔体检证明自己:我跟得上

柴叔带你看电影
2024-11-28 15:31:16
震惊!网传特斯拉降价后,有车主天天去4S店里搬水,表示很难受

震惊!网传特斯拉降价后,有车主天天去4S店里搬水,表示很难受

火山诗话
2024-11-29 07:34:51
菲4大部门出手,杜特尔特父女危险,我军出手给菲律宾“上强度”

菲4大部门出手,杜特尔特父女危险,我军出手给菲律宾“上强度”

说天说地说实事
2024-11-29 13:28:58
笑麻了!原来要戳破台湾民进党的谎言,只需马龙去一趟就可以了!

笑麻了!原来要戳破台湾民进党的谎言,只需马龙去一趟就可以了!

青青子衿
2024-11-29 05:18:26
又一国宣布:终止合作

又一国宣布:终止合作

环球时报新闻
2024-11-29 11:10:29
英媒:曼联球员不愿意给安东尼传球,阿莫林非常生气

英媒:曼联球员不愿意给安东尼传球,阿莫林非常生气

雷速体育
2024-11-29 08:57:15
最低气温<5℃!广东将迎来两股冷空气……

最低气温<5℃!广东将迎来两股冷空气……

南粤女声
2024-11-29 15:22:23
某局大崩溃:管理人员都发不出工资了!

某局大崩溃:管理人员都发不出工资了!

黯泉
2024-11-23 22:57:36
一名物业和两名外卖员受伤,警方通报详情

一名物业和两名外卖员受伤,警方通报详情

鲁中晨报
2024-11-29 09:28:07
2024-11-29 19:23:00
技术小生
技术小生
互联网技术与技术人的职业发展
957文章数 508关注度
往期回顾 全部

科技要闻

2024新一代AI(深圳)创业创新大赛决赛

头条要闻

俄国防部:俄防空部队一周内击落10枚美制ATACMS导弹

头条要闻

俄国防部:俄防空部队一周内击落10枚美制ATACMS导弹

体育要闻

中国足球需要什么样的舆论环境

娱乐要闻

叶珂被曝独自去产检,他俩真分了吗

财经要闻

专家建议将农民养老金提升至每月500元

汽车要闻

问界M7今年累计交付量已突破18万辆

态度原创

房产
健康
家居
艺术
教育

房产要闻

大量甩地!114亿,4790亩!海南土地市场全面爆发!

花18万治疗阿尔茨海默病,值不值?

家居要闻

现代设计感 温馨两居室

艺术要闻

故宫珍藏的墨迹《十七帖》,比拓本更精良,这才是地道的魏晋写法

教育要闻

门锁密码、爸妈吵架......孩子在学校当“大喇叭”,家里的隐私藏不住了

无障碍浏览 进入关怀版