需求:在页面的代码太多,想把弹窗代码提取为子组件,复用也方便。
 
这里涉及到弹窗el-dialog的一个属性show-close:
show-close="false"是设置不显示关闭按钮,因为弹窗显示状态值(:visible.sync)是从父组件传递的参数,如果使用自带的关闭按钮,会报出一个错误:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "visible"
虽然弹窗会关闭,但却会导致弹窗的显示状态没有及时修改为false,需要点击两次触发弹窗click事件才能再打开弹窗。
所以,为了避免这个错误,这里提供两个方案:
1.关闭按钮另外添加,因为要触发click事件来触发父组件修改变量(使用$emit通知父组件来操作)。
2.使用自带关闭按钮,给弹窗添加before-close事件(这是elementUI提供的),在这个方法里也是使用$emit修改父组件的visible状态。
 
第一种方案:
 
父组件:
<template>
<div class="main-wrap">
<el-button type="primary" @click="add('addOrder')">添加</el-button>
<add-order ref="addOrder" v-if="addOrderVisible" :visible.sync="addOrderVisible"></add-order>
</div>
</template>
<script>
import Add from './add.vue'
export default {
data(){
return {
addOrderVisible: false
}
},
methods: {
add(refForm){
if(this.$refs[refForm]){
this.$refs[refForm].initForm();
}
this.addOrderVisible= true;
}
},
components: {
'add-order': Add
}
}
</script>
 
子组件:
<template>
<el-dialog :visible.sync="visible" :show-close="false" width="600px" :modal="true" :close-on-click-modal="false" :close-on-press-escape="false">
<h2 slot="title">添加订单</h2>
<button type="button" aria-label="Close" class="el-dialog__headerbtn" @click.stop="cancelModal"><i class="el-dialog__close el-icon el-icon-close"></i></button>
<el-form class="form-wrapper" ref="orderForm" :model="orderForm" :rules="addRules" label-width="110px">
<el-form-item label="联系人:" prop="fromContact">
<el-input v-model="orderForm.fromContact" type="text" placeholder="请输入联系人名称"></el-input>
</el-form-item>
<el-form-item label="联系电话:" prop="fromPhone">
<el-input v-model="orderForm.fromPhone" type="text" placeholder="请输入联系电话"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="buttons-wrap">
<el-button type="primary">确定</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
props: {
visible: {
type: Boolean,
default: false
}
},
data(){
return {
orderForm: {},
addRules: {
fromContact: [{ required: true, message: "请输入联系人姓名", trigger: 'blur'}],
fromPhone: [{required: true, message: "请输入", trigger: 'blur'}]
}
}
},
methods: {
initForm(){
this.orderForm = {
fromContact: '',
fromPhone: ''
};
if(this.$refs.orderForm){
this.$refs.orderForm.resetFields();
}
},
cancelModal(){
// 关闭弹窗,触发父组件修改visible值
this.$emit('update:visible', false);
}
}
}
</script>
<style lang="scss" scoped>
.buttons-wrap { .el-button {
margin-right: 20px;
min-width: 100px;
}
}
</style>
 
第二种方案:(添加before-close)

父组件:

<template>
<div class="main-wrap">
<el-button type="primary" @click="toAdd">添加</el-button>
<add-order ref="orderAdd" v-if="addOrderVisible" :visible.sync="addOrderVisible"></add-order>
</div>
</template>
<script>
import Add from './add.vue'
export default {
data(){
return {
addOrderVisible: false
}
},
methods: {
toAdd() {
this.addOrderVisible = true;
}
},
components: {
'add-order': Add
}
}
</script>

子组件:

<template>
<el-dialog
title="添加"
v-loading="loading"
:visible.sync="visible"
width="600px"
:before-close="modalClose"
:close-on-click-modal="false"
:close-on-press-escape="false">
<div>弹窗内容</div>
</el-dialog>
</template>
<script>
export default {
data() {
return {
loading: false
}
},
props: {
visible: {
type: Boolean,
default: false
}
},
methods: {
modalClose() {
this.$emit('update:visible', false); // 直接修改父组件的属性
}
}
}
</script>

这里提另外一种情况:

在只需要显示详情内容的情况下,也可以采取只把内容放到子组件中,头部和底部按钮都放在父组件中,这就不需要考虑弹窗显示状态的问题,把需要显示的参数传到子组件中即可。
 
父组件:
<template>
<div class="main-wrap">
<el-button type="primary" @click="showDetail()">详情</el-button>
<el-dialog v-if="detailVisible" :visible.sync="detailVisible" width="600px" :modal="true">
<h2 slot="title">详情</h2>
<detail ref="newOrderDetail" :newOrderDetail="newOrderDetail"></detail>
<div slot="footer" class="detail-wrap-bottom">
<el-button type="primary">确认</el-button>
<el-button type="default">退回</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import detail from './detail'
export default {
data(){
return {
detailVisible: false,
newOrderDetail: {}
}
},
methods: {
showDetail(){
this.newOrderDetail = {id: 8, fromContact: 'Thomas', fromPhone: '15812345678'};
this.detailVisible= !this.detailVisible;
}
},
components: {
detail: detail
}
}
</script>
子组件:
<template>
<div class="detail-wrap" :data="newOrderDetail">
<ul>
<li><span>用车联系人:</span><div>{{newOrderDetail.fromContact}}</div></li>
<li><span>联系人电话:</span><div>{{newOrderDetail.fromPhone}}</div></li>
</ul>
</div>
</template>
<script>
export default {
props: {
newOrderDetail: {
type: Object,
default: null
}
},
data() {
return {
loading: false
}
}
}
</script>
<style lang="scss" scoped>
.detail-wrap ul {
max-height: 400px;
overflow: auto; li {
position: relative;
padding: 8px;
font-size: 1rem; span {
position: absolute;
width: 90px;
} & > div {
margin-left: 90px;
}
}
}
</style>
 

温馨提示:

如果弹窗内容较多,出现了滚动条,需要每次打开还原到顶部,则需要添加v-if指令,因为这个指令是动态渲染内容的(文中有用到)。

 
 
 

ElementUI对话框(dialog)提取为子组件的更多相关文章

  1. elementUI 的el-dialog作为子组件,父组件如何控制其关闭的按钮

    这里有三点需要说明: 1. 使用:before-close="closeHandle" 将其 $emit() 出去 2. 取消按钮 也需要$emeit出去 3. 控制对话框显示隐藏 ...

  2. vue+elementUI项目,父组件向子组件传值,子组件向父组件传值,父子组件互相传值。

    vue+elementUI项目,父组件向子组件传值,子组件向父组件传值,父子组件互相传值. vue 父组件与子组件相互通信 一.父组件给子组件传值 props 实现父组件向子组件传值. 1父组件里: ...

  3. java 图形化小工具Abstract Window Toolit 常用组件:对话框Dialog FileDialog

    对话框 Dialog是Window类的子类,是1个容器类,属于特殊组件,对话框是可以独立存在的顶级窗口,因此用法与普通窗口的用法几乎完全一样.但对话框有如下两点需要注意. (1),对话框通常依赖于其他 ...

  4. element-ui(或者说Vue的子组件)绑定的方法中传入自定义参数

    比如el-upload中的 :on-success= fn,其实是给组件el-upload传递一个prop,这样写的话fn只能接受upload组件规定的参数,如果想自己传递父组件中的参数比如b,要写成 ...

  5. 对话框Dialog

    QMainWindow QMainWindow是 Qt 框架带来的一个预定义好的主窗口类. 主窗口,就是一个普通意义上的应用程序(不是指游戏之类的那种)最顶层的窗口.通常是由一个标题栏,一个菜单栏,若 ...

  6. vue实现element-ui对话框可拖拽功能

    element-ui对话框可拖拽及边界处理 应业务需求,需要实现对话框可拖拽问题,应element-ui没有提供官方支持,于是便参考大神的文章,得出了适合业务需要的解决方案.很多大神给出的代码是没有解 ...

  7. vue:父子组件间通信,父组件调用子组件方法进行校验子组件的表单

    参考: ElementUI多个子组件表单的校验管理:https://www.jianshu.com/p/541d8b18cf95 Vue 子组件调用父组件方法总结:https://juejin.im/ ...

  8. vue父组件向子组件传对象,不实时更新解决

    vue报错:void mutating a prop directly since the value will be overwritten whenever the parent componen ...

  9. 实现element-ui对话框可拖拽功能

    element-ui对话框可拖拽及边界处理 应业务需求,需要实现对话框可拖拽问题,应element-ui没有提供官方支持,于是便参考大神的文章,得出了适合业务需要的解决方案.很多大神给出的代码是没有解 ...

随机推荐

  1. PHP 范围解析操作符 (::) 主要用于访问静态成员和类常量

    范围解析操作符 (::) 范围解析操作符(也可称作 Paamayim Nekudotayim)或者更简单地说是一对冒号,可以用于访问静态成员,类常量,还可以用于覆盖类中的属性和方法. 当在类定义之外引 ...

  2. SeetaFace2 cmake VS2015编译编译

    cmake Selecting Windows SDK version 10.0.17134.0 to target Windows 10.0.18362. == BUILD_VERSION: v2. ...

  3. linux非root用户安装4.0.14版本redis

    先到官网https://redis.io/download下安装包,现在最新是5.0.5版本,可惜点击下载后被windows禁了,那就下4版本的,往下看Other versions的Old(4.0), ...

  4. [转]Winform打包工具SetupFactory 9 的使用

    写了个WinForm的小程序..以前没打过包..只是直接把Bin里的东西复制出来使用..自己使用是足够.但是发给别人毕竟不太好看(不牛逼)..所以就想着打包.. Vs2012自带的有打包的功能..相信 ...

  5. redis cluster环境搭建

    环境搭建 http://blog.51cto.com/zhoushouby/1560400 http://hot66hot.iteye.com/blog/2050676 ruby环境安装---ruby ...

  6. http响应时长分析

    curl -o /dev/null -s -w "time_namelookup:%{time_namelookup}::time_connect:%{time_connect}::time ...

  7. docker安装MongoDB创建用户,并用工具Robo连接简单CRUD

    搜索mongo docker search mongo 拉取mongo[这里默认为latest] docker pull mongo 查看本地镜像 启动容器[就是安装,-v后面的参数表示把数据文件挂载 ...

  8. java的ReentrantLock类详解

    ReentrantLock 能用于更精细化的加锁的Java类, 通过它能更清楚了解Java的锁机制 ReentrantLock 类的集成关系有点复杂, 既有内部类, 还有多重继承关系 类的定义 pub ...

  9. Action<T>和Func<T>委托事例

    Action<T>和Func<T>委托事例 using System; //除了为每个参数和返回类型定义一个新委托类型之外,还可以使用Action<T>和Func& ...

  10. pytorch1.0神经网络保存、提取、加载

    pytorch1.0网络保存.提取.加载 import torch import torch.nn.functional as F # 包含激励函数 import matplotlib.pyplot ...