項目基礎工程文件是使用
vue-cli3.0
搭建的,這裏不過多介紹。開發Vue組件系列之模態框,主要有標題、內容、定時器、按鈕文案、按鈕事件回調、遮罩層這些可配置項。本次開發得組件是本系列的第一個組件,後期也會有更多系列教程推出。javascript
$ Vue create echi-modal
$ cd echi-modal
$ npm install
$ npm run serve
$ npm run build
$ npm run lint
複製代碼
const path = require("path");
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = {
// 基本路徑
publicPath: "./",
// eslint-loader 是否在保存的時候檢查
lintOnSave: false,
// webpack配置
// see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
chainWebpack: config => {
config.resolve.alias
.set("@", resolve("src"))
},
// 生產環境是否生成 sourceMap 文件
productionSourceMap: false,
// css相關配置
css: {
// 是否使用css分離插件 ExtractTextPlugin
extract: true,
// 開啓 CSS source maps?
sourceMap: false,
// css預設器配置項
loaderOptions: {},
// 啓用 CSS modules for all css / pre-processor files.
modules: false
},
// use thread-loader for babel & TS in production build
// enabled by default if the machine has more than 1 cores
parallel: require("os").cpus().length > 1,
devServer: {
port: 9595, // 端口號
open: true, // 自動開啓瀏覽器
compress: true, // 開啓壓縮
overlay: {
warnings: true,
errors: true
}
}
};
複製代碼
├── src # 項目源碼。開發的時候代碼寫在這裏。
│ ├── components # 組件目錄
| | |--EchiModal # 模態框組件
│ ├── App.vue # 項目根視圖
│ ├── main.js # 程序主入口
複製代碼
使用
transition
能夠爲組件添加動效;對應的組件模板內容以下css
<template>
<transition name="toggle">
<section class="modal" v-show="visible">
<div class="modal-mask" v-show="showMask" @click="clickMask"></div>
<section class="modal-content modal-center" :style="contentStyle">
<header class="modal-header" :class="{ 'modal-plain': plain }" v-if="showHeader">
<slot name="header">{{ title }}</slot>
<span class="closed" v-if="showClose" @click.stop="onClose">
關閉
</span>
</header>
<main class="modal-body">
<slot>
<div class="text-tips">{{ text }}</div>
</slot>
</main>
<footer class="modal-footer" v-if="showFooter">
<slot name="footer">
<button class="modal-btn modal-btn-primary" @click.stop="onConfirm">
{{ confirmBtnText }}
</button>
<button class="modal-btn modal-btn-default" @click.stop="onClose">
{{ cancelBtnText }}
</button>
</slot>
</footer>
</section>
</section>
</transition>
</template>
複製代碼
添加組件的屬性,其中
duration
屬性若是設定的數值小於10,則會乘以1000;不然按傳遞的數值計算html
<script>
export default {
name: "EchiModal",
props: {
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: "標題"
},
text: {
type: String,
default: "提示信息"
},
tinyBar: {
type: Boolean,
default: false
},
confirmBtnText: {
type: String,
default: "肯定"
},
cancelBtnText: {
type: String,
default: "返回"
},
contentStyle: {
type: Object,
default: () => {}
},
showClose: {
type: Boolean,
default: true
},
plain: {
type: Boolean,
default: false
},
showHeader: {
type: Boolean,
default: true
},
showFooter: {
type: Boolean,
default: true
},
showMask: {
type: Boolean,
default: true
},
onMask: {
type: Boolean,
default: false
},
duration: {
type: Number,
default: 0
}
},
watch: {
visible(nv) {
if (nv) {
this.closeTimerHandle()
}
}
},
data() {
return {
closeTimer: null,
}
},
methods: {
onClose() {
this.$emit("on-close");
this.hide();
},
onConfirm() {
this.$emit("on-confirm");
},
hide() {
this.$emit("update:visible", false);
this.$emit("on-closed");
clearTimeout(this.closeTimer);
this.closeTimer = null;
},
clickMask() {
if (this.onMask && this.showMask) {
this.hide();
}
},
closeTimerHandle() {
try {
if (this.duration <= 0) {
return;
}
const duration = (this.duration < 10) ? (this.duration * 1000) : this.duration;
clearTimeout(this.closeTimer);
this.closeTimer = setTimeout(() => {
this.onClose();
}, duration);
} catch (e) {
console.log(e)
}
}
}
};
</script>
複製代碼
<style scoped lang="scss">
*,
:after,
:before {
box-sizing: border-box;
outline: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
$color-tips: #1ab394;
$color-text: rgba(255, 255, 255, 0.6);
$color-info: #ff9900;
$color-default: #ccc;
.modal {
display: block;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 99;
.modal-mask {
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.modal-center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.modal-content {
display: flex;
flex-direction: column;
min-width: 360px;
box-shadow: 0 1px 8px 0 rgba(0, 30, 24, 0.05);
background-color: #fff;
border-radius: 6px;
overflow: hidden;
}
.modal-header {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 44px;
font-size: 18px;
padding: 0 20px;
font-weight: 500;
color: #fff;
background-color: $color-tips;
z-index: 9999;
.closed {
position: absolute;
top: 50%;
right: 0;
font-size: 12px;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
color: #fff;
transform: translateY(-50%);
}
&.modal-plain {
background-color: rgba(245,
245,
245,
1);
color: $color-tips;
.closed {
color: $color-info;
}
}
}
.modal-body {
display: block;
flex: 1;
background-color: #fff;
overflow: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.modal-footer {
display: block;
width: 100%;
padding: 20px 30px;
text-align: center;
background-color: #fff;
.modal-btn {
width: 80px;
+.modal-btn {
margin-left: 8px;
}
}
}
}
.text-tips {
display: block;
width: 100%;
font-size: 16px;
text-align: center;
color: #333;
padding: 40px 60px;
}
.modal-btn {
display: inline-flex;
padding: 0 12;
margin: 0;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 400;
height: 32px;
text-align: center;
white-space: nowrap;
touch-action: manipulation;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
cursor: pointer;
user-select: none;
background-image: none;
text-decoration: none;
border: 1px solid transparent;
border-radius: 4px;
transition: all .3s ease;
&:link,
&:visited,
&:hover,
&:active {
text-decoration: none;
}
}
.modal-btn-default {
background-color: $color-default;
color: #fff;
&:link {
color: #fff;
background-color: $color-default;
}
&:visited {
color: #fff;
background-color: $color-default;
}
&:hover {
color: #fff;
background-color: rgba(170, 170, 170, .85);
}
&:active {
color: #fff;
background-color: $color-default;
}
&[plain] {
background-color: #fff;
color: $color-default;
border: 1px solid $color-default;
}
}
.modal-btn-primary {
background-color: $color-tips;
color: #fff;
&:link {
color: #fff;
background-color: $color-tips;
}
&:visited {
color: #fff;
background-color: $color-tips;
}
&:hover {
color: #fff;
background-color: rgba(26, 179, 148, 0.85);
}
&:active {
color: #fff;
background-color: $color-tips;
}
&[plain] {
background-color: #fff;
color: $color-tips;
border: 1px solid $color-tips;
}
}
.toggle-enter,
.toggle-leave-active {
opacity: 0;
transform: translatey(-10px);
}
.toggle-enter-active,
.toggle-leave-active {
transition: all ease .2s;
}
</style>
複製代碼
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<div>
<button @click.stop="showModel_0 = true">
顯示默認樣式
</button>
<button @click.stop="showModel_1 = true">
顯示素樣式
</button>
<button @click.stop="showModel_2 = true">
修改提示語
</button>
<button @click.stop="showModel_3 = true">
自定義內容
</button>
<button @click.stop="showModel_4 = true">
去除Footer
</button>
<button @click.stop="showModel_5 = true">
去除Header
</button>
<button @click.stop="showModel_6 = true">
設置3秒後自動關閉
</button>
</div>
<EchiModal :visible.sync="showModel_0" title="顯示默認樣式"></EchiModal>
<EchiModal :visible.sync="showModel_1" title="顯示素樣式" plain></EchiModal>
<EchiModal :visible.sync="showModel_2" title="修改提示語" text="哈哈哈哈哈,我把提示信息修改了"></EchiModal>
<EchiModal :visible.sync="showModel_3" title="自定義內容" :contentStyle="{width: '600px'}">
<img alt="Vue logo" src="./assets/logo.png" />
</EchiModal>
<EchiModal :visible.sync="showModel_4" title="去除Footer" :showFooter="false"></EchiModal>
<EchiModal :visible.sync="showModel_5" title="去除Header" :showHeader="false"></EchiModal>
<EchiModal :visible.sync="showModel_6" title="設置3秒後自動關閉" :duration="3"></EchiModal>
</div>
</template>
<script> import EchiModal from "./components/EchiModal.vue"; export default { name: "app", components: { EchiModal }, data() { return { showModel_0: false, showModel_1: false, showModel_2: false, showModel_3: false, showModel_4: false, showModel_5: false, showModel_6: false, } } }; </script>
複製代碼
感謝那您的觀看,以上就是我爲你們帶來的模態框組件,本文同步更新於個人github點擊前往。若是對您有幫助,請爲我點個小星星vue
本文做者: Echi
本文連接: juejin.im/user/585e36…
版權聲明: 本文章除特別聲明外,均採用 @BY-NC-SA 許可協議。轉載請註明出處!java