在Vue 2中,命令式组件指的是通过Vue的API直接创建和操作的组件实例,而非在模板中声明式使用的组件。
使用场景:动态创建、挂载和卸载的,如模态框、提示信息等。
简单的说,就是,在父组件或其他地方,你可以使用
Vue.extend()
和new
关键字创建组件构造器,然后实例化这个构造器并挂载到DOM上,此时可以访问和调用组件内部的函数。
代码复制可运行
一、父组件,简单的引个方法
<!--
命令式组件:父组件
CommandBaseComponent.vue
-->
<template>
<div>
<el-button @click="clickHandler">显示提示框</el-button>
</div>
</template>
<script>
import { showMsg } from "./components/commandBaseComponents/showMsg";
export default {
methods: {
clickHandler() {
// 调用js文件方法并传参
const close = showMsg('确认要提交该信息吗?',
() => {
// ToDo一些请求
this.uploadMsg()
close()
},
() => {
close()
})
},
uploadMsg() {
console.log('uploadMsg');
}
}
};
</script>
二、 js文件
// 命令式组件:js文件 showMsg.js
// 引入子组件
import MessageBox from "./MessageBox.vue";
// 引入Vue
import Vue from 'vue'
export function showMsg(msg, confirm, cancel) {
// 使用Vue.extend创建一个组件构造器,相当于拷贝了一份组件
const MessageBoxConstructor = Vue.extend(MessageBox);
// 创建组件实例,进行传参
const instance = new MessageBoxConstructor({
// 传递数据
propsData: {
msg: msg, // 假设MessageBox组件需要一个msg,子组件用prop接收
onClick: (clickType) => { // 方法也传给子组件,子组件用prop接收
if (clickType === 'onComfirm') {
confirm()
} else if (clickType === 'onCancle') {
cancel()
}
}
},
});
// 创建一个新的div元素
const div = document.createElement('div');
// 将div添加到body中
document.body.appendChild(div);
// 挂载组件实例到div上
instance.$mount(div);
return () => {
// 如果你的组件是一个对话框或类似需要手动关闭的,你可能还需要处理它的生命周期或提供一个关闭方法
// 例如,你可以在这里监听组件的某些事件来决定何时卸载它
instance.$el.remove(); // 关闭时从DOM中移除div
instance.$destroy(); // 销毁Vue实例
}
}
三、子组件,一个简单的弹窗
<!--
命令式组件:子组件
MessageBox.vue -->
<template>
<div class="mark">
<div class="dialog">
<div class="body">{{ msg }}</div>
<div class="footer">
<el-button size="small" type="primary" @click="setEvent('onComfirm')">提交</el-button>
<el-button size="small" @click="setEvent('onCancle')">取消</el-button>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'MessageBox',
props: {
msg: {
type: String,
required: true
},
onClick: {
type: Function,
default: () => { }
}
},
methods: {
setEvent(type) {
this.onClick(type)
},
},
};
</script>
<style scoped lang="scss">
.mark {
position: fixed;
z-index: 2000;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.3);
.dialog {
width: 30%;
background-color: white;
margin: auto;
margin-top: 15vh;
border-radius: 5px;
.header {
display: flex;
justify-content: space-between;
padding: 15px;
padding-bottom: 5px;
}
.body {
text-align: center;
padding: 15px;
}
.footer {
text-align: right;
padding: 15px;
}
}
}
</style>
主要是解题思想,做个记录,如有不妥,欢迎指正。
不要忽视你达成的每个小目标,它是你前进路上的垫脚石。冲!