vue自定义抽屉组件
<template>
<div class="drawer">
<div :class="maskClass" @click="closeByMask"></div>
<div :class="mainClass" :style="mainStyle" class="main">
<div class="drawer-head">
<span>{{ title }}</span>
<span
v-show="closable"
class="close-btn"
@click="closeByButton"
>x</span>
</div>
<div class="drawer-body" :style="bodyStyle">
<slot />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'drawer',
props: {
// 是否打开
display: {
type: Boolean
},
// 标题
title: {
type: String,
default: '标题'
},
// 是否显示关闭按钮
closable: {
type: Boolean,
default: true
},
// 是否显示遮罩
mask: {
type: Boolean,
default: true
},
// 是否点击遮罩关闭
maskClosable: {
type: Boolean,
default: true
},
// 宽度
width: {
type: String,
default: '400px'
},
// 高度
height: {
type: String,
default: '75%'
},
// 是否在父级元素中打开
inner: {
type: Boolean,
default: false
}
},
computed: {
maskClass: function () {
return {
'mask-show': this.mask && this.display,
'mask-hide': !(this.mask && this.display),
inner: this.inner
}
},
mainClass: function () {
return {
'main-show': this.display,
'main-hide': !this.display,
inner: this.inner
}
},
mainStyle: function () {
return {
width: this.width,
height: this.height,
bottom: this.display ? '0' : `-${this.height}`,
borderTop: this.mask ? 'none' : '1px solid #eee'
}
},
bodyStyle: function () {
return {
height: this.height
}
}
},
mounted () {
if (this.inner) {
let box = this.$el.parentNode
box.style.position = 'relative'
}
},
methods: {
closeByMask () {
this.maskClosable && this.$emit('update:display', false)
},
closeByButton () {
this.$emit('update:display', false)
}
}
}
</script>
<style lang="less" scoped>
.drawer {
.mask-show {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 10;
background-color: rgba(0, 0, 0, 0.5);
opacity: 1;
transition: opacity 0.5s;
}
.mask-hide {
opacity: 0;
transition: opacity 0.5s;
}
.main {
position: fixed;
z-index: 10;
bottom: 0;
height: 100%;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
background: #f7f7f7;
transition: all 0.5s;
}
.main-show {
opacity: 1;
}
.main-hide {
opacity: 0;
}
.inner {
position: absolute;
}
.drawer-head {
display: flex;
justify-content: space-between;
align-items: center;
height: 50px;
padding: 20px;
box-sizing: border-box;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
font-size: 16px;
font-weight: bold;
background: #fff;
position: relative;
border-bottom: 1px solid #eee;
.close-btn {
font-size: 24px;
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
display: inline-block;
cursor: pointer;
}
}
.drawer-body {
// padding: 20px;
font-size: 14px;
overflow: auto;
}
}
</style>
import drawer from './drawer' components: { drawer }, display: true,
drawerWidth: '100%',
drawerHeight: '500px', <el-button type="primary" @click="display = !display">{{display?'close': 'open'}}</el-button>
<drawer title="我是标题" :display.sync="display" :width="drawerWidth" :height="drawerHeight">
<div>123</div>
</drawer>
cnpm install stylus-loader css-loader style-loader --save-dev
cnpm install less less-loader --save-dev
第二种方案:
<template>
<div class="drawer">
<button @click="clickBtn">点击</button> <div class="background" v-if="open" @click.self="closeDrop">
<div class="drop" :class="{ active: isActive, close: isClose }">drop</div>
</div>
</div>
</template> <script>
export default {
name: 'HelloWorld',
props: {},
data () {
return {
open: false,
isActive: false,
isClose: false
}
},
methods: {
clickBtn () {
this.open = true
this.isActive = true
this.isClose = false
},
closeDrop () {
this.isClose = true
setTimeout(() => {
this.open = false
}, 200)
}
}
}
</script> <style scoped lang="scss">
.background {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba($color: #000000, $alpha: 0.5);
.drop {
width: 0px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
background: #fff;
}
// 开
.active {
animation: opendoor 0.3s normal forwards;
}
@keyframes opendoor {
from {
width: 0;
}
to {
width: 45%;
}
}
// 关
.close {
animation: close 0.3s normal forwards;
}
@keyframes close {
0% {
width: 45%;
}
100% {
width: 0;
opacity: 0;
}
}
}
</style>
vue自定义抽屉组件的更多相关文章
- vue自定义全局组件(自定义插件)
有时候我们在做开发的时候,就想自己写一个插件然后就可以使用自己的插件,那种成就感很强.博主最近研究element-ui和axios的时候,发现他们是自定义组件,但是唯一有一点不同的是,在用elemen ...
- vue 自定义报警组件
1.自定义报警组件 Alarm.vue <!-- 报警 组件 --> <template> <div class="alarm"> <!- ...
- vue自定义select组件
1.目的 看了很多element-ui的源码,决定自己实现一个简单的select组件,遇到的几个难点,便记录下来. 2.难点一 element-ui中的select组件通过v-model可以绑定数据, ...
- vue 自定义分页组件
vue2.5自定义分页组件,可设置每页显示条数,带跳转框直接跳转到相应页面 Pagination.vue 效果如下图: all: small(只显示数字和上一页和下一页): html <temp ...
- Vue自定义日历组件
今天给大家介绍Vue的日历组件,可自定义样式.日历类型及支持扩展,可自定义事件回调.Props数据传输. 线上demo效果 示例 Template: <Calendar :sundayStart ...
- vue自定义分页组件---切图网
vue2.5自定义分页组件 Pagination.vue,可设置每页显示条数,带跳转框直接跳转到相应页面,亲测有用.目前很多框架自带有分页组件比如elementUI,不过在面对一个拿到PSD稿,然后重 ...
- vue自定义日期组件
vue-datepicker 基于 vuejs 2.x 可自定义主题的日期组件 github Usage 只需要在项目中加入 calendar.vue,就可以使用了. 向组件传入 prop 即可改变 ...
- vue 自定义image组件
介绍 1:当图片加载失败时,给出错误提示. 2:当图片加载中时,给出加载提示. 3:图片处理模式:等比缩放/裁剪/填充/... 1.图片加载状态处理 通过给图片绑定load事件与error事件处理函数 ...
- vue 自定义封装组件 使用 model 选项
自定义组件的 v-model 一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框.复选框等类型的输入控件可能会将 value 特性用于不同 ...
随机推荐
- leetcode 217. 存在重复元素 (python)
给定一个整数数组,判断是否存在重复元素. 如果任何值在数组中出现至少两次,函数返回 true.如果数组中每个元素都不相同,则返回 false. 示例 1: 输入: [1,2,3,1]输出: true示 ...
- 屏幕适配dip
android适配一般使用dpi 那dpi与分辨率,屏幕尺寸的关系 DPI值计算是屏幕对角线的像素值除以屏幕的大小 dip=/ 屏幕尺寸, 比如:计算WVGA(800*480)分辨率,3.7英寸的密度 ...
- 安全体系建设-OWASP
OWASP Checklist Spiders, Robots and Crawlers IG- Search Engine Discovery/Reconnaissance IG- Identify ...
- 让Debian以root登录
Debian默认不允许root登录,所以修改之. (1)让Debian以root登录 修改gdm3的登录pam文件 #vi /etc/pam.d/gdm3 将auth required pam_suc ...
- Git008--远程仓库
Git--远程仓库 本文来自于:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/ ...
- python args参数理解
文件名:while.py 代码:import sysprint(sys.path)print(sys.argv) 执行结果: ['D:\\python_basic\\s01', 'D:\\python ...
- 常见ORM框架及JDBC操作工具类
在Java 程序里面去连接数据库,最原始的办法是使用JDBC 的API.我们先来回顾一下使用JDBC 的方式,我们是怎么操作数据库的. // 注册JDBC 驱动 Class.forName(" ...
- Java 遍历某个目录
import java.io.File; import java.io.IOException; public class DirErgodic { public static void find(S ...
- [HDU5807] [BestCoder Round #86 1004] Keep In Touch (DP)
[HDU5807] [BestCoder Round #86 1004] Keep In Touch (DP) 题面 有三个人从一张N个点无重边的有向无环图上的三个点出发,每单位时间,他们分别选择当前 ...
- nginx配置多个server,搭建多个站点
今天域名备案终于成功了,赶紧进行了域名的绑定,在配置vhosts的时候发现了一个default_server 字段,对于这个字段之前没有接触过,后来查了一下,其实是这样的 当用户在浏览器中输入相关域名 ...