不知道大家有没有遇到这种情况。平时过于依赖组件库,如果产品对某个组件有特殊的要求。我们与其去改,去覆盖组件库的源码。还不如自己写一个组件,毕竟是自己写的,不管你想怎么改,都方便容易的很。这里就实现一个dialog组件和input组件,不基于任何组件库。供大家参考
效果展示
MDialog.vue
<template>
<transition name="fade">
<div class="dialog-mask">
<div class="dialog-wrapper animated fadeInUp" ref="dialogWrapper">
<div class="dialog-container">
<div class="dialog-header">{{title}}</div>
<div class="dialog-body">
<slot></slot>
</div>
<div class="dialog-footer">
<div class="left i-block" @click="dialogClose">{{cancel}}</div>
<div class="right i-block" @click="submit">{{confirm}}</div>
</div>
</div>
</div>
</div>
</transition>
</template>
<script lang='ts'>
import { Component, Vue, Watch, Prop } from "vue-property-decorator";
import '@/../public/css/animate.min.css';
@Component({
components: {}
})
export default class extends Vue {
@Prop()
private title!: string;
@Prop()
private cancel!: string;
@Prop()
private confirm!: string;
private dialogClose() {
this.$emit("close");
}
private submit() {
this.$emit("submit");
}
}
</script>
<style scoped lang="scss">
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.4s;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
.dialog-mask {
background-color: rgba(0, 0, 0, 0.5);
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 99;
display: table;
animation-duration: 0.6s;
.dialog-wrapper {
display: table-cell;
vertical-align: middle;
animation-duration: 0.3s;
.dialog-container {
margin: auto;
top: 50%;
background-color: white;
width: 260px;
height: 150px;
border-radius: 12px;
.dialog-header {
background-color: #f3fff7;
color: #42b983;
height: 32px;
border-radius: 12px 12px 0 0;
border-bottom: 1px solid #cccccc;
display: flex;
justify-content: center;
align-items: center;
font-size: 13px;
color: #38c26b;
}
.dialog-body {
display: flex;
justify-content: center;
align-items: center;
margin: 20px 0;
height: 50px;
font-size: 13px;
}
.dialog-footer {
height: 40px;
width: 100%;
background-color: #ffffff;
border-radius: 0 0 12px 12px;
display: table;
.left {
width: 50%;
height: 100%;
vertical-align: middle;
display: table-cell;
font-size: 13px;
color: #38c26b;
}
.right {
width: 50%;
height: 100%;
vertical-align: middle;
display: table-cell;
font-size: 13px;
color: #38c26b;
}
.left:hover {
cursor: pointer;
}
.right:hover {
cursor: pointer;
}
}
}
}
}
</style>
DialogInput.vue
<template>
<div class="input-wrap">
<input
type="text"
:value="value"
:placeholder="placeholder"
@input="$emit('input',$event.target.value)"
/>
</div>
</template>
<script lang='ts'>
import { Component, Vue, Watch, Prop } from "vue-property-decorator";
@Component({
components: {}
})
export default class extends Vue {
@Prop()
private value!: string;
@Prop()
private placeholder!: string;
}
</script>
<style scoped lang="scss">
.input-wrap {
border: 1px solid #56d16a;
border-radius: 5px;
height: 32px;
width: 90%;
background-color: #f3fff7;
display: flex;
align-items: center;
justify-content: center;
input {
background-color: #f3fff7;
font-size: 13px;
height: 25px;
width: 95%;
border: 0px;
text-indent: 3px;
}
}
</style>
父组件中使用
<m-dialog
@close="closeDialog"
@submit="handleSubmit"
v-if="visible"
cancel="取消"
confirm="确定"
title="提示"
>
<dialog-input placeholder="请输入手机号码" v-model="value"></dialog-input>
<!-- 您确定要取消该订单吗 -->
</m-dialog>
这里script部分是用ts写的,你可以改成vue的语法。template和style部分不用改。
窗体部分使用了animate.css的动画,直接下好css,在script导入就可以了。遮罩层使用了transition做fadein fadeout效果