项目基础工程文件是使用vue-cli3.0搭建的,这里不过多介绍。开发Vue组件系列之模态框,主要有标题、内容、定时器、按钮文案、按钮事件回调、遮罩层这些可配置项。本次开发得组件是本系列的第一个组件,后期也会有更多系列教程推出。
使用命令行
$ 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 是否在保存的时候检查 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"os").cpus().length > 1, devServer: { port: 9595, // 端口号 open: true, // 自动开启浏览器 compress: true, // 开启压缩 overlay: { warnings: true, errors: true } } };
项目结构
├── src # 项目源码。开发的时候代码写在这里。 │ ├── components # 组件目录 | | |--EchiModal # 模态框组件 │ ├── App.vue # 项目根视图 │ ├── main.js # 程序主入口
部分截图
modal组件模板
使用 transition 可以为组件添加动效;对应的组件模板内容如下
<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;否则按传递的数值计算
<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) "htmlcode"><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="/UploadFiles/2021-04-02/logo.png">感谢那您的观看,以上就是我为大家带来的模态框组件,本文同步更新于我的github点击前往。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]