🐳 引言
关于 MessageBox
弹框,Element UI
官方的介绍是:从场景上来说,MessageBox
的作用是美化系统自带的 alert
、confirm
和 prompt
,因此适合展示较为简单的内容。如果需要弹出较为复杂的内容,请使用 Dialog。不过,MessageBox
是可以自定义配置内容的,因此我想尝试使用 MessageBox
来展示复杂的内容,实现一个公共的全局弹框功能。
🐳 关于$createElement
$createElement
是 Vue
实例上的一个方法,用于创建虚拟节点 VNode
。$createElement
的功能非常强大,它为开发者提供了极大的灵活性。这里我们主要简要介绍一些常用的使用方法,了解其核心功能和应用场景。
1. 创建dom元素
首先,通过 $createElement
实现自定义配置内容,我希望将一个 list
数组中的内容渲染到 MessageBox
中。代码如下:
msgBox.vue
<script>
export default {
name: "msgBox",
data() {
return {
list: [
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1517 弄"
},
{
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄"
}
]
};
},
mounted() {
this.init();
},
methods: {
init() {
const h = this.$createElement;
this.$msgbox({
title: "自定义弹框",
showCancelButton: true,
message: h("div", null, [
this.list.map(item => {
return h("div", { class: "msg-item" }, [
h("div", null, item.name),
h("div", null, item.date),
h("div", null, item.address)
]);
})
])
});
}
}
};
</script>
<style lang="scss" scoped>
.msg-item {
display: flex;
align-items: center;
justify-content: space-between;
height: 45px;
padding: 10px;
}
</style>
2. 加载Element UI组件
上面我们仅演示了如何通过$createElement
加载简单的dom
元素,但现在我希望进一步利用$createElement
来加载Element-UI
中的组件。代码如下:
msgBox.vue
<script>
import { Collapse } from "element-ui";
import { CollapseItem } from "element-ui";
export default {
name: "msgBox",
components: {
Collapse,
CollapseItem
},
data() {
return {
activeNames: ["1"],
list: [
{
id: "1",
title: "一致性 Consistency",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 1"
},
{
id: "2",
title: "反馈 Feedback",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 2"
},
{
id: "3",
title: "效率 Efficiency",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 3"
},
{
id: "4",
title: "可控 Controllability",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 4"
}
]
};
},
mounted() {
this.init();
},
methods: {
init() {
const h = this.$createElement;
this.$msgbox({
title: "自定义弹框",
showCancelButton: true,
message: h("div", null, [
h(
Collapse,
{
props: { value: this.activeNames },
on: {
change: this.handleChange
}
},
[
this.list.map(item => {
return h(
CollapseItem,
{
props: {
name: item.id,
title: item.title
}
},
[h("div", null, [h("p", null, item.content)])]
);
})
]
)
])
});
},
handleChange(val) {
console.log(val);
}
}
};
</script>
3. 加载自定义组件
如果采用上述方法来加载Element-UI
中的组件显得过于繁琐,这并非我所期望的效果。既然$createElement
能够用于加载组件,我们便可以在公共组件中编写代码,进而通过$createElement
来加载这些自定义的公共组件。
创建一个公共组件,代码如下:
demo.vue
<template>
<div class="content">
<el-collapse v-model="activeNames" @change="handleChange">
<el-collapse-item
v-for="item in list"
:key="item.id"
:title="item.title"
:name="item.id"
>
<div>{{ item.content }}</div>
</el-collapse-item>
</el-collapse>
<div>
<div class="msg-item" v-for="item in list" :key="item.id">
<div>{{ item.id }}</div>
<div>{{ item.title }}</div>
<div>{{ item.content }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "demo",
props: {
initData: {
type: Object,
default: () => {}
}
},
data() {
return {
activeNames: ["1"],
list: [
{
id: "1",
title: "一致性 Consistency",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 1"
},
{
id: "2",
title: "反馈 Feedback",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 2"
},
{
id: "3",
title: "效率 Efficiency",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 3"
},
{
id: "4",
title: "可控 Controllability",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 4"
}
]
};
},
methods: {
handleChange(val) {
console.log(val);
}
}
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
padding: 10px;
background: #fff;
.msg-item {
display: flex;
align-items: center;
justify-content: space-between;
height: 45px;
padding: 10px;
}
}
</style>
在MessageBox中使用公共组件,代码如下:
msgBox.vue
<script>
import Demo from "./demo.vue";
export default {
name: "msgBox",
components: {
Demo
},
data() {
return {};
},
mounted() {
this.init();
},
methods: {
init() {
const h = this.$createElement;
this.$msgbox({
title: "自定义弹框",
showCancelButton: true,
message: h(Demo)
});
}
}
};
</script>
🐳 封装自定义MessageBox
为了提升代码的复用性和开发效率,我计划将之前通过 $createElement
加载自定义公共组件的逻辑进行封装,将其转化为一个全局公共方法。通过这种方式,我们可以实现一个通用的全局弹框功能,从而在项目的任何地方轻松调用,避免重复代码,同时增强代码的可维护性和一致性。代码如下:
- 挂载全局方法,代码如下:
main.js
Vue.prototype.msgBox = function(props) {
const h = this.$createElement
this.$msgbox({
title: props.title || '提示',
showCancelButton: props.showBtns || false,
showConfirmButton: props.showBtns || false,
closeOnClickModal: false,
closeOnPressEscape: false,
customClass: 'msg-container',
message: h('div', { style: { height: props.height || 'auto', width: props.width || 'auto', overflow: 'auto' } }, [
h(props.component, { props: { initData: { ...props.initData } } }) // 调用组件传入的值
])
})
}
- 修改公共组件,代码如下:
demo.vue
<template>
<div class="content">
<el-collapse v-model="initData.activeNames" @change="handleChange">
<el-collapse-item
v-for="item in list"
:key="item.id"
:title="item.title"
:name="item.id"
>
<div>{{ item.content }}</div>
</el-collapse-item>
</el-collapse>
<div>
<div class="msg-item" v-for="item in list" :key="item.id">
<div>{{ item.content }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "demo",
props: {
initData: {
type: Object,
default: () => {}
}
},
data() {
return {
list: [
{
id: "1",
title: "一致性 Consistency",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 1"
},
{
id: "2",
title: "反馈 Feedback",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 2"
},
{
id: "3",
title: "效率 Efficiency",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 3"
},
{
id: "4",
title: "可控 Controllability",
content:
"与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念 4"
}
]
};
},
methods: {
handleChange(val) {
console.log(val);
}
}
};
</script>
<style lang="scss" scoped>
.content {
width: 100%;
height: 100%;
background: #fff;
.msg-item {
display: flex;
align-items: center;
justify-content: space-between;
height: 45px;
padding: 10px;
}
}
</style>
- 在MessageBox中使用封装的全局函数,代码如下:
msgBox.vue
<template> </template>
<script>
import Demo from "./demo.vue";
export default {
name: "msgBox",
components: {
Demo
},
data() {
return {
activeNames: ["1"]
};
},
mounted() {
this.init();
},
methods: {
init() {
this.msgBox({
title: "自定义弹框",
width: "600px",
height: "400px",
component: Demo,
initData: {
activeNames: this.activeNames
}
});
}
}
};
</script>
<style>
.msg-container {
width: auto; /* 将最外层的宽度限制去掉 */
}
</style>
最终效果如下:
以上就是本次分享的全部内容。目前这里还只是一个初步的版本,并非最终的完整形态。我将在未来的分享中继续完善和补充更多细节,敬请期待!
🐳 文章小尾巴
感谢你看到最后,最后再说两点~
①如果你持有不同的看法,欢迎你在文章下方进行留言、评论。
②如果对你有帮助,或者你认可的话,欢迎给个小点赞,支持一下~
我是程序员张张,一个热爱编程也爱生活的程序员
(文章内容仅供学习参考,如有侵权,非常抱歉,请立即联系作者删除。)