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

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

以上是 vue组件实践之可搜索下拉框功能 的全部内容, 来源链接: utcz.com/z/350908.html

回到顶部