vue 封装组件(以button和select为例)

Button

目录文件


首先创建button文件夹,新建index.vue文件
index.vue

<template>
   <div :class="type == 'Default'?'btn default':type == 'primary'?'btn primary':type == 'danger'?'btn danger':'btn default'"
    :style="size == 'Default'? '100px;padding:14px 0' : size =='mini'?'60px;padding:10px 0':'100px;padding:14px 0'">
      <span>
          <slot></slot>
      </span>
   </div>
</template>

<script>
//import common from './common'
export default {
  name:'L-button',
   props:{
        size:String,
        type:String,
        default:"Default"
    },
};
</script>

<style lang='stylus'>
   .btn{
        color:#fff;
        text-align: center;
        line-height:1;
        // padding:5px 10px
        border-radius:5px;
        
     }
     .default{
        background: red; 
     }
 
    .primary{
        background: yellow;
     }
 
    .danger{
        background: #ccc;
     }
</style>

在button同级目录下创建index.js 用来注册多个组件

index.js

    import Lbutton  from "./button/index.vue"
    import LSelect from "./select"
    const components = [
        Lbutton,
        LSelect
    ]
    const install = (vue)=>{
        for (let key in components){
            vue.component(components[key].name,components[key])
        }
    }
    export default {
        install,
        <!-- 按需加载 -->
        Lbutton,
        LSelect
    }

最后在main.js中引用

    import UI from "./components" // UI为任意定义的
    Vue.use(UI)

应用组件

    <L-button type="danger" size="mini">asdas</L-button>

效果:

select

index.vue
简易select 应用时不需要绑定v-model,支持多选单选 和 清空,change方法可以获取到当前的选中值

    <template>
      <div class="l-select">
        <div v-if="!multiple" class="l-select-content">
            <input class="select-input" readonly  style="padding:0 15px" type="text" v-model="selectModel" @focus="focus" @blur="blur">
            <ul v-show="show">
                <li class="l-select-li"  @click.stop="clickHandler(item,index,$event)" style="line-height:30px" v-for="(item,index) in data?data:options" :key="item.id">{{item.value}}</li>
            </ul>
        </div>
     <!-- multiple -->
         <div v-if="multiple" class="l-select-content">
            <div class="input" style="overflow:hidden;background:#fff;cursor:pointer" @click.stop="MulclickHandler" >
                <div style="1000px;padding:5px 10px;height:100%">
                    <div class="l-select-wrap"
                        v-for="(item) in multipleArr" :key="item.id"
                    >
                    {{item.value}}
                    </div>
                </div>
                 <div style="30px;height:95%;background:#fff;float:right;position:absolute;top:0;right:0px;border-radius:5px;margin:1px">
                        <i @click.stop="clearVal" class="fa fa-close" style="position:absolute;top:35%;right:10px"></i>
                    </div>
            </div>
            <ul v-show="show">
                <li class="l-select-li"  @click.stop="clickHandler(item,index,$event)" style="line-height:30px" v-for="(item,index) in data?data:options" :key="item.id">{{item.value}}</li>
            </ul>
        </div>
      </div>
    </template>
    
    <script>
    //import common from './common'
    export default {
      name:'L-select',
      props:{
        data:{
            type:Array 
        },
        multiple:Boolean
        // value:String
      },
      data() {
        return {
            showUL:true,
            selectModel:"",
            list:[],
            show:false,
            multipleArr:[],
            selectModelmul:'',
            docArr:[],
            options:[{id:1,label:'label',value:"value"},{id:2,label:'label',value:"value"}]
         };
      },
      watch:{
          selectModel(newval){
             this.$emit("change",this.selectId)
             this.closeUL()
          },
          multipleArr(newval){
             this.$emit("change",newval)
            //  this.show=false
          }
      },
    
      created(){ },
      mounted(){
          document.addEventListener("click",this.docClick)
          this.docArr = document.getElementsByClassName("l-select-li")
       },
      methods: {
        docClick(e){
            if(e.target.className!="select-input" && this.show){
                this.closeUL()
            }
            
        },
        clearVal(){
            this.multipleArr=[]
            this.selectModel=""
             this.docArr.forEach(item=>{
                item.style.color="#000"
                item.style.fontWeight="100"
            })  
        },
        focus(){
            this.show=true
        },
        MulclickHandler(){
            this.show=true
        },
        closeUL(){
            this.show=false
           
        },
        clickHandler(item,index,e){
            if(this.multiple){
                if(e.target.style.color=="rgb(37, 135, 255)"){
                    e.target.style.color="#000"
                    e.target.style.fontWeight="100"
                }else{
                    e.target.style.color="rgb(37, 135, 255)"
                    e.target.style.fontWeight="bold"
                }
                if(this.multipleArr.indexOf(item) == -1){
                    this.multipleArr.push(item)
                }else{
                    this.multipleArr.splice(this.multipleArr.indexOf(item),1)
                }
                
            }else{
                this.selectModel=item.value
                this.selectId=item
            }
        },
       }
    };
    </script>
    
    <style lang='stylus'>
    .l-select{
        180px;
        height:40px  
      .l-select-content{
        width 100%;
        height:100%;
        position:relative
        input{
            100%;
            height:100%;
            border-radius:5px
            border:1px solid black
        }
        input:focus{
            border:none
            border-radius:5px
        }
        .input{
            100%;
            height:100%;
            border-radius:5px
            border:1px solid black
        }
        .input:focus{
            border:none
            border-radius:5px
        }
    
      }
      ul{
          position:absolute;
          180px;
          max-height:200px;
          overflow:auto;
          background:#fff;
          box-shadow:0 0 5px 0;
          left:0;
          top:45px;
          padding:10px 15px
      }
      li{
          list-style none
      }
      .l-select-wrap{
          margin-right:5px;
          background:#f2f2f2;
          height:100%;
          float:left;
          line-height:2;
          border-radius:5px;
          color:#909399;
          padding:0 10px
      }
    
    }
    </style>

同button在index中注册组件。

应用:

    <L-select multiple :data="data" @change="value"></L-select>
    <L-select multiple :data="data" @change="value"></L-select>
    //data为需要传递的数据 change用来获取选中的值
    //例如:data:[{id:1,label:'label1',value:"valuge1"},{id:2,label:'label1',value:"value1"},{id:3,label:'label1',value:"vaasdlue1"},{id:4,label:'label1',value:"vdfalue1"}]
    
    value(val){
      console.log(val,"ssssssssssss")
    }

使用效果:多选:


使用效果:单选:

原文地址:https://www.cnblogs.com/FormerWhite/p/15016051.html