封装一:只把弹窗封装成一个单独的组件
1. 弹窗组件 my-dialog.vue
<template>
<el-dialog
title="选择水果"
:visible.sync="dialogVisible"
width="30%"
@close="handleClose"
>
<el-checkbox-group v-model="checkList">
<el-checkbox
v-for="it in optionList"
:key="it.value"
:label="it.value"
>{{it.text}}</el-checkbox>
</el-checkbox-group>
<span slot="footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</template>
<script>
export default {
props: {
visible: Boolean,
},
data () {
this.optionList = [
{ value: 'apple', text: '苹果' },
{ value: 'orange', text: '橘子' },
{ value: 'pear', text: '梨' },
]
return {
dialogVisible: this.visible,
checkList: [],
};
},
methods: {
handleClose() {
this.$emit('update:visible', false);
}
},
}
</script>
<style>
</style>
2. 点击的按钮所在的业务组件
<template>
<div>
<!-- 其他业务 -->
<!-- 其他业务 -->
<!-- 其他业务 -->
<el-button type="primary" @click="visible = true">显示弹窗</el-button>
<MyDialog
v-if="visible"
:visible.sync="visible"
/>
</div>
</template>
<script>
import MyDialog from '../components/my-dialog.vue';
export default {
name: "Home",
data() {
return {
visible: false,
}
},
components: {
MyDialog,
},
};
</script>
优点:弹窗组件上可以加v-if,就可以不用手动去初始化data数据了。
缺点:按钮和弹窗没有跟业务代码混在一起,没有完全解耦。
封装二:按钮 + 弹窗 封装在同一个组件里
1. 按钮 + 弹窗组件 show-dialog-btn.vue
<template>
<span>
<slot :show="show"></slot>
<el-dialog
title="选择水果"
:visible.sync="dialogVisible"
width="30%"
>
<el-checkbox-group v-model="checkList">
<el-checkbox
v-for="it in optionList"
:key="it.value"
:label="it.value"
>{{it.text}}</el-checkbox>
</el-checkbox-group>
<span slot="footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</span>
</template>
<script>
export default {
data () {
this.optionList = [
{ value: 'apple', text: '苹果' },
{ value: 'orange', text: '橘子' },
{ value: 'pear', text: '梨' },
];
// 初始化的data
this.initData = {
checkList: [],
}
return {
dialogVisible: false,
...JSON.parse(JSON.stringify(this.initData)),
};
},
methods: {
show() {
this.dialogVisible = true;
},
},
watch: {
dialogVisible(val) {
if (!val) return;
Object.assign(this, JSON.parse(JSON.stringify(this.initData)));
}
},
}
</script>
<style>
</style>
2. 使用组件
<ShowDialogBtn>
<template slot-scope="{show}">
<a @click="show">显示弹窗</a>
</template>
</ShowDialogBtn>
优点:1.?按钮 + 弹窗的整个组件跟业务组件解耦的比较干净。
? ? ? ? ? ?2. 按钮通过 slot 传入,看业务代码的时候也很好知道这个是什么按钮。
缺点:要在组件显示或关闭时手动初始化data数据。
还有一种按钮 + 弹窗封装在一起的方法是,按钮不用 slot 传入,而是直接写在组件里面:
<template>
<span>
<a @click="show">显示弹窗</a>
<el-dialog
title="选择水果"
:visible.sync="dialogVisible"
width="30%"
>
<el-checkbox-group v-model="checkList">
<el-checkbox
v-for="it in optionList"
:key="it.value"
:label="it.value"
>{{it.text}}</el-checkbox>
</el-checkbox-group>
<span slot="footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</span>
</template>
<script>
export default {
data () {
this.optionList = [
{ value: 'apple', text: '苹果' },
{ value: 'orange', text: '橘子' },
{ value: 'pear', text: '梨' },
];
// 初始化的data
this.initData = {
checkList: [],
}
return {
dialogVisible: false,
...JSON.parse(JSON.stringify(this.initData)),
};
},
methods: {
show() {
this.dialogVisible = true;
},
},
watch: {
dialogVisible(val) {
if (!val) return;
Object.assign(this, JSON.parse(JSON.stringify(this.initData)));
}
},
}
</script>
<style>
</style>
<ShowDialogBtn/>
优点:跟业务代码解耦的最彻底。
缺点:1.?一眼看不出这是哪个功能按钮,还要看一下组件里的代码。
? ? ? ? ? ?2.?要在组件显示或关闭时手动初始化data数据。
|