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

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

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.

相关推荐
热点推荐
50只鲍鱼女儿刚夹起1只,婆婆1巴掌扇过去,儿媳下一秒让婆婆后悔

50只鲍鱼女儿刚夹起1只,婆婆1巴掌扇过去,儿媳下一秒让婆婆后悔

星辰故事屋
2024-06-15 11:45:53
取消对华免签,还拒绝中国的高铁,甚至放言:“不欢迎中国人”!

取消对华免签,还拒绝中国的高铁,甚至放言:“不欢迎中国人”!

星辰故事屋
2024-06-18 10:54:05
下半场到来:中国将彻底调整经济布局(深度)

下半场到来:中国将彻底调整经济布局(深度)

流逝的沙
2024-07-02 11:25:16
他身为全国政协副主席,亲弟开小卖铺糊口,儿子靠开货车谋生!

他身为全国政协副主席,亲弟开小卖铺糊口,儿子靠开货车谋生!

杨哥历史
2024-07-03 16:41:14
地铁上让座叶大爷遭围攻,终遭报应

地铁上让座叶大爷遭围攻,终遭报应

看界馆
2024-07-03 15:43:16
iPhone 16爆料汇总:起步5999元新增实体按键

iPhone 16爆料汇总:起步5999元新增实体按键

中关村在线
2024-07-03 12:01:15
实力越强阵容越怪?下赛季联盟5大奇葩阵容:快船7后卫,掘金4塔

实力越强阵容越怪?下赛季联盟5大奇葩阵容:快船7后卫,掘金4塔

你的篮球频道
2024-07-03 12:01:32
7比6和6比3横扫!21岁华裔大满贯冠军归来,网友:甩掉水货帽子

7比6和6比3横扫!21岁华裔大满贯冠军归来,网友:甩掉水货帽子

体坛知识分子
2024-07-04 06:10:02
解放军 108 架战机亮剑台海,美对台军售惹怒中国!

解放军 108 架战机亮剑台海,美对台军售惹怒中国!

笔墨V
2024-07-04 05:36:45
飞阿勒泰的机票,不升反降!暑期出游花费更省?

飞阿勒泰的机票,不升反降!暑期出游花费更省?

半岛晨报
2024-07-03 18:19:02
家中再穷,也不要让子女从事这4类工作,看似工资高实则没前途

家中再穷,也不要让子女从事这4类工作,看似工资高实则没前途

时尚的弄潮
2024-07-02 23:45:55
凶多吉少!湖南一对情侣玩皮艇翻船溺水失联,事发时均未穿救生衣

凶多吉少!湖南一对情侣玩皮艇翻船溺水失联,事发时均未穿救生衣

火山诗话
2024-07-04 06:30:29
曝曼联同意6000万出售拉什福德!拉爵大裁员,俱乐部将精简250人

曝曼联同意6000万出售拉什福德!拉爵大裁员,俱乐部将精简250人

罗米的曼联博客
2024-07-04 09:29:07
一个偷情的妇女讲出了实话:老公和情人的差距在哪?

一个偷情的妇女讲出了实话:老公和情人的差距在哪?

四象八卦
2024-07-03 12:29:44
美国人真买不起房了:房价持续上涨中位数36万美元!住房成本占美国平均工资的35.1%

美国人真买不起房了:房价持续上涨中位数36万美元!住房成本占美国平均工资的35.1%

和讯网
2024-07-03 15:52:03
来不及了!卡米拉解锁女王传家宝,这些价值连城的珠宝保不住了

来不及了!卡米拉解锁女王传家宝,这些价值连城的珠宝保不住了

白宸侃片
2024-07-04 07:50:11
笑趴了!上海向佛祖借了100个亿?官方紧急辟谣,网友众说纷纭

笑趴了!上海向佛祖借了100个亿?官方紧急辟谣,网友众说纷纭

鬼谷子思维
2024-07-03 16:25:56
“吃一顿饭,做4次爱”:2022最恶心的男人出现了!

“吃一顿饭,做4次爱”:2022最恶心的男人出现了!

黎兜兜
2022-09-15 20:39:33
朝阳群众又出手!在北京抓捕的4位明星,个个臭名远扬、下场凄惨

朝阳群众又出手!在北京抓捕的4位明星,个个臭名远扬、下场凄惨

附允历史观
2024-06-28 10:25:08
马卡:西足协已决定2030年世界杯决赛在伯纳乌举行

马卡:西足协已决定2030年世界杯决赛在伯纳乌举行

直播吧
2024-07-03 20:44:12
2024-07-04 12:20:49
技术小生
技术小生
互联网技术与技术人的职业发展
957文章数 498关注度
往期回顾 全部

科技要闻

三折卖“问界”撇清关系,华为这买卖值吗

头条要闻

卢沙野称"台政权是叛乱政权" 蔡正元:叫解放军东征啊

头条要闻

卢沙野称"台政权是叛乱政权" 蔡正元:叫解放军东征啊

体育要闻

我不用当体育老师了,我去踢欧洲杯了!

娱乐要闻

胡歌打败范伟,又一个内娱黑幕?

财经要闻

理想裁员闹笑话,蔚来裁员闹风波?

汽车要闻

巴黎4S店价格对比 同款车型中国售价打对折

态度原创

数码
家居
本地
手机
公开课

数码要闻

家庭鸿蒙平板到手1299元 MatePad SE 11英寸今天开售

家居要闻

艺术栖居 撞色不羁

本地新闻

云游中国 | 走进安塞,寻觅黄土高原文化记忆

手机要闻

realme 真我 13 Pro+ 手机参数曝光,骁龙 7s Gen 2 处理器

公开课

连中三元是哪三元?

无障碍浏览 进入关怀版