Vue组件系列开发之模态框

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

部分截图

Vue组件系列开发之模态框

Vue组件系列开发之模态框

Vue组件系列开发之模态框

modal组件模板

使用 transition 可以为组件添加动效;对应的组件模板内容如下

<template> <transition> <section v-show="visible"> <div v-show="showMask" @click="clickMask"></div> <section :style="contentStyle"> <header :class="{ 'modal-plain': plain }" v-if="showHeader"> <slot>{{ title }}</slot> <span v-if="showClose" @click.stop="onClose"> 关闭 </span> </header> <main> <slot> <div>{{ text }}</div> </slot> </main> <footer v-if="showFooter"> <slot> <button @click.stop="onConfirm"> {{ confirmBtnText }} </button> <button @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>

添加样式声明

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/a15d5c51c2dba23c9eb59231364c90e2.html