前言
对于该组件针对Vue2比较多,而Element Plus中的Drawer针对Vue3比较多
此处的Demo主要偏向Vue2
后续的Element Plus 偏向Vue3
1. 基本知识
Drawer 组件可以用于从屏幕的边缘滑入一个面板,用来显示额外的内容而不会离开当前页面视图
主要属性如下:
visible
:是否显示抽屉,Boolean 类型,默认值为 falsedirection
:抽屉滑出的方向,可以是 ‘ltr’(左侧滑出)、‘rtl’(右侧滑出)、‘ttb’(顶部滑出)、‘btt’(底部滑出),默认值为 ‘rtl’size
:抽屉的大小,可以是具体的像素值或者百分比,默认值为 ‘30%’title
:抽屉的标题,String 类型append-to-body
:是否将 Drawer 添加到 body 元素上,Boolean 类型,默认值为 false
事件:
open
:抽屉打开时触发的事件close
:抽屉关闭时触发的事件
2. Demo
更多的Demo如下:
2.1 基本用法
<template>
<div>
<el-button type="primary" @click="drawerVisible = true">打开抽屉</el-button>
<el-drawer
title="基本抽屉"
:visible.sync="drawerVisible"
@close="handleClose">
<span>这是一个基本的抽屉内容。</span>
</el-drawer>
</div>
</template>
<script>
export default {
data() {
return {
drawerVisible: false
};
},
methods: {
handleClose() {
console.log('抽屉已关闭');
}
}
};
</script>
2.2 不同方向
<template>
<div>
<el-button type="primary" @click="leftDrawer = true">左侧滑出</el-button>
<el-button type="primary" @click="rightDrawer = true">右侧滑出</el-button>
<el-button type="primary" @click="topDrawer = true">顶部滑出</el-button>
<el-button type="primary" @click="bottomDrawer = true">底部滑出</el-button>
<el-drawer
title="左侧抽屉"
:visible.sync="leftDrawer"
direction="ltr"
@close="handleClose('leftDrawer')">
<span>左侧滑出的抽屉内容。</span>
</el-drawer>
<el-drawer
title="右侧抽屉"
:visible.sync="rightDrawer"
direction="rtl"
@close="handleClose('rightDrawer')">
<span>右侧滑出的抽屉内容。</span>
</el-drawer>
<el-drawer
title="顶部抽屉"
:visible.sync="topDrawer"
direction="ttb"
@close="handleClose('topDrawer')">
<span>顶部滑出的抽屉内容。</span>
</el-drawer>
<el-drawer
title="底部抽屉"
:visible.sync="bottomDrawer"
direction="btt"
@close="handleClose('bottomDrawer')">
<span>底部滑出的抽屉内容。</span>
</el-drawer>
</div>
</template>
<script>
export default {
data() {
return {
leftDrawer: false,
rightDrawer: false,
topDrawer: false,
bottomDrawer: false
};
},
methods: {
handleClose(drawer) {
this[drawer] = false;
console.log(`${drawer} 抽屉已关闭`);
}
}
};
</script>
2.3 自定义大小
<template>
<div>
<el-button type="primary" @click="smallDrawer = true">小抽屉</el-button>
<el-button type="primary" @click="largeDrawer = true">大抽屉</el-button>
<el-drawer
title="小抽屉"
:visible.sync="smallDrawer"
size="20%"
@close="handleClose('smallDrawer')">
<span>这是一个小抽屉。</span>
</el-drawer>
<el-drawer
title="大抽屉"
:visible.sync="largeDrawer"
size="70%"
@close="handleClose('largeDrawer')">
<span>这是一个大抽屉。</span>
</el-drawer>
</div>
</template>
<script>
export default {
data() {
return {
smallDrawer: false,
largeDrawer: false
};
},
methods: {
handleClose(drawer) {
this[drawer] = false;
console.log(`${drawer} 抽屉已关闭`);
}
}
};
</script>
2.4 嵌入表单
<template>
<div>
<el-button type="primary" @click="drawerVisible = true">打开表单抽屉</el-button>
<el-drawer
title="表单抽屉"
:visible.sync="drawerVisible"
size="50%"
@close="handleClose">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="用户名">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model=""></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm">提交</el-button>
</el-form-item>
</el-form>
</el-drawer>
</div>
</template>
<script>
export default {
data() {
return {
drawerVisible: false,
form: {
username: '',
email: ''
}
};
},
methods: {
handleClose() {
console.log('表单抽屉已关闭');
},
submitForm() {
this.$refs.form.validate(valid => {
if (valid) {
console.log('提交成功', this.form);
this.drawerVisible = false;
} else {
console.error('表单验证失败');
}
});
}
}
};
</script>
2.5 嵌套抽屉
<template>
<div>
<el-button type="primary" @click="outerDrawer = true">打开外层抽屉</el-button>
<el-drawer
title="外层抽屉"
:visible.sync="outerDrawer"
size="50%"
@close="handleClose('outerDrawer')">
<span>这是外层抽屉的内容。</span>
<el-button type="primary" @click="innerDrawer = true">打开内层抽屉</el-button>
<el-drawer
title="内层抽屉"
:visible.sync="innerDrawer"
size="30%"
@close="handleClose('innerDrawer')">
<span>这是内层抽屉的内容。</span>
</el-drawer>
</el-drawer>
</div>
</template>
<script>
export default {
data() {
return {
outerDrawer: false,
innerDrawer: false
};
},
methods: {
handleClose(drawer) {
this[drawer] = false;
console.log(`${drawer} 抽屉已关闭`);
}
}
};
</script>
3. 实战
对于实战中的Demo(部分)
<template>
<basic-container>
<avue-crud :option="option"
:table-loading="loading"
:data="data"
ref="crud"
v-model="form"
:permission="permissionList"
:before-open="beforeOpen"
@row-del="rowDel"
@row-update="rowUpdate"
@row-save="rowSave"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="refreshChange"
@on-load="onLoad"
@tree-load="treeLoad">
<template slot-scope="{row}" slot="menu">
<el-button type="text"
icon="el-icon-setting"
size="small"
v-if="permission.api_scope_setting"
plain
style="border: 0;background-color: transparent !important;"
@click.stop="handleDataScope(row)">权限配置
</el-button>
</template>
<template slot-scope="{row}" slot="source">
<div style="text-align:center">
<i :class="row.source"/>
</div>
</template>
</avue-crud>
<el-drawer :title="`[${scopeMenuName}] 接口权限配置`" :visible.sync="drawerVisible" :direction="direction"
append-to-body
:before-close="handleDrawerClose" size="1000px">
<basic-container>
<avue-crud :option="optionScope"
:data="dataScope"
:page="pageScope"
v-model="formScope"
:table-loading="scopeLoading"
ref="crudScope"
@row-del="rowDelScope"
@row-update="rowUpdateScope"
@row-save="rowSaveScope"
:before-open="beforeOpenScope"
@search-change="searchChangeScope"
@search-reset="searchResetScope"
@selection-change="selectionChangeScope"
@current-change="currentChangeScope"
@size-change="sizeChangeScope"
@on-load="onLoadScope">
<template slot="menuLeft">
<el-button type="danger"
size="small"
icon="el-icon-delete"
plain
@click="handleDeleteScope">删 除
</el-button>
</template>
<template slot-scope="{row}"
slot="scopeType">
<el-tag>{{row.scopeTypeName}}</el-tag>
</template>
</avue-crud>
</basic-container>
</el-drawer>
</basic-container>
</template>
截图如下:
对应的弹窗风格如下:
4. Element Plus(Drawer)
既然阐述到Element 的Drawer,那么看看Element Plus中的有啥差异
基本用法的对比:
<template>
<div>
<el-button type="primary" @click="drawerVisible = true">打开抽屉</el-button>
<el-drawer
title="基本抽屉"
:visible.sync="drawerVisible"
@close="handleClose">
<span>这是一个基本的抽屉内容。</span>
</el-drawer>
</div>
</template>
<script>
export default {
data() {
return {
drawerVisible: false
};
},
methods: {
handleClose() {
console.log('抽屉已关闭');
}
}
};
</script>
Element Plus:
<template>
<div>
<el-button type="primary" @click="drawerVisible = true">打开抽屉</el-button>
<el-drawer
title="基本抽屉"
:model-value="drawerVisible"
@close="handleClose">
<span>这是一个基本的抽屉内容。</span>
</el-drawer>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const drawerVisible = ref(false);
const handleClose = () => {
console.log('抽屉已关闭');
};
return {
drawerVisible,
handleClose
};
}
};
</script>
差异如下:
绑定可见性:
- Element 使用
:visible.sync
来绑定可见性状态。 - Element Plus 使用
:model-value
来绑定可见性状态。
API 设计:
- Element 是基于 Vue 2 的选项式 API。
- Element Plus 是基于 Vue 3 的组合式 API
更多的差异推荐如下:
- 详细分析Vue3中组合式API(附Demo)
- 详细分析Vue3中的props用法(父传子)
- 详细分析Vue3中的emit用法(子传父)
- 详细分析Vue3中的defineEmits基本知识(子传父)