首页 > 编程 > JavaScript > 正文

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

2019-11-19 12:28:52
字体:
来源:转载
供稿:网友

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

效果图:

子组件 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的可搜索下拉框定制组件实现,在此记录.

一、效果

二、组件代码

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下拉菜单组件(含搜索)功能,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表