提示:关于简单的常用组件的封装收录在我的专题 “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(不熟悉的小伙伴同样可以评论留言 我会单独出一期)