這篇文章給大家分享的是有關(guān)Vue如何實(shí)現(xiàn)模態(tài)框的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
創(chuàng)新互聯(lián)主要從事網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)新巴爾虎右,十年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):13518219792
項(xiàng)目基礎(chǔ)工程文件是使用vue-cli3.0搭建的,這里不過(guò)多介紹。開(kāi)發(fā)Vue組件系列之模態(tài)框,主要有標(biāo)題、內(nèi)容、定時(shí)器、按鈕文案、按鈕事件回調(diào)、遮罩層這些可配置項(xiàng)。本次開(kāi)發(fā)得組件是本系列的第一個(gè)組件,后期也會(huì)有更多系列教程推出。
使用命令行
$ Vue create echi-modal $ cd echi-modal $ npm install $ npm run serve $ npm run build $ npm run lint
添加vue.config.js文件,配置如下
const path = require("path"); function resolve(dir) { return path.join(__dirname, dir); } module.exports = { // 基本路徑 publicPath: "./", // eslint-loader 是否在保存的時(shí)候檢查 lintOnSave: false, // webpack配置 // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md chainWebpack: config => { config.resolve.alias .set("@", resolve("src")) }, // 生產(chǎn)環(huán)境是否生成 sourceMap 文件 productionSourceMap: false, // css相關(guān)配置 css: { // 是否使用css分離插件 ExtractTextPlugin extract: true, // 開(kāi)啟 CSS source maps? sourceMap: false, // css預(yù)設(shè)器配置項(xiàng) 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, // 端口號(hào) open: true, // 自動(dòng)開(kāi)啟瀏覽器 compress: true, // 開(kāi)啟壓縮 overlay: { warnings: true, errors: true } } };
項(xiàng)目結(jié)構(gòu)
├── src # 項(xiàng)目源碼。開(kāi)發(fā)的時(shí)候代碼寫(xiě)在這里。 │ ├── components # 組件目錄 | | |--EchiModal # 模態(tài)框組件 │ ├── App.vue # 項(xiàng)目根視圖 │ ├── main.js # 程序主入口
部分截圖
modal組件模板
使用 transition 可以為組件添加動(dòng)效;對(duì)應(yīng)的組件模板內(nèi)容如下
<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" :> <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"> 關(guān)閉 </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屬性如果設(shè)定的數(shù)值小于10,則會(huì)乘以1000;否則按傳遞的數(shù)值計(jì)算
<script> export default { name: "EchiModal", props: { visible: { type: Boolean, default: false }, title: { type: String, default: "標(biāo)題" }, 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"> 顯示默認(rèn)樣式 </button> <button @click.stop="showModel_1 = true"> 顯示素樣式 </button> <button @click.stop="showModel_2 = true"> 修改提示語(yǔ) </button> <button @click.stop="showModel_3 = true"> 自定義內(nèi)容 </button> <button @click.stop="showModel_4 = true"> 去除Footer </button> <button @click.stop="showModel_5 = true"> 去除Header </button> <button @click.stop="showModel_6 = true"> 設(shè)置3秒后自動(dòng)關(guān)閉 </button> </div> <EchiModal :visible.sync="showModel_0" title="顯示默認(rèn)樣式"></EchiModal> <EchiModal :visible.sync="showModel_1" title="顯示素樣式" plain></EchiModal> <EchiModal :visible.sync="showModel_2" title="修改提示語(yǔ)" text="哈哈哈哈哈,我把提示信息修改了"></EchiModal> <EchiModal :visible.sync="showModel_3" title="自定義內(nèi)容" :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="設(shè)置3秒后自動(dòng)關(guān)閉" :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>
感謝各位的閱讀!關(guān)于“Vue如何實(shí)現(xiàn)模態(tài)框”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
網(wǎng)站欄目:Vue如何實(shí)現(xiàn)模態(tài)框
標(biāo)題URL:http://jinyejixie.com/article2/ippooc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、網(wǎng)站導(dǎo)航、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站建設(shè)、、移動(dòng)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)