vue组件实践之可搜索下拉框功能


Posted in Javascript onNovember 25, 2018

之前也写过这个小组件,最近遇到select下加搜索的功能,所以稍微完善一下。

效果图:

vue组件实践之可搜索下拉框功能

子组件 DROPDOWN.VUE

<template>
 <div class="vue-dropdown default-theme">
 <div class="cur-name" :class="isShow ? 'show':''" @click="isShow =! isShow">{{itemlist.cur.name}}</div>
 <div class="list-and-search" :class="isShow?'on':''">
 <div class="search-module clearfix" v-show="isNeedSearch">
  <input class="search-text" 
  @keyup='search($event)' :placeholder="placeholder" />
  </div>
  <ul class="list-module">
  <li v-for ="(item,index) in datalist" @click="selectToggle(item)" 
  :key="index">
   <span class="list-item-text">{{item.name}}</span>
  </li>
  </ul>
  <div class="tip-nodata" v-show="isNeedSearch && datalist.length == 0">{{nodatatext}}</div>
 </div>
 </div>
</template>

<script>
 export default {
 data(){
  return {
  datalist:[],
  isShow:false
  }
 },
 props:{
  'itemlist':Object,//父组件传来的数据
  'placeholder':{
  type:String,
  default: '搜索' //input placeholder的默认值
  },
  'isNeedSearch':{ //是否需要搜索框
  type:Boolean,
  default: false
  },
  'nodatatext':{ 
  type:String,
  default: '未找到结果' //没有搜索到时的文本提示
  } 
 },
 created(){
  this.datalist = this.itemlist.data;
  //点击组件以外的地方,收起
  document.addEventListener('click', (e) => {
  if (!this.$el.contains(e.target)){
   this.isShow = false; 
  }
  }, false)
 },
 methods:{
  selectToggle(data){
  this.itemlist.cur.name = data.name;
  this.isShow = false;
  this.$emit('item-click',data);
  },
  search(e){
  let searchvalue = e.currentTarget.value;
  this.datalist = this.itemlist.data.filter((item,index,arr)=>{
   return item.name.indexOf(searchvalue) != -1;
  });
  }
 }
 }
</script>

<style lang="less" scoped>
 .list-and-search{
 background: #fff;
 border: 1px solid #ccc;
 display: none;
 &.on{
  display: block;
 }
 }
 .cur-name{
 height: 32px;
 line-height: 32px;
 text-indent: 10px;
 position: relative;
 color: #777;
 &:after{
 position: absolute;
 right: 9px;
 top: 13px;
 content: " ";
 width: 0;
 height: 0;
 border-right: 6px solid transparent;
 border-top: 6px solid #7b7b7b;
 border-left: 6px solid transparent;
 border-bottom: 6px solid transparent;
 }
 &.show{
 &:after{
 right: 9px;
 top: 6px;
 border-right: 6px solid transparent;
 border-bottom: 6px solid #7b7b7b;
 border-left: 6px solid transparent;
 border-top: 6px solid transparent;
 }
 }
 }
 .vue-dropdown.default-theme {
 width: 200px;
 z-index:10;
 border-radius:3px; 
 border: 1px solid #ccc;
 cursor: pointer;
 -webkit-user-select:none; 
 user-select:none;
 &._self-show {
  display: block!important;
 }
 .search-module {
  position: relative;
  border-bottom: 1px solid #ccc;
  .search-text {
  width: 100%;
  height: 30px;
  text-indent: 10px;
  // border-radius: 0.5em;
  box-shadow: none;
  outline: none;
  border: none;
  // &:focus {
  // border-color: #2198f2;
  // }
  }
  .search-icon {
  position: absolute;
  top: 24%;
  right: 0.5em;
  color: #aaa;
  }
 }
 input::-webkit-input-placeholder{
  font-size: 14px;
 }
 .list-module {
  max-height: 200px;
  overflow-y: auto;
  li {
  &._self-hide {
   display: none;
  }
  margin-top: 0.4em;
  padding: 0.4em;
  &:hover {
   cursor:pointer;
   color: #fff;
   background: #00a0e9;
  }
  }
 }
 }
 .tip-nodata {
 font-size: 14px;
 padding: 10px 0;
 text-indent: 10px;
 }
</style>

父组件调用

<dropdown :item-click="dropDownClick" :isNeedSearch="true" :itemlist="itemlist"></dropdown>
import Dropdown from '@/components/dropdown.vue'
export default {
 data() {
 return {
 itemlist: {
 cur: {
  val: "",
  name: "所有产品"
 },
 data: [{
  val: "",
  name: "所有产品"
 }, {
  val: 1,
  name: "梦幻西游"
 }, {
  val: 2,
  name: "梦幻无双"
 }, {
  val: 3,
  name: "大话西游"
 }]
 },
 }
 },
 components: {
 Dropdown,
 },
 methods :{
 dropDownClick(e) {
 console.log(e.name, e.val)
 }
 }
}

默认是不带搜索框,如果需要可以传这个:isNeedSearch="true"。

ps:下面看下vue组件实践-可搜索下拉框

实践加深对vue的理解和运用有效途径,本文是基于vue的可搜索下拉框定制组件实现,在此记录.

一、效果

vue组件实践之可搜索下拉框功能

二、组件代码

dropdown.vue

<template>
 <div class="vue-dropdown default-theme" v-show-extend="show">
  <div class="search-module clearfix" v-show="itemlist.length">
   <input class="search-text" 
   @keyup='search($event)' :placeholder="placeholder" />
   <span class="glyphicon glyphicon-search search-icon"></span>
  </div>
  <ul class="list-module" v-show="length">
   <li v-for ="(item,index) in datalist" @click="appClick(item)" 
   :key="index">
    <span class="list-item-text">{{item.name}}</span>
   </li>
  </ul>
  <div class="tip__nodata" v-show="!length">{{nodatatext}}</div>
 </div>
</template>

<script>
 export default {
  data(){
   return {
    datalist:[]
   }
  },
  props:{
   'show':{//用于外部控制组件的显示/隐藏
    type:Boolean,
    default:true
   },
   'itemlist':Array,
   'placeholder':String,
   'nodatatext':String
  },
  watch:{
   itemlist:function(val){
    this.datalist = val.concat();
   }
  },
  directives:{
   'show-extend':function(el,binding,vnode){//bind和 update钩子
    let value = binding.value,searchInput = null;
    if(value){
     el.style.display='block';
    }else{//隐藏后,恢复初始状态
     el.style.display='none';
     searchInput = el.querySelector(".search-text");
     searchInput.value = '';
     vnode.context.datalist = vnode.context.itemlist;//还原渲染数据
    }
   }
  },
  methods:{
   appClick:function(data){
    this.$emit('item-click',data);
   },
   search:function(e){
    let vm = this,searchvalue = e.currentTarget.value;
    vm.datalist = vm.itemlist.filter(function(item,index,arr){
     return item.name.indexOf(searchvalue) != -1;
    });
   }
  },
  computed:{
   length:function(){
    return this.datalist.length;
   }
  }
 }
</script>

<style lang="scss" scoped>
 .vue-dropdown.default-theme {
  position: absolute;
  left:15%;
  display: none;
  width: 70%;
  margin: 0 auto;
  margin-top: 1em;
  padding: 1em;
  z-index:10;
  box-shadow: 0px 0px 10px #ccc;
  &._self-show {
   display: block!important;
  }

  .search-module {
   position: relative;
   .search-text {
    width: 100%;
    height: 30px;
    padding-right: 2em;
    padding-left:0.5em;
    border-radius: 0.5em;
    box-shadow: none;
    border: 1px solid #ccc;

    &:focus {
     border-color: #2198f2;
    }
   }

   .search-icon {
    position: absolute;
    top: 24%;
    right: 0.5em;
    color: #aaa;
   }

  }

  .list-module {
   max-height: 200px;
   overflow-y: auto;
   li {
    &._self-hide {
     display: none;
    }
    margin-top: 0.5em;
    padding: 0.5em;
    &:hover {
     cursor:pointer;
     color: #fff;
     background: #00a0e9;

    }
   }
  }
 }
 .tip__nodata {
  font-size: 12px;
  margin-top: 1em;
 }
</style>

三、组件使用

<dropdown :itemlist="itemlist" :placeholder="placeholder" 
:nodatatext="nodatatext"></dropdown>

总结

以上所述是小编给大家介绍的vue下拉菜单组件(含搜索)功能,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
javascript中DOM复选框选择用法实例
May 14 Javascript
js实现类似MSN提示的页面效果代码分享
Aug 24 Javascript
JQuery 在文档中查找指定name的元素并移除的实现方法
May 19 Javascript
jQuery实现邮箱下拉列表自动补全功能
Sep 08 Javascript
jQuery插件FusionCharts实现的3D柱状图效果实例【附demo源码下载】
Mar 03 Javascript
js处理包含中文的字符串实例
Oct 11 Javascript
JS原型继承四步曲及原型继承图一览
Nov 28 Javascript
详解基于electron制作一个node压缩图片的桌面应用
Jan 29 Javascript
微信小程序实现跳转的几种方式总结(推荐)
Apr 24 Javascript
JS自定义滚动条效果
Mar 13 Javascript
解决vue项目router切换太慢问题
Jul 19 Javascript
如何使用three.js 制作一个三维的推箱子游戏
Jul 29 Javascript
详解离线安装npm包的几种方法
Nov 25 #Javascript
vue将单页面改造成多页面应用的方法
Nov 25 #Javascript
vue下拉菜单组件(含搜索)的实现代码
Nov 25 #Javascript
Angular ui-roter 和AngularJS 通过 ocLazyLoad 实现动态(懒)加载模块和依赖
Nov 25 #Javascript
详解Vue CLI 3.0脚手架如何mock数据
Nov 23 #Javascript
详解js静态检查工具eslint配置文件
Nov 23 #Javascript
详解小程序不同页面之间通讯的解决方案
Nov 23 #Javascript
You might like
MySQL 日期时间函数常用总结
2012/06/12 PHP
php eval函数用法总结
2012/10/31 PHP
PHP面向对象编程之深入理解方法重载与方法覆盖(多态)
2015/12/24 PHP
PHP实现的折半查询算法示例
2017/10/09 PHP
关于php支持的协议与封装协议总结(推荐)
2017/11/17 PHP
Laravel框架执行原生SQL语句及使用paginate分页的方法
2018/08/17 PHP
javascript实现unicode和字符的互相转换
2007/07/18 Javascript
采用自执行的匿名函数解决for循环使用闭包的问题
2014/09/11 Javascript
node.js操作mysql(增删改查)
2015/07/24 Javascript
jquery结婚电子请柬特效源码分享
2015/08/21 Javascript
js 自带的 map() 方法全面了解
2016/08/16 Javascript
原生js实现轮播图
2017/02/27 Javascript
深入理解Node.js中的进程管理
2017/03/13 Javascript
微信小程序异步处理详解
2017/11/10 Javascript
node作为中间服务层如何发送请求(发送请求的实现方法详解)
2018/01/02 Javascript
vue全局组件与局部组件使用方法详解
2018/03/29 Javascript
对layui中表单元素的使用详解
2018/08/15 Javascript
vue表单验证你真的会了吗?vue表单验证(form)validate
2019/04/07 Javascript
nuxt配置通过指定IP和端口访问的实现
2020/01/08 Javascript
基于JS实现操作成功之后自动跳转页面
2020/09/25 Javascript
[00:36]DOTA2风云人物相约完美“圣”典 12月17日不见不散
2016/11/30 DOTA
实例解析Python中的__new__特殊方法
2016/06/02 Python
浅析Python的web.py框架中url的设定方法
2016/07/11 Python
Ubuntu下Python+Flask分分钟搭建自己的服务器教程
2019/11/19 Python
Python标准库itertools的使用方法
2020/01/17 Python
django ORM之values和annotate使用详解
2020/05/19 Python
Python获取excel内容及相关操作代码实例
2020/08/10 Python
如何在python中处理配置文件代码实例
2020/09/27 Python
英国计算机商店:Technextday
2019/12/28 全球购物
EM Cosmetics官网:由彩妆大神Michelle Phan创办的独立品牌
2020/04/27 全球购物
毕业生自我推荐
2013/11/04 职场文书
好矿嫂事迹材料
2014/01/21 职场文书
物业保安员岗位职责制度
2014/01/30 职场文书
年终晚会主持词
2014/03/25 职场文书
降消项目实施方案
2014/03/30 职场文书
2014年校务公开工作总结
2014/12/18 职场文书