【IMWeb训练营作业】用vue编写的自定义select

首先放上效果图(样式改了下,仿vue.js官网)
这里写图片描述

这次任务用到了组件,将输入框与与列表封装为两个组件,主要注意组件作用域是独立的,传值用到,props$emit

输入框组件:
主要定义了,点击输入框列表弹出,而且加了渐变效果

Vue.component("custom-select",{
    data:function(){
        return {
            selectShow:false,
            val:""
        }
    },
    props:["btn","list"],
    template:`
        <section class="wrap">
            <div class="searchIpt">
                <div class="search">
                    <div>
                        <input type="text" 
                            class="keyword" 
                            @click="selectShow = !selectShow" 
                            v-model="val"
                        />
                        <input type="button" :value="btn" class="btn"/>
                        <span></span>
                    </div>
                </div>
                <transition name="fade">
                    <custom-list 
                        v-show="selectShow"
                        :list="list"
                        :val="val"
                        @receive="changeValueHandle"
                    ></custom-list>
                </transition>
            </div>
        </section>`,
    methods:{
        changeValueHandle(value){
            this.val = value;
        }
    }
})

列表组件:
增加了输入时对列表值得筛选

Vue.component('custom-list',{
    props:["list","val"],//传入列表,正在输入值
    template:
        `<ul class="list">
            <li v-for="(item,index) of computedList" @click="selectValueHandle(item,index)">{{item}}</li>
        </ul>`,
    methods:{ //点击时抛出事件
        selectValueHandle(item,index){
            this.$emit("receive",item,index)
        }
    },
    computed:{ 
        computedList(){ //根据正在输入值过滤
            var val = this.val;
            return this.list.filter(function(item){
                return item.toLowerCase().indexOf(val.toLowerCase())!==-1;
            })
        }
    }
})

最后放上整体代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="./vue.js"></script>
    <style>
        input{padding: 0;}
        ul,li{margin: 0;padding: 0;list-style: none;}
        body{font-size:15px;font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;}

        .wrap{
            width: 260px;
        }
        input{
            height: 30px;
            line-height: 30px;
            box-sizing: border-box;
            border-radius: 15px;
            border:1px solid #e3e3e3;
            outline: none;
            transition: border-color 0.2s ease;         
        }
        .keyword{
            padding: 0 15px 0 30px;
            color: #2c3e50; 
            background: url(./img/search.png) 8px 5px no-repeat;
            background-size: 20px;

        }
        .keyword:focus{
            border-color: #42B983;
        }
        .btn{
            padding: 0 15px;
            line-height: 28px;
            background-color: #fff;
            cursor: pointer;
        }
        .btn:hover{
            border-color: #42B983;
        }
        .list{
            padding: 0 15px;
            font-size: 0.85em;
            -webkit-font-smoothing: antialiased; 
            line-height: 1.8em;
            color: #2c3e50;
        }
        .list li:hover{
            color: #42B983;
            cursor: pointer;
        }
        .fade-enter-active,.fade-leave-active{
            transition: opacity .5s;
        }
        .fade-enter,.fade-leave-active{
            opacity: 0;
        }
    </style>
</head>
<body>
    <div id="app">
        <custom-select btn="查询" :list="list1"></custom-select>
    </div>
    <script>
        //选择框组件---当点击输入框时,列表弹出,添加了渐变效果
        Vue.component("custom-select",{
            data:function(){
                return {
                    selectShow:false,
                    val:""
                }
            },
            props:["btn","list"],
            template:`
                <section class="wrap">
                    <div class="searchIpt">
                        <div class="search">
                            <div>
                                <input type="text" 
                                    class="keyword" 
                                    @click="selectShow = !selectShow" 
                                    v-model="val"
                                />
                                <input type="button" :value="btn" class="btn"/>
                                <span></span>
                            </div>
                        </div>
                        <transition name="fade">
                            <custom-list 
                                v-show="selectShow"
                                :list="list"
                                :val="val"
                                @receive="changeValueHandle"
                            ></custom-list>
                        </transition>
                    </div>
                </section>`,
            methods:{
                changeValueHandle(value){
                    this.val = value;
                }
            }
        })

        //列表组件
        Vue.component('custom-list',{
            props:["list","val"],//传入列表,正在输入值
            template:
                `<ul class="list">
                    <li v-for="(item,index) of computedList" @click="selectValueHandle(item,index)">{{item}}</li>
                </ul>`,
            methods:{ //点击时抛出事件
                selectValueHandle(item,index){
                    this.$emit("receive",item,index)
                }
            },
            computed:{ 
                computedList(){ //根据正在输入值过滤
                    var val = this.val;
                    return this.list.filter(function(item){
                        return item.toLowerCase().indexOf(val.toLowerCase())!==-1;
                    })
                }
            }
        })

        new Vue({
            el:"#app",
            data:{
                list1:['html+css','html5+css3','javascript','angular','react','vue','jquery','nodejs','vue2']
            }
        })
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值