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 相关文章推荐
json格式的时间显示为正常年月日的方法
Sep 08 Javascript
IE6/IE7中JavaScript json提示缺少标识符、字符串或数字问题处理
Dec 16 Javascript
有效提高JavaScript执行效率的几点知识
Jan 31 Javascript
JS实现跟随鼠标闪烁转动色块的方法
Feb 26 Javascript
JavaScript实现把rgb颜色转换成16进制颜色的方法
Jun 01 Javascript
整理Javascript数组学习笔记
Nov 29 Javascript
JS弹性运动实现方法分析
Dec 15 Javascript
Bootstrap中datetimepicker使用小结
Dec 28 Javascript
jquery代码规范让代码越来越好看
Feb 03 Javascript
利用纯js + transition动画实现移动端web轮播图详解
Sep 10 Javascript
Vue中关闭弹窗组件时销毁并隐藏操作
Sep 01 Javascript
浅谈react路由传参的几种方式
Mar 23 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简单的伪原创程序,配合商城采集用的
2010/10/12 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十五)
2014/06/30 PHP
windows8.1下Apache+Php+MySQL配置步骤
2015/10/30 PHP
ThinkPHP实现附件上传功能
2017/04/27 PHP
php无限级评论嵌套实现代码
2018/04/18 PHP
一个加密JavaScript的开源工具PACKER2.0.2
2006/11/04 Javascript
firefox下对ajax的onreadystatechange的支持情况分析
2009/12/14 Javascript
基于JavaScript 下namespace 功能的简单分析
2013/07/05 Javascript
处理文本部分内容的TextRange对象应用实例
2014/07/29 Javascript
js显示文本框提示文字的方法
2015/05/07 Javascript
jquery+正则实现统一的表单验证
2015/09/20 Javascript
bootstrap输入框组代码分享
2016/06/07 Javascript
使用React实现轮播效果组件示例代码
2016/09/05 Javascript
Extjs让combobox写起来简洁又漂亮
2017/01/05 Javascript
vue+mockjs模拟数据实现前后端分离开发的实例代码
2017/08/08 Javascript
VsCode新建VueJs项目的详细步骤
2017/09/23 Javascript
jquery如何实现点击空白处隐藏元素
2017/12/05 jQuery
解决js ajax同步请求造成浏览器假死的问题
2018/01/18 Javascript
vue2 全局变量的设置方法
2018/03/09 Javascript
vue.js仿hover效果的实现方法示例
2019/01/28 Javascript
微信公众号网页分享功能开发的示例代码
2020/05/27 Javascript
如何在node环境实现“get数据解析”代码实例
2020/07/03 Javascript
Vue 实现可视化拖拽页面编辑器
2021/02/01 Vue.js
[01:43]3.19DOTA2发布会 三代刀塔人第三代
2014/03/25 DOTA
[03:20]2015国际邀请赛全明星表演赛
2015/08/08 DOTA
Python中的测试模块unittest和doctest的使用教程
2015/04/14 Python
Python编程实现生成特定范围内不重复多个随机数的2种方法
2017/04/14 Python
python 实现 hive中类似 lateral view explode的功能示例
2020/05/18 Python
HTML5时代CSS设置漂亮字体取代图片
2014/09/04 HTML / CSS
优质服务活动实施方案
2014/05/02 职场文书
教师党员先进性教育自我剖析材料思想汇报
2014/09/24 职场文书
2014年公司工作总结
2014/11/22 职场文书
最新农村养殖致富:资金投入较低的创业项目有哪些?
2019/09/26 职场文书
《中国机长》观后感:敬畏生命,敬畏职责
2019/11/12 职场文书
Python Pandas知识点之缺失值处理详解
2021/05/11 Python
Python requests用法和django后台处理详解
2022/03/19 Python