vue把el-dialog提取出来作为子组件,并实现父组件和子组件相互传值
Posted 贺包蛋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue把el-dialog提取出来作为子组件,并实现父组件和子组件相互传值相关的知识,希望对你有一定的参考价值。
最近做项目遇到了一个需求是,为了防止组件中代码冗长,需要将
el-dialog
对话弹出框单独封装成子组件,并将父组件中的id传递给子组件,子组件再根据id刷新父组件。具体项目代码太长,这里仅记录一下实现思路。
01 把el-dialog提取出来作为子组件
效果如下
父组件
<template>
<div>
<!-- 1. 父组件template中注册子组件 -->
<dialog-update ref="dialogUpdate"/>
</div>
</template>
<script>
export default
components:
// 2. 父组件components中引入子组件
DialogUpdate: () => import('./updateContent')
,
methods:
// 按钮点击事件
clickUpdate()
// 3. this.$refs获取子组件属性,设置属性为可见
this.$refs.dialogUpdate.visible = true
</script>
子组件
<template>
<el-dialog :visible.sync="visible">
</el-dialog>
</template>
02 父组件向子组件传值,子组件刷新父组件
子组件的props
属性接收父组件的传参
子组件用this.$emit()
调用父组件的属性和方法
父组件
<template>
<div>
<!-- 1. 父组件将maintainId传给子组件,并为getContentInfo()开启监听事件 -->
<dialog-update
ref="dialogUpdate"
:maintain-id="maintainId"
@getContentInfo="getContentInfo"
/>
</div>
</template>
<script>
export default
components:
DialogUpdate: () => import("./updateContent"),
,
methods:
clickUpdate()
this.$refs.dialogUpdate.visible = true;
,
getContentInfo(maintainId)
// 根据maintainId查询数据
,
;
</script>
子组件
<template>
<el-dialog :visible.sync="visible"></el-dialog>
</template>
<script>
export default
// 2. 子组件props属性接收父组件的传参
props:
maintainId: null,
,
methods:
// 点击提交
submit()
// 3. 子组件this.$emit()刷新父组件, 即getContentInfo(this.maintainId)
this.$emit("getContentInfo", this.maintainId);
,
,
;
</script>
this.$parent
也可以用于子组件获取父组件的属性和方法,但是注意,此时子组件必须放在父组件的根div下,否则undefined
// 父组件
<template>
<div>
// 子组件
<dialog-update ref="dialogUpdate" />
</div>
</template>
// 子组件的方法中调用父组件的method1方法
this.$parent.method1
如果子组件外层有ui组件包裹,那么子组件使用this.$parent
获取父组件的属性和方法时,有几层ui组件,多几个.$parent
// 父组件
<template>
<div>
<el-dialog>
// 子组件
<dialog-update ref="dialogUpdate" />
</el-dialog>
</div>
</template>
// 子组件的方法中调用父组件的method2方法
this.$parent.$parent.method2
Vue2 + ElementUI 关于$emit用法总结
数据传递总结
- 父组件可以使用 props 把数据传给子组件。
- 子组件可以使用 $emit 触发父组件的自定义事件。
实战:封住客户等级功能的通用表单(支持新增和编辑)
定义封住子组件:levelCommon.vue
<style>
</style>
<template>
<el-dialog :title="title" :visible="visible" size="tiny">
<el-form ref="LevelForm" :model="level" :rules="rules" label-width="80px" >
<el-form-item label="等级名称" prop="name" >
<el-col :span="7">
<el-input v-model="level.name" auto-complete="off" ></el-input>
</el-col>
</el-form-item>
<el-form-item label="等级标识" >
<el-col :span="7">
<el-select v-model="level.mark" value-key="id" prop="mark">
<el-option v-for="item in markArry" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
</el-form-item>
<el-form-item label="等级描述" >
<el-col :span="7">
<el-input v-model="level.introduction" prop="introduction" auto-complete="off"></el-input>
</el-col>
</el-form-item>
</el-form>
<template slot="footer" class="dialog-footer">
<el-button @click="handleVisibleChange(false)">取 消</el-button>
<el-button type="primary" @click="handleSave">确 定</el-button>
</template>
</el-dialog>
</template>
<script>
export default{
name: "LevelForm",
// 用来接收父组件传给子组件的数据
props: {
// 是否显示表单
visible: {
type: Boolean,
default: false
},
// 弹窗的title
title: String,
// 回显数据
model: {
type: Object,
default: null
}
},
data() {
return {
level: {
id: '',
mark: '',
name: '',
introduction: ''
},
rules: {
name: {required: true, message: '请输入姓名', trigger: 'blur'},
mark: {required: true, message: '请输入标记', trigger: 'blur'},
introduction: {required: true, message: '请输入描述', trigger: 'blur'}
},
markArry:[
{
"id": 1,
"name": '启用'
},
{
"id": 2,
"name": '删除'
}
]
}
},
watch: {
// 监听 编辑时回显表单
model(levelInfo) {
this.level = {...levelInfo} // 简单的浅克隆
}
},
methods: {
handleSave() {
// 表单验证 返回数据
this.$refs.LevelForm.validate((valid) => {
if (valid) {
// 调用父类组件相关方法
this.$emit('save', this.level)
// 实体对象重置
this.level ={}
}
})
},
handleVisibleChange(value) {
this.$emit('update:visible', value)
}
}
}
</script>
组件调用
<style>
</style>
<template>
<el-card class="full-height full-width">
<search-table class="full-height full-width"
:table-loading="loading"
:tableData="tableData"
:ref="tableRef"
:labelWidth="'40px'"
:row-keys="row => row.id"
@query="currentPage = 1; query();"
@reset="doReset"
@selectionChange="selectionChange">
<template v-slot:row>
<el-form-item label="名称">
<el-input placeholder="请输入名称" v-model="searchForm.name" clearable></el-input>
</el-form-item>
<el-form-item label="标识">
<el-select placeholder="请选择" v-model="searchForm.mark" clearable>
<el-option :label="'启用'" :value="1"></el-option>
<el-option :label="'删除'" :value="2"></el-option>
</el-select>
</el-form-item>
</template>
<template v-slot:actions>
<el-button size="small" type="primary" v-on:click="addLevel()">新 建</el-button>
<el-button size="small" type="primary" v-on:click="editLevel()">编 辑</el-button>
<el-button size="small" type="primary" v-on:click="handlerDelete()">删除/批量删除</el-button>
</template>
<template >
<el-table-column :reserve-selection="true" type="selection" width="55" />
<el-table-column prop="name" label="名称" show-overflow-tooltip />
<el-table-column prop="mark" label="标识" :formatter="formatMarkType" show-overflow-tooltip />
<el-table-column prop="introduction" label="描述" show-overflow-tooltip />
</template>
<template v-slot:footer>
<el-pagination
background
:current-page="currentPage"
:page-sizes="pageSizes"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</template>
</search-table>
<levelCommon
title="新增客户等级"
:visible.sync="dialogFormAdd"
@save="add" // 执行父类组件的add 方法
></levelCommon>
<levelCommon
:model="level"
title="修改客户等级"
:visible.sync="dialogFormEdit"
@save="edit" // 执行父类组件的edit方法
></levelCommon>
</el-card>
</template>
<script>
import SearchTable from '@/components/searchTable'
import levelCommon from '../levelCommon'
import { Message} from "element-ui";
import {getLevelPage, batchLevelDelete, levelInsert, levelGetById, levelUpdate} from "@/api/level";
export default{
name: 'customer',
components: {
SearchTable,
levelCommon
},
data () {
return {
tableData: [],
loading: false,
tableRef: 'tableRef',
searchForm: {},
currentPage: 1,
pageSizes: [10, 20, 50],
pageSize: 10,
total: 0,
selectionList:[], //定义删除/批量删除
dialogFormAdd:false,
dialogFormEdit: false,
level:{
id: '',
name: '',
introduction: '',
mark: ''
},
markArry:[{
"id": 1,
"name": "启用"
},{
"id": 2,
"name": "删除"
}],
};
},
created() {
this.query()
},
methods: {
query() {
// 请求表格数据
var params ={
'pageNum': this.currentPage,
'pageSize': this.pageSize,
'name':this.searchForm.name,
'mark':this.searchForm.mark
}
getLevelPage(params).then(res => {
console.log(res)
// 把请求到的数据给testDatas数组
this.tableData = res.data.list
// 当前页数
this.currentPage = res.data.pageNum
// 当前页数量
this.pageSize = res.data.pageSize
// 分页总数
this.total = res.data.total
// console.log(JSON.stringify(res.data.data.total))
})
.catch((error) => {
console.log(error)
})
},
doReset() {
// 重置搜索条件
// 请求表格数据
this.tableData = [];
this.restForm();
this.query();
},
restForm(){
this.searchForm.name = ""
this.searchForm.mark = ""
},
selectionChange(val) {
// 表格选项发生变化
console.log("触发表格事件")
this.selectionList = []
val.forEach(element => {
this.selectionList.push(element.id)
});
},
handlerDelete(){
// 数组转字符串使用逗号分隔
let sids = this.selectionList.join(",")
var params ={
'sids': sids
}
batchLevelDelete(params).then(res =>{
Message({
message: '批量删除成功',
type: 'success',
duration: 3 * 1000
})
// 重新查询表格
this.query()
}).catch((error) => {
console.log(error)
})
},
handleSizeChange(val) {
// 改变每页条数
this.pageSize = val
this.query()
},
handleCurrentChange(val) {
// 切换页码
this.currentPage = val
this.query()
},
// table 数据转换
formatMarkType(row, column){
if(row.mark === 1){
return '启用'
} else if(row.mark === 2) {
return '删除'
} else {
return ''
}
},
// 新增客户
addLevel(){
this.dialogFormAdd = true
this.level = {}
},
// 修改客户
editLevel(){
let id = this.selectionList[0]
var params = {
'id' : id
}
levelGetById(params).then(res =>{
//
this.level = {}
this.level = res.data
this.dialogFormEdit = true
}).catch((error) => {
console.log(error)
})
},
add(level){
console.log(level)
levelInsert(level).then(res =>{
Message({
message: '客户等级新增成功',
type: 'success',
duration: 3 * 1000
})
// 新增弹出框隐藏
this.dialogFormAdd = false
// 重新查询表格
this.query()
}).catch((error) => {
console.log(error)
})
},
edit(level){
levelUpdate(level.id, level).then(res =>{
Message({
message: '客户等级修改成功',
type: 'success',
duration: 3 * 1000
})
// 新增弹出框隐藏
this.dialogFormEdit = false
// 重新查询表格
this.query()
}).catch((error) => {
console.log(error)
})
}
}
}
</script>
以上是关于vue把el-dialog提取出来作为子组件,并实现父组件和子组件相互传值的主要内容,如果未能解决你的问题,请参考以下文章
Vue——每次弹出el-dialog,都会执行mounted