vue下拉菜单组件(含搜索)的实现代码

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

效果图:

子组件 dropdown.vue

<template>
  <div class="vue-dropdown default-theme">
   <div class="cur-name" @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" 。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Vue用自定义指令完成一个下拉菜单(select组件)

    这次分享的是关于Vue自定义指令的使用方法,学习完基础后我们再来实战完成一个下拉列表,废话不多说,直接上干货 基本用法 //全局注册 Vue.directive('my-directive', { // 指令选项 }) // 局部注册 var app = new Vue({ el: '#app' directives: { 'my-directive': { // 指令选项 } }) 相信对Vue比较熟悉的人看完都知道,directive的写法与组件 基本类似,只是方法名由component改为

  • Vue.js 递归组件实现树形菜单(实例分享)

    最近看了 Vue.js 的递归组件,实现了一个最基本的树形菜单. 项目结构: main.js 作为入口,很简单: import Vue from 'vue' Vue.config.debug = true import main from './components/main.vue' new Vue({ el: '#app', render: h => h(main) }) 它引入了一个组件 main.vue: <template> <div class="tree-m

  • vue-router+vuex addRoutes实现路由动态加载及菜单动态加载

    此案例主要实现了一个功能是,在vue实例首次运行时,在加载了login和404两个路由规则,登录成功后,根据登录用户角色权限获取该角色相应菜单权限,生成新的路由规则添加进去. 做过后台管理系统都一定做过这个功能,在对菜单权限进行粗粒度权限控制的时候,通过角色获取菜单后,异步生成菜单,所以一开始拿到需求的时候,我也以为这和平常的没什么不同,不过做起来就发现了很多问题, 1.vue-router的实例,在new vue实例的时候,就加载了,且必须加载,这个时候,登录路由一定要加载,可是这个时候没有登

  • Vue实现自定义下拉菜单功能

    先看例子,后面有对用到的知识点的总结 效果图: 实现代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>组件练习</title> <link rel="stylesheet" type="text/css" href="component.c

  • Vue.js下拉菜单组件使用方法详解

    本文实例为大家分享了Vue.js下拉菜单组件的具体实现代码,供大家参考,具体内容如下 效果 #### 入口页面 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scal

  • 基于vue.js实现侧边菜单栏

    侧边菜单栏应该是很多项目里必不可少的 自己手写了一个 下面是效果图 下面就说一下实现的过程 还是比较简单的 首先导入一下需要的文件 <link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.min.css" rel="external nofollow" > <link rel="stylesheet" typ

  • Vue.js组件tree实现无限级树形菜单

    分享一段用 <ul>和<li>标签实现tree的代码,可能写的不是很好,如果大家有更好的希望分享下. 代码看这里喽: html代码: <div class="tree"> <nav class='navbar'> <ul class='nav nav-stacked'> <template v-for='item in menus'> <li role='presentation' v-if='!item.c

  • vue实现多级菜单效果

    本次记录基于iview3框架实现多级菜单+vue router实现页面切换 方法一: 使用Tree 树形控件,官方文档 以官方demo为例,数据中添加URL属性,用于路由跳转,正式项目中该tree控件的数据由后端给出,需要注意的是后端给出的URL跳转地址最前一定要看清有没有"/" ,如果没有自己手动加或后端改,没有这个"/" 斜杠会导致路由跳转失败. 思路:根据官方文档里面写用on-select-change事件返回当前已选中的节点数组.当前项,就利用返回的当前项数

  • vue.js实现二级菜单效果

    本文实例为大家分享了vue.js实现二级菜单效果的具体代码,供大家参考,具体内容如下 主要是对二级菜单和当前点击的处理: 点击导航时,如果有二级菜单,就切换二级菜单显示状态(显示或者关闭),如果没有二级菜单,就变色,表示页面处于当前位置,并且导航中最多只能有一个菜单变色. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title&g

  • 浅谈Vue.js中如何实现自定义下拉菜单指令

    我们利用  Vue.js 的自定义指令能力,来实现一个自定义下拉菜单功能.描述如下: 点击按钮,弹出下拉菜单. 点击下拉菜单之外的区域,关闭下拉菜单. 1基础版 html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="styleshee

随机推荐