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 相关文章推荐
用js模拟JQuery的show与hide动画函数代码
Sep 20 Javascript
深入探密Javascript数组方法
Jan 08 Javascript
javascript密码强度校验代码(两种方法)
Aug 10 Javascript
谈谈JavaScript中function多重理解
Aug 28 Javascript
Jquery判断form表单数据是否变化
Mar 30 Javascript
Javascript实现汉字和拼音互转的终极方案
Oct 19 Javascript
BootStrap网页中代码显示用法详解
Oct 21 Javascript
jQuery中ztree 点击文本框弹出下拉框的实例代码
Feb 05 Javascript
JavaScript实现二维坐标点排序效果
Jul 18 Javascript
使用Angular CLI进行Build(构建)和Serve详解
Mar 24 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
Apr 30 Javascript
深入了解JavaScript词法作用域
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
PHP实现检测客户端是否使用代理服务器及其匿名级别
2015/01/07 PHP
mysql desc(DESCRIBE)命令实例讲解
2016/09/24 PHP
让你的网站可编辑的实现js代码
2009/10/19 Javascript
nodejs 实现模拟form表单上传文件
2014/07/14 NodeJs
5个JavaScript经典面试题
2014/10/13 Javascript
javascript实现节点(div)名称编辑
2014/12/17 Javascript
js实现百度联盟中一款不错的图片切换效果完整实例
2015/03/04 Javascript
Angularjs过滤器使用详解
2016/05/25 Javascript
JavaScript制作颜色反转小游戏
2016/09/25 Javascript
JS实现用户注册时获取短信验证码和倒计时功能
2016/10/27 Javascript
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
2016/12/14 Javascript
Bootstarp基本模版学习教程
2017/02/01 Javascript
微信小程序 参数传递实例代码
2017/03/20 Javascript
JavaScript实现简单的星星评分效果
2017/05/18 Javascript
JS/jQuery实现DIV延时几秒后消失或显示的方法
2018/02/12 jQuery
Vue引入sass并配置全局变量的方法
2018/06/27 Javascript
vue使用v-for实现hover点击效果
2018/09/29 Javascript
Node.js实现简单管理系统
2019/09/23 Javascript
vue父子组件的通信方法(实例详解)
2019/11/10 Javascript
JavaScript代码简化技巧实例解析
2020/09/09 Javascript
详细分析JavaScript中的深浅拷贝
2020/09/17 Javascript
详解微信小程序「渲染层网络层错误」的解决方法
2021/01/06 Javascript
Python中tell()方法的使用详解
2015/05/24 Python
深入浅析ImageMagick命令执行漏洞
2016/10/11 Python
Python中turtle作图示例
2017/11/15 Python
Python实现的插入排序,冒泡排序,快速排序,选择排序算法示例
2019/05/04 Python
Python如何实现转换URL详解
2019/07/02 Python
django将网络中的图片,保存成model中的ImageField的实例
2019/08/07 Python
pip安装tensorflow的坑的解决
2020/04/19 Python
使用PyQt5实现图片查看器的示例代码
2020/04/21 Python
德国低价购买灯具和家具网站:Style-home.de
2016/11/25 全球购物
C/C++程序员常见面试题一
2012/12/08 面试题
医院学雷锋活动策划方案
2014/02/15 职场文书
俞敏洪励志演讲稿
2014/04/29 职场文书
创业女性典型材料
2014/05/02 职场文书
劳动者解除劳动合同通知书
2015/04/16 职场文书