手把手教你简单的“抽屉”组件的封装

提示:关于简单的常用组件的封装收录在我的专题 “vue常见的组件封装” 里面。


提示:以下是本篇文章正文内容,下面案例可供参考,大佬也可以指出其中的不足之处,哈哈哈。

一、效果图

1、说明

抽屉打开的方向有 上下左右 4种

2、示例图

左边打开
在这里插入图片描述右边打开
在这里插入图片描述
下面打开
在这里插入图片描述

上面打开
在这里插入图片描述

二、准备工作

1、环境配置准备

省略(不清楚的小伙伴可以看我的 手把手教你封装按钮组件 的准备工作和这个差不多)

2、需求分析

2.1、需要抽屉随使用者的偏好 设置上下左右打开

2.2、可以自定义样式。

2.3、使用插槽

三、代码实现

1、基础样式实现

//drawer
<template>
  <div>
    <div class="title">
       <div>{{ title }}</div> //drawer的title
    </div>
  </div>
</template>
.title{
   display: flex;
   padding: 20px;
    div:nth-child(1){
        flex: 1;
        text-align: left;
    }
}

2、编写上下左右的基础样式

/*定义上下打开的公共样式*/
.cl{
    width: 100%;
    height: 300px;
    position: absolute;
}
/*定义左右打开的基础样式*/
.rw{
    height: calc(100vh);
    width: 300px;
    position: absolute;
}
/*定义公共背景颜色*/
@background-color:#d1d1d1;
/*从上到下*/
.ttb{
    .cl();
    top:0px;
    background-color: @background-color;
}
/*从下到上*/
.btt{
    .cl();
    bottom:0px;
    background-color: @background-color;

}
/*从右到左*/
.rtl{
    .rw();
    right: 0px;
    background-color: @background-color;
}
/*从左到右*/
.ltr{
    .rw();
    left: 0;
    background-color: @background-color;
}

3、定义props动态绑定drawer样式

<template>
  <div :class="direction" :style="style" v-show="drawer">
    <div class="title">
       <div>{{ title }}</div>
    </div>
  </div>
</template>

<script>
export default{
    name:'can-drawer',
    props:{
        title:{
            type:String,
        },
        drawer:{
            type:Boolean,
            default:false
        },
        direction:{
            type:String,
            default:'btt',
            validator(value) {
                // The value must match one of these strings
                return ['ttb', 'rtl', 'ltr','btt'].includes(value)
            }
        },
        style:{
            type:String,
            default:''
        }
    },
}
</script>

4、给drawer打开加入动态效果

这里我们采用 css3 的方式,当然也可以用 js 控制

.cl{
    width: 100%;
    height: 300px;
    position: absolute;
    animation-duration: 0.5s; /*规定动画时间0.5秒*/
}

.rw{
    height: calc(100vh);
    width: 300px;
    position: absolute;
    animation-duration: 0.5s; /*规定动画时间0.5秒*/
}

@background-color:#d1d1d1;

.ttb{
    .cl();
    top:0px;
    animation-name: ttb; /*规定动画名称*/
    background-color: @background-color;
}
.btt{
    .cl();
    bottom:0px;
    animation-name: btt; /*规定动画名称*/
    background-color: @background-color;

}

.rtl{
    .rw();
    right: 0px;
    animation-name: rtl; /*规定动画名称*/
    background-color: @background-color;
}

.ltr{
    .rw();
    left: 0;
    animation-name: ltr; /*规定动画名称*/
    background-color: @background-color;
}

5、给drawer加入插槽

  <div :class="direction" :style="style" v-show="drawer">
    <div class="title">
       <div>{{ title }}</div>
    </div>
    //加入插槽
    <template>
        <div>
            <slot></slot>
        </div>
    </template>
  </div>
</template>

6、使用组件drawer

<template>
  <div id="app">
    <can-drawer 
      title="这是title"
      :drawer="drawer" 
      :direction="direction" 
    >
      <button>haha</button>
    </can-drawer>
    <button @click="openDrawer" >打开drawer</button>
  </div>
</template>

<script>
//引入组件
  import canDrawer from './components/drawer.vue'
  export default{
    components:{
      canDrawer
    },
    data(){
      return{
        drawer:false,//默认drawer为关闭状态
        direction:'rtl',//ttb从上到下
      }
    },
    methods:{
    //定义自定义点击事件 打开drawer
      openDrawer(){
        this.drawer = true
      }
    }
  }
</script>

<style lang="less">
html{
  padding: 0;
  margin: 0;
}
</style>

四、完整代码

1、drawer

<template>
  <div :class="direction" :style="style" v-show="drawer">
    <div class="title">
       <div>{{ title }}</div>
    </div>
    <template>
        <div>
            <slot></slot>
        </div>
    </template>
  </div>
</template>

<script>
export default{
    name:'can-drawer',
    props:{
        title:{
            type:String,
        },
        drawer:{
            type:Boolean,
            default:false
        },
        direction:{
            type:String,
            default:'btt',
            validator(value) {
                // The value must match one of these strings
                return ['ttb', 'rtl', 'ltr','btt'].includes(value)
            }
        },
        style:{
            type:String,
            default:''
        }
    },
}
</script>

<style lang="less" scoped>
.title{
   display: flex;
   padding: 20px;
    div:nth-child(1){
        flex: 1;
        text-align: left;
    }
}
.cl{
    width: 100%;
    height: 300px;
    position: absolute;
    animation-duration: 0.5s;
}

.rw{
    height: calc(100vh);
    width: 300px;
    position: absolute;
    animation-duration: 0.5s;
}

@background-color:#d1d1d1;

.ttb{
    .cl();
    top:0px;
    animation-name: ttb;
    background-color: @background-color;
}
.btt{
    .cl();
    bottom:0px;
    animation-name: btt;
    background-color: @background-color;

}

.rtl{
    .rw();
    right: 0px;
    animation-name: rtl;
    background-color: @background-color;
}

.ltr{
    .rw();
    left: 0;
    animation-name: ltr;
    background-color: @background-color;
}

@keyframes btt {
   0% {bottom:-100%;}
   100% {bottom: 0%;}
}

@keyframes ttb {
   0% {top:-100%;}
   100% {top: 0%;}
}

@keyframes rtl {
   0% {right:-100%;}
   100% {right: 0%;}
}

@keyframes ltr {
   0% {left:-100%;}
   100% {left: 0%;}
}
</style>

总结

1、主要还是组件之间的通信(不熟悉的小伙伴欢迎评论留言 我会单独出一期组件之间的通信)
2、这一点很重要就是在css中采用的是css预处理器less(不熟悉的小伙伴同样可以评论留言 我会单独出一期)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值