<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自定义抽屉组件的更多相关文章

  1. vue自定义全局组件(自定义插件)

    有时候我们在做开发的时候,就想自己写一个插件然后就可以使用自己的插件,那种成就感很强.博主最近研究element-ui和axios的时候,发现他们是自定义组件,但是唯一有一点不同的是,在用elemen ...

  2. vue 自定义报警组件

    1.自定义报警组件 Alarm.vue <!-- 报警 组件 --> <template> <div class="alarm"> <!- ...

  3. vue自定义select组件

    1.目的 看了很多element-ui的源码,决定自己实现一个简单的select组件,遇到的几个难点,便记录下来. 2.难点一 element-ui中的select组件通过v-model可以绑定数据, ...

  4. vue 自定义分页组件

    vue2.5自定义分页组件,可设置每页显示条数,带跳转框直接跳转到相应页面 Pagination.vue 效果如下图: all: small(只显示数字和上一页和下一页): html <temp ...

  5. Vue自定义日历组件

    今天给大家介绍Vue的日历组件,可自定义样式.日历类型及支持扩展,可自定义事件回调.Props数据传输. 线上demo效果 示例 Template: <Calendar :sundayStart ...

  6. vue自定义分页组件---切图网

    vue2.5自定义分页组件 Pagination.vue,可设置每页显示条数,带跳转框直接跳转到相应页面,亲测有用.目前很多框架自带有分页组件比如elementUI,不过在面对一个拿到PSD稿,然后重 ...

  7. vue自定义日期组件

    vue-datepicker 基于 vuejs 2.x 可自定义主题的日期组件 github Usage 只需要在项目中加入 calendar.vue,就可以使用了. 向组件传入 prop 即可改变 ...

  8. vue 自定义image组件

    介绍 1:当图片加载失败时,给出错误提示. 2:当图片加载中时,给出加载提示. 3:图片处理模式:等比缩放/裁剪/填充/... 1.图片加载状态处理 通过给图片绑定load事件与error事件处理函数 ...

  9. vue 自定义封装组件 使用 model 选项

    自定义组件的 v-model 一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框.复选框等类型的输入控件可能会将 value 特性用于不同 ...

随机推荐

  1. Nexus Repository OSS 3安装配置使用

    Nexus Repository OSS 3是一个开源的仓库管理系统,提供了更加丰富的功能,而且安装.配置.使用起来也更加简单方便.OSS 3版本主要支持的仓库(Repository)包括如下: bo ...

  2. [CSP-S模拟测试]:Tree(贪心)

    题目描述 给定一颗$n$个点的树,树边带权,试求一个排列$P$,使下式的值最大 $$\sum \limits_{i=1}^{n-1}maxflow(P_i,P_{i+1})$$ 其中$maxflow( ...

  3. [CSP-S模拟测试]:回文(hash+二维前缀和)

    题目描述 闲着无聊的$YGH$秒掉上面两道题之后,开始思考有趣的回文串问题了. 他面前就有一个漂浮着的字符串.显然$YGH$是会$manacher$的,于是他随手求出了这个字符串的回文子串个数.但是他 ...

  4. curl 和 wget 命令

    1. curl curl 支持 HTTP.HTTPS.FTP 等协议,还支持 POST.cookies.认证.从指定偏移处下载部分文件.User-Agent.限速.文件大小.进度条等特征. 1.1 选 ...

  5. stl vector创建二维数组

    vector<vector<); for (auto it = v.begin(); it != v.end(); it++) { ; (*it).reserve();//预留空间为5,但 ...

  6. ELK日志分析系统之elasticsearch7.x最新版安装与配置

    1.Elasticsearch 1.1.elasticsearch的简介 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful ...

  7. JavaScript PriorityQueue

    function PriorityQueue() { var items = []; function QueueElement(element, priority) { this.element = ...

  8. ubuntu18.04 搭建scrapy环境(连环踩坑+解决办法)

    ---恢复内容开始--- 预期需求: 打算搭建scrapy环境,基于python3.x的 环境描述: ubuntu18.04自带了python3.6,打算在虚拟环境vlenv中跑scrapy,装好虚拟 ...

  9. jquery 操作select,checkbox,radio (整理)

    在工作中经经常使用到select,checkbox,radio,今天有点空暇就整理一下,免得以后用的时候还要又一次找. 操作select下拉框 -- 获取值或选中项: 1, $("#sele ...

  10. C#中XmlTextWriter读写xml文件详细介绍

    XmlTextWriter类允许你将XML写到一个文件中去.这个类包含了很多方法和属性,使用这些属性和方法可以使你更容易地处理XML.为了使用这个类,你必须首先创建一个新的XmlTextWriter对 ...