场景
vue + elementUi框架做后台管理系统时,需要使用弹出框 新增/编辑 内容时,可以将el-dialog二次封装,使代码简洁易维护。
子组件 addDialog.vue:
<template>
<div>
<el-dialog
title="新增"
:visible.sync="show"
@close="$emit('update:visible', false)"
>
<el-form>
<el-form-item label="姓名">
<el-input v-model="name" />
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
export default {
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
name: ' ',
show: this.visible,
};
},
watch: {
visible(val) {
this.show = val;
}
}
}
</script>
复制代码
父组件中使用:
<template>
<div>
<button @click="handleAdd">打开/关闭</button>
<addDialog :visible.sync="addshow" />
</div>
</template>
<script>
import addDialog from "./addDialog.vue";
export default {
components: { addDialog },
data() {
return {
addshow: false,
};
},
methods: {
handleAdd() {
this.addshow = true;
}
}
};
</script>
复制代码
在子组件中不能直接使用 props 的 visible来控制显示与隐藏,需要一个中间值 show 来控制。因为 el-dialog 关闭时会设置 visible 的值,子组件直接更改 props 的值会报错
[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"
所以,实现的思路是 父组件传递的参数添加 .sync
修饰,子组件中关闭弹框时使用 $emit('update:visible', false)
这样更改父组件中传递的 visible
的值,子组件中watch
到visible
改变,就改变中间值show
达到关闭的目的。
另外 <addDialog :visible.sync="addshow" />
中 .sync
是下面代码的语法糖
<addDialog
:visible="addshow"
@update:visible="newVal => addshow = newVal"
/>
复制代码
有 新增/修改 使用同一个弹出框的需求时,需要动态修改dialog中的内容,可以给子组件传递其他参数,在子组件watch中监听。之所以用watch监听,是因为子组件渲染只会执行一次created生命周期,如果非要将更改内容写在created中,就要配合 v-if 使用,将子组件用 v-if 包裹起来,每次都重新加载子组件,此时可以达到动态修改dialog内容的需求,但是el-dialog弹出的动画效果会消失。