首页 > 编程 > JavaScript > 正文

Vue组件系列开发之模态框

2019-11-19 11:45:07
字体:
来源:转载
供稿:网友

项目基础工程文件是使用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? 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     # 程序主入口

部分截图

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) ? (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点击前往。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表