elementui实现抽屉效果_如何给element添加⼀个抽屉组件的
⽅法步骤
近来因为业务需要,对⽐iview和element库,发现element确实要⽐实习期间使⽤的iview强⼤点,尤其⽂档更为友好,但是iview的组件功能更多⼀点,⽐如分割线和抽屉组件
今天特意⼿写⼀个抽屉组件,⽅便⾃⼰使⽤element库,写好的组件我已经放在我的githup了, 点这⾥
⼀、实践
1.分析
⼀个抽屉组件的z-index必定是在当前页⾯之上的,在抽屉主体之外的区域还会有⼀层半透明的遮罩层,知道这些就很容易了
// drawer.vue
.drawer {
position: absolute;
height: 100vh;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 1000000 !important;
}
.drawer .drawer_body {
height: 100%;
position: absolute;
z-index: 1000001;
background-color: #fff;
}
.mask {
height: 100vh;
width: 100vw;
position: absolute;
z-index: 1000000;
top: 0;
left: 0;
background-color: #000;
opacity: 0.5;
}
现在已经是我们想要的样⼦了,接下来是给drawer_body添加样式
作为⼀个灵活的组件库,我们希望样式是可以随时定制的,所以,接下要添加的样式都 使⽤props
动态绑定的
参考iview的样式,除了抽屉的宽度,还需要设置抽屉的⽅向,当我们需要抽屉时让它显⽰出来,不需要时隐藏它,或者为了更加显眼,甚⾄给抽屉更换背景⾊......,这些都是可以实现的,看下⾯的代码
export default {
props: {
// 是否显⽰drawer
drawerVisible: Boolean,
// drawer⽅向
element表格横向滚动条
direction: {
type: String,
validator(val) {
return ["right", "left"].indexOf(val) !== -1;
}
},
// drawer宽度
width: {
type: Number,
default: 400
},
// drawer背景⾊
background: {
type: String,
default: "#ffffff"
},
// 是否显⽰遮罩层
mask: {
type: Boolean,
default: true
}
}
};
对于宽度和背景⾊,你还需要额外的处理下
class="drawer_body"
:
>drawer
你只需在使⽤的地⽅引⼊组件,然后提供你想修改的props值
//index.vue
...
显⽰抽屉
:drawerVisible="drawerVisible"
direction="right"
:mask="true"
background="aquamarine"
>
export default {
data() {
return {
drawerVisible: false
};
},
methods:{
/
/ 打开抽屉
visible() {
this.drawerVisible = true;
}
}
}
2.关闭抽屉
在点击遮罩层的时候,我们希望可以关闭已经打开的抽屉组件,这⾥如果你直接修改⽗组件传过来的drawerVisible值,会报错如下
vue.esm.js:629 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten
whenever the parent component re-renders. Instead, use a data or computed property based on the
prop's value. Prop being mutated: "drawerVisible"
这是因为vue是单向数据流的,如果想改变⽗元素的值,必须使⽤监听事件的⽅式,但是2.3.0之后添加了.sync修饰符,所以,正确的做法是使⽤.sync修饰符
...
class="drawer_body"
:
>
...
methods: {
close() {
this.$emit("update:drawerVisible", false);
}
}
另外,我们还希望在关闭抽屉组件时,我们可以监听到这个事件然后做出反应
methods: {
close() {
this.$emit("update:drawerVisible", false);
this.$emit("close");
}
}
此时需要在抽屉组件上添加
:drawerVisible.sync="drawerVisible"
@close="close"
>
methods:{
close(){
// 关闭抽屉组件时你要做的事
}
}
2.动画
动画是UI的灵魂,所以接下来给抽屉组件的显⽰和隐藏添加动画,我们使⽤transition的css动画做动画过度效果//drawer.vue
class="drawer_body"
v-if="drawerVisible"
:
>drawer
/*
* ...
*这⾥省略了写过的样式
*/
.
slide-right-enter-active,
.slide-right-leave-active,
.slide-left-enter-active,
.slide-left-leave-active {
will-change: transform;
transition: transform 300ms;
position: absolute;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.
slide-right-enter,
.slide-right-leave-active {
transform: translate(-100%, 0);
}
.slide-left-leave-active,
.slide-left-enter {
transform: translate(100%, 0);
}
虽然现在已经完全实现了抽屉的功能,但是本着更加精美的原则,我还打算使⽤slot给它添加辩题和页脚3.添加标题
标题solt的name值是header
添加标题的⽬的是为了让抽屉组件看起来更加清楚,此外,除了添加标题,我还想添加个关闭按钮
// 需要添加⼏个props属性