element——弹窗

本来以为弹窗挺简单的,结果自己想多了。这几天的使用碰到了好多问题。

在组件中使用弹窗

<div id="app">
	<el-button type="primary" @click="open=true">打开弹窗</el-button>
	<test :visible.sync="open" :table="tableData"></test>
</div>
<script type="text/javascript">
	//定义组件
	Vue.component('test',{
		template:`
		    
		      
		        
		        
		        
		      
		    
		`,
		props:{
			//visible父组件传给子组件的值,控制是否显示弹窗
			visible:{
				type:Boolean,
				default:false
			},
			table:{
				type:Object,
				default:()=>{
					return {}
				}
			}
		},
		methods:{
			clone(){
				this.$emit('update:visible',false)
			}
		}
	})
	new Vue({
		el:'#app',
		data:{
			//是否打开弹窗
			open:false,
			tableData:[{
				date:'2020-10-01',
				name:'张三丰',
				address:'武当山'
			}]
		}
	})

注意点:

1、父组件
<test :visible.sync="open" :table="tableData"></test>
:visible.sync="open" 
2、子组件
props:{
//visible父组件传给子组件的值,控制是否显示弹窗
	visible:{
		type:Boolean,
		default:false
	}
}
3、弹窗的关闭
如果只是关闭弹窗没有其它操作就 this.$emit('update:visible',false) 
如果有其它操作就按照子组件给父组件传参的方式
<test :visible.sync="open" :table="tableData" @change="close"</test>
this.$emit('change')
change(){
	this.open = false
	this.init()
}

是不是固定写法不太清楚,公司很多前辈基本都这样

弹窗嵌套

今天碰见了个弹窗里套弹窗的操作,真让人头大

<template>
  <el-button type="text" @click="outerVisible = true">点击打开外层 Dialog</el-button>
  
  <el-dialog title="外层 Dialog" :visible.sync="outerVisible">
    <el-dialog
      width="30%"
      title="内层 Dialog"
      :visible.sync="innerVisible"
      append-to-body>
    </el-dialog>
    <div slot="footer" class="dialog-footer">
      <el-button @click="outerVisible = false">取 消</el-button>
      <el-button type="primary" @click="innerVisible = true">打开内层 Dialog</el-button>
    </div>
  </el-dialog>
</template>

这个是官方的例子,重点是给外层弹窗加一个append-to-body 属性

新增与编辑操作共用一个弹窗

注意点:
1、弹窗的标题,要根据是新增还是编辑进行修改
2、先点击编辑操作,form表单数据正确。当点击新增时,form中应该没有任何数据,但是却显示之前编辑时的数据

实例

<div id="app">
	<el-button type="primary" @click="addOrEdit(true,null)">新增</el-button>
	<el-dialog :title="dialogT" :visible.sync="openDialog" @close="closeDialog">
		 <el-form label-position="right" label-width="80px" :model="form" ref="formRef">
		   <el-form-item label="名称" prop="name">
			 <el-input v-model="form.name"></el-input>
		   </el-form-item>
		   <el-form-item label="年龄" prop="age">
			 <el-input v-model="form.age"></el-input>
		   </el-form-item>
		 </el-form>
		 <el-button type="primary" @click="closeDialog">取消</el-button>
	</el-dialog>
	  <el-table :data="tableData" style="width: 60%">
	      <el-table-column  prop="name" label="姓名"></el-table-column>
	      <el-table-column  prop="age" label="年龄"></el-table-column>
		  <el-table-column  label="操作">
			  <template slot-scope="scope">
				  <div>
					  <el-button size="mini" @click="addOrEdit(false,scope.row)">编辑</el-button>
				  </div>
			  </template>
		  </el-table-column>
	    </el-table>
</div>
<script type="text/javascript">
	new Vue({
		el:'#app',
		data:{
			//控制弹窗的打开与关闭
			openDialog:false,
			dialogT:'新增',
			form:{
				name:undefined,
				age:undefined
			},
			tableData:[
				{name:'张三',age:15},
				{name:'李四',age:20}
			]
		},
		methods:{
			addOrEdit(type,row){
				this.openDialog=true
				if(type){
					//新增时
					this.dialogT='新增'
				}else{
					this.dialogT='编辑'
					this.form.name=row.name
					this.form.age=row.age
				}
			},
			closeDialog(){
				this.openDialog=false
				this.$refs['formRef'].resetFields()
			}
		}
	})
</script>

这样写是错误的,效果图如下
element——弹窗_第1张图片
看起来是没问题的,实际上是有问题的。看下面这个图
element——弹窗_第2张图片

  • 第一个图没问题是先打开的新增,新增时初始状态是空的,所以重置后还是为空。
  • 第二个图先打开的编辑,这时初始状态为张三的值,不是没有重置而实重置后还是张三。仔细观察可以看到关闭李四时,值重置成了张三

解决:

this.dialogT='编辑'
this.$nextTick(()=>{
	this.form.name=row.name
	this.form.age=row.age
})

$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
因为form表单初始值都是underfunded,所以在初始化完成后再赋值,初始值是underfunded。之前是因为打开弹窗时还没有初始化完成,这时赋值会替代原来的underfunded

查看详情

<div id="app">
  <el-table :data="tableData" style="width: 60%">
      <el-table-column  prop="name" label="姓名"></el-table-column>
      <el-table-column  prop="age" label="年龄"></el-table-column>
	  <el-table-column  label="操作">
		  <template slot-scope="scope">
			  <div>
				  <el-button size="mini" @click="showDetail(scope.row)">查看</el-button>
			  </div>
		  </template>
	  </el-table-column>
    </el-table>
	<detail :visible.sync="openDialog" :details="rowData"></detail>
</div>
<script type="text/javascript">
	Vue.component('detail',{
		template:`
		
			 
			   
				 
			   
			   
				 
			   
			 
		
		`,
		props:{
			visible:{
				type:Boolean,
				default:false
			},
			details:{
				type:Object,
				default:()=>{
					return {}
				}
			}
		},
		data(){
			return {
				form :{},
				open:false
			}
		},
		watch:{
			details(nval,oval){
				this.open=this.visible
				this.$nextTick(()=>{
					this.form=this.details
				})
			}
		},
		methods:{
			closeDialog(){
				this.$emit('update:visible',false)
			}
		}
	})
	new Vue({
		el:'#app',
		data:{
			//控制弹窗的打开与关闭
			openDialog:false,
			//当前行信息
			rowData:{},
			tableData:[
				{name:'张三',age:15},
				{name:'李四',age:20}
			]
		},
		methods:{
			showDetail(row){
				this.openDialog=true
				this.rowData=row
			}
		}
	})
</script>

element——弹窗_第3张图片

你可能感兴趣的:(vue基础)