2021-03-10
Posted bywayboy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-03-10相关的知识,希望对你有一定的参考价值。
vue3.0 动态创建组件
缘起
有时候, 我们希望组件在我们任何需要的时候呼之即来,而不是固定在html的DOM中.
在 element-plus中 是事先通过 el-dialog 定义 然后 控制起是否可见来决定对话框的弹出还是隐藏。
这在涉及复杂逻辑可能会不太方便。
设想中的写法:
import LocMarkDialog from 'LocMarkDialog.vue'
///省略代码 ....
let proxy = getCurrentInstance();
proxy.$mount(LocMarkDialog).then(res)=>
//点击了确定
).catch(()=>
//点击了取消
MyDialog 组件并不写在<template></template> 标签中,而是在任何业务需要的地方临时创建,并且在使用完后自动销毁.
组件的实现代码:
import markRaw, ref, createVNode, defineComponent from 'vue'
let componentMap = ref([])
let id=0;
const factory = defineComponent(
props:
,
render()
var children = componentMap.value.map((item, i)=>createVNode(item.c, item.p))
return createVNode('div', class:'ui-app-component-container', children);
,
setup(props)
return
componentMap
,
install(app)
app.component('CompFactory', factory);
app.config.globalProperties.$mount = (comp, props) =>
return new Promise((resolve, reject)=>
let p = props || ;
Object.assign(p, q:resolve, reject, _compId: id++, finish:(id)=>
let ret = componentMap.value.findIndex(v=>v.p.id===id)
if(ret >=0)
componentMap.value.splice(ret, 1);
);
console.log('mount component.', comp);
componentMap.value.push(c:markRaw(comp), p);
)
)
export default factory;
用法
第一步: 首先全局引入组件
// 引入前面写的组件
import CompFactory from '/@/uiframe/layout/components/CompFactory.vue'
const app = createApp(App);
app.use(CompFactory)
第二步: 在全局使用一次组件
这么做的目的是在document 中创建一个容器节点.
App.vue
<CompFactory></CompFactory>
第三步: 如何使用
定义一个对话框组件
<template>
<el-dialog custom-class="ui-loc-mark-dialog ui-dialog-autow" v-model="dialogVisible" destroy-on-close :modal="true" @closed="finalThings" title="地理位置标注">
<BaiduMap :location="location" width="100%" height="100%"></BaiduMap>
<template #footer>
<el-button type="primary" size="mini" @click="onSure">保存</el-button>
<el-button size="mini" @click="onCancel">取消</el-button>
</template>
</el-dialog>
</template>
<script>
import ref from '@vue/reactivity';
import BaiduMap from '/@/uiframe/layout/components/BaiduMap.vue'
import onUnmounted from '@vue/runtime-core';
import LocMarkDialog from '/@/uiframe/layout/components/LocMarkDialog.vue'
export default
components:
BaiduMap
,
props:
q:Object, //这里是 resolve 和reject
_compId:Number, //这里是组件id
finish:Function, //这里是组件销毁后的回调。
location: type:Object, default:lng:113.97, lat:28.36300,
,
setup(props, ctx)
let dialogVisible = ref(true); //对话框默认显示
const onCancel = ()=>
dialogVisible.value = false;
props.q.reject('cancel');
const onSure = ()=>
dialogVisible.value = false;
props.q.resolve(success:true);
//对话框销毁后, 通知CompFactory 销毁节点.
const finalThings = ()=>
props.finish(props.id);
onUnmounted(()=>
console.log('bye!');
)
return
location:props.location,
dialogVisible,
onCancel,
onSure,
finalThings
</script>
<style lang="scss">
.ui-loc-mark-dialog .el-dialog__body
height: 23rem;padding:.5rem;
</style>
以上是关于2021-03-10的主要内容,如果未能解决你的问题,请参考以下文章