elmentui 弹窗,自定义样式 修改里边默认样式,自定义header,自定义头部等。Vue自定义组件的使用。Vue模板。Vue弹窗实现反馈页面 电脑版发表于:2020/6/9 10:19 [TOC] **这样一个效果** ![](https://img.tnblog.net/arcimg/aojiancc2/a37b559d85bb4557862ff11ac5a309ed.png) **主要分为三块:** - 一块是:一个简单的可以拖动的右下角悬浮菜单组件封装,点击它弹出这个弹窗 - 一块是:对于这个弹窗的自定义样式,主要是header和body和footer插槽的使用,也是封装的一个组件 - 一块是:最下面关于图片上传的组件封装,还有就是图片预览的组件的使用 ### 可以拖动的悬浮菜单部分代码如下: 是触发的第一个组件。部分代码如下,详细的可以参考下方连接 ``` <template> <div> <!-- 悬浮菜单开始 --> <div class="realTranslationInfos" v-drag> <div class="RealtranslationBox"> <img draggable="false" @click="openFeedbackDialog()" src="@/assets/imgs/labroom/feedback.png" alt="" width="66px" height="66px"> </div> </div> <!-- 悬浮菜单结束 --> <!-- 封装的弹窗组件 --> <FeedbackDialog ref="feedbackDialog" /> </div> </template> <script> import FeedbackDialog from '@/pages/feedback/feedbackDialog.vue' export default { // 组件名字 name: 'FeedBack', components: { FeedbackDialog }, // 组件参数 props: { id: { type: String, default: '' }, index: { type: Number, default: 0 }, }, data() { return { // 用来给自己封装的弹窗组件传递参数 dialogVisible: false } }, mounted() { }, // 组件方法 methods: { openFeedbackDialog() { //调用子组件的方法打开弹窗 this.$refs.feedbackDialog.openFeedbackDialog(); } } } </script> <style scoped="scoped" lang="scss"> .realTranslationInfos { width: 66px; height: 66px; // background: red; position: fixed; // position: absolute; bottom: 56px; right: 20px; // bottom: 122px; // right: -30px; .translationContent { min-height: 100px; line-height: 23px; width: 338px; padding: 18px 74px 19px 19px; background: #004CB3; opacity: 0.80; border-radius: 12px; color: #fff; position: fixed; // position: absolute; right: 58px; bottom: 22px; z-index: 99999; } .RealtranslationBox { display: flex; align-items: center; position: absolute; right: 2px; bottom: 5px; z-index: 99999; img { cursor: pointer; } } } </style> ``` 详细的使用可以参考:https://www.tnblog.net/aojiancc2/article/details/7829 #### 这里打开子组件弹窗的方式是调用子组件的方法打开的弹窗 ``` openFeedbackDialog() { //调用子组件的方法打开弹窗 this.$refs.feedbackDialog.openFeedbackDialog(); } ``` vue3中父组件调用子组件方法有点不一样了,参考:https://www.tnblog.net/xiuxin/article/details/8153 ### 第二块:关于弹窗的自定义样式 ``` <!-- 问题反馈使用的弹窗 --> <template> <div> <!-- 弹窗start --> <div class="dialogContent"> <el-dialog :visible.sync="dialogVisible" :show-close="false" width="700px" height="800px" :before-close="handleClose"> <div slot="title" class="dialog-footer"> <div style="font-size:16px"> 问题反馈 </div> <div class="separateline"> </div> </div> <div style="margin-top:-10px"> <div style="display:flex"> <div style="width:78px;color:#000"> 问题类型: </div> <div> <el-radio v-model="radio" label="1">系统问题</el-radio> <el-radio v-model="radio" label="2">内容问题</el-radio> <el-radio v-model="radio" label="3">我要吐槽</el-radio> </div> </div> <div style="display:flex;margin-top: 30px;"> <div style="width:78px;color:#000;"> 描 述: </div> <div style="flex-grow: 1"> <el-input type="textarea" v-model="describe" style="width:100%" :rows="7" placeholder="请输入内容"> </el-input> </div> </div> <div style="display:flex;margin-top: 30px;"> <div style="width:78px;color:#000"> 问题截图: </div> <div style="flex-grow: 1"> <!-- 引用图片上传的组件 --> <UpLoadImg /> </div> </div> </div> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false" size="small">我在想想</el-button> <el-button type="primary" size="small" @click="dialogVisible = false">确定反馈</el-button> </span> </el-dialog> </div> <!-- 弹窗end --> </div> </template> <script> import UpLoadImg from '@/pages/feedback/upLoadImg.vue' export default { // 组件名字 name: 'FeedbackDialog', components: { UpLoadImg }, // 组件参数 props: { index: { type: Number, default: 0 }, }, data() { return { radio: "3", describe:"", dialogVisible: false } }, mounted() { //alert("组件内部加载好了"+this.dialogVisibleParameter) this.initPic() }, // 组件方法 methods: { initPic() { }, //模态框关闭前的事件 handleClose(done) { }, //打开弹窗 openFeedbackDialog() { this.dialogVisible = true } } } </script> <style scoped="scoped" lang="scss"> // 自定义的一根简单分割线 .separateline { height: 1px; background: #eee; margin-left: -40px; margin-right: -40px; margin-top: 9px; } // 问题截图,传递图片的样式 .form-content.panle { // padding: 20px; padding-bottom: 10px; // background-color: #f8f8f8; .img-boxs { display: flex; /* margin-right: 46px; */ flex-wrap: wrap; .img-waper { margin-right: 10px; margin-bottom: 10px; position: relative; .remove-icon:hover { cursor: pointer; img { opacity: 0.6; } } .remove-icon { position: absolute; width: 14px; height: 14px; top: -8px; right: -5px; img { width: 100%; } } } } .add-btn:hover { cursor: pointer; opacity: 0.6; } .add-btn { width: 70px; height: 70px; border: solid 1px #DDDDDD; display: flex; align-items: center; flex-wrap: wrap; justify-content: space-around; .icon-waper { width: 18px; height: 21px; position: relative; .icon-x { width: 19px; height: 5px; background-color: #DDDDDD; position: absolute; top: 0; bottom: 0; margin: auto; } .icon-y { height: 21px; width: 5px; background-color: #DDDDDD; position: absolute; left: 0; right: 0; margin: auto; } } } } </style> <!-- 修改elementui里边对话框的默认样式 需要注意两点: 1:样式声明的时候不要加scoped,不然样式只在当前组件起作用,无法覆盖样式内容的样式 2:要修改默认弹窗里边的样式,加一个前缀,就可以做到只修改当前这个组件的了,不然可能会影响到其他地方的样式 --> <style lang="scss"> /* .dialogContent .el-dialog { background-color: #F6F8FC; } .dialogContent .el-dialog__header { padding: 20px 40px 10px 40px } .dialogContent .el-dialog__body { padding: 30px 40px; color: #606266; font-size: 14px; word-break: break-all; } */ // 修改el-dialog里边的默认样式 .dialogContent { .el-dialog { background-color: #F6F8FC; } .el-dialog__header { padding: 20px 40px 10px 40px } .el-dialog__body { padding: 30px 40px; color: #606266; font-size: 14px; word-break: break-all; } .el-dialog__footer { padding: 0px 40px 30px 40px } // 修改默认按钮的padding也就是跳转按钮的宽度 .el-button--small, .el-button--small.is-round { padding: 9px 16px; } // 修改默认按钮的圆角为直角 .el-button--mini, .el-button--small { border-radius: 0px; } } </style> ``` ### 第三块:关于图片上传的组件 ``` <!-- 问题反馈使用的弹窗 --> <template> <div> <!-- 图片上传start --> <div class="form-content panle"> <div class="img-boxs"> <div v-for="(item,i) in taskResoult.imgJson" :key="i+'img'" class="img-waper" @click="onPreviewImg(i)"> <img :src="'/oss/api/ImageViewer/'+item.id+'.jpg?percent=0.6&quality=80&od=true'" width="79px" height="79px"> <div class="remove-icon" @click="rmImgs(i)"> <img src="/asserts/img/error.png"> </div> </div> <div v-if="taskResoult.imgJson.length<9" class="img-waper"> <div class="add-btn" @click="addImgClick"> <input ref="inputImgFile" type="file" @change="uploadimg" style="display: none;" accept="image/*"> <div class="icon-waper"> <div class="icon-x" /> <div class="icon-y" /> </div> </div> </div> </div> </div> <!-- 图片上传end --> <!-- 图片预览start --> <el-image-viewer v-if="showViewer" :z-index="20000" :initial-index="initialIndex" :append-to-body="true" :on-close="closeViewer" :mask-closable="false" :url-list="taskResoult.imgJson.map(a=>a.fileUrl)" /> <!-- 图片预览end --> </div> </template> <script> import ElImageViewer from 'element-ui/packages/image/src/image-viewer' export default { // 组件名字 name: 'UpLoadImg', components: { ElImageViewer }, // 组件参数 props: { index: { type: Number, default: 0 }, }, data() { return { showViewer: false, initialIndex: 0, taskResoult: { 'uploadFileID': '', stuImgs: '', imgJson: [], 'uploadFileInfo': '', uploadFileInfoJson: {}, 'remarks': null } } }, mounted() { this.initPic() }, // 组件方法 methods: { initPic() { }, //点击添加图片,直接触发文件选择框的事件即可 addImgClick() { this.$refs.inputImgFile.click() }, //打开图片预览 onPreviewImg(i) { //设置预览图片的索引 this.initialIndex = i this.showViewer = true }, // 关闭图片预览 closeViewer() { this.showViewer = false }, rmImgs(i) { this.taskResoult.imgJson.splice(i, 1) // console.log(self.taskResoult) this.$forceUpdate() }, //上传图片逻辑。文件选择框的change事件触发 uploadimg(e) { // 日精进上传图片 const imgFileExtensionArry = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'psd', 'svg', 'tiff'] const file = e.target.files[0] const fileExt = file.name.substr(file.name.lastIndexOf('.') + 1) if (imgFileExtensionArry.indexOf(fileExt.toLowerCase()) === -1) { this.$message.warning('仅允许提交图片文件!') return } const formData = new FormData() formData.append('bucketName', 'labroom') formData.append('filePath', 'labresult') formData.append('FileType', 1) formData.append('file', file) if (this.taskResoult.stuImgs && this.taskResoult.imgJson.length === 9) { this.$message.error('不允许超过9张图片') return } const self = this self.$service.api.UpLoadFormFile(formData).then(res => { const imgInfo = { id: res.data.id, fileName: res.data.title, fileUrl: '/oss/api/ImageViewer/' + res.data.id + '.jpg' } self.taskResoult.imgJson.push(imgInfo) console.log(self.taskResoult) self.$forceUpdate() }) } } } </script> <style scoped="scoped" lang="scss"> // 问题截图,传递图片的样式 .form-content.panle { // padding: 20px; padding-bottom: 10px; // background-color: #f8f8f8; .img-boxs { display: flex; /* margin-right: 46px; */ flex-wrap: wrap; .img-waper { margin-right: 10px; margin-bottom: 10px; position: relative; .remove-icon:hover { cursor: pointer; img { opacity: 0.6; } } .remove-icon { position: absolute; width: 14px; height: 14px; top: -8px; right: -5px; img { width: 100%; } } } } .add-btn:hover { cursor: pointer; opacity: 0.6; } .add-btn { width: 79px; height: 79px; border: solid 1px #DDDDDD; display: flex; align-items: center; flex-wrap: wrap; justify-content: space-around; .icon-waper { width: 18px; height: 21px; position: relative; .icon-x { width: 19px; height: 5px; background-color: #DDDDDD; position: absolute; top: 0; bottom: 0; margin: auto; } .icon-y { height: 21px; width: 5px; background-color: #DDDDDD; position: absolute; left: 0; right: 0; margin: auto; } } } } </style> ``` 详细的图片预览的组件的使用可以参考: https://www.tnblog.net/aojiancc2/article/details/7830