Vue Portal (用于vue2的插件)和 Vue3 Teleport (vue3内置特性)是两个可以在vue应用中更方便地控制组件渲染位置的工具
它们都可以将组件渲染到DOM结构的特定位置,而不是跟随父组件的渲染位置
Vue Portal
1、简单易用,Vue Portal是一个独立的插件,可以与vue2无缝集成,无需额外配置
2、可以在任何DOM元素中渲染组件,可以将组件渲染到应用之外的DOM元素中,例如body元素
3、可以通过使用不同的target属性,将组件渲染到不同的DOM元素中
4、对版本有限制,Vue Portal是为vue2设计的
5、需要额外的依赖,Vue Portal需要依赖第三方库portal-vue
Vue Portal使用:
1、安装
npm i `portal-vue`
2、main.js中引入
import PortalVue from 'portal-vue'
Vue.use(PortalVue)
3、PortalVue 包含两个组件,portal组件和portal-target组件,将portal组件中的内容转至portal-target组件所在的地方
1、A父页面中使用portal插件,to就是要去的DOM元素,destination${place}中的place是动态变量,假设值为1
<portal :to="`destination${place}`"
>
//作用域插槽,多个父组件需要传送内容,根据条件动态传送
<div slot-scope="props" v-if="props.value == 'personId'">
<el-form-item
class="customFormItem"
:label="props.label ? `${props.label}:` : '申请人:'"
prop="personId"
>
<el-input
class="options"
type="text"
v-model="form.personId"
/>
</el-form-item>
</div>
</portal>
2、B父页面中使用portal插件,to就是要去的DOM元素,destination${place}中的place是动态变量,假设值为2
<portal :to="`destination${place}`"
>
//作用域插槽,多个父组件需要传送内容,根据条件动态传送
<div slot-scope="props" v-if="props.value == 'empName'">
<el-form-item
class="customFormItem"
:label="props.label ? `${props.label}:` : '领用人:'"
prop="empName"
>
<el-input
class="options"
type="text"
v-model="form.empName"
/>
</el-form-item>
</div>
</portal>
3、子组件中使用portal-target,name就是传送地点, :name="destination${template.place}
"中的place动态接收,假设A组件传过来的是1,即A组件portal包裹的内容将放在portal-target内, :name=“destination1
”,假设B组件传过来的是2,即A组件portal包裹的内容将放在portal-target内, :name=“destination2
”,很好理解吧
<template>
<div class="formItem">
<portal-target //示例中A组件或B组件portal包裹的内容显示在这里
v-if="template.isSend"
:name="`destination${template.place}`"
:slot-props="{ disabled, ...template }"
multiple
></portal-target>
<el-form-item
v-else
ref="formItem"
:label="template.label + ':'"
:prop="template.value"
:title="template.label + ':'"
:style="{
width: template.editor === 'el-input-textarea' ? '80%' : '45.8%',
}"
>
<el-input
class="options"
type="text"
v-model="template.value"
/>
</el-form-item>
</div>
</template>
vue 3 Teleport
1、vue3的内置特性,不需要额外的依赖
2、语法简洁,Vue3 Teleport 有一个简洁的语法来标记要将组件渲染到的位置
3、更好的性能,Vue3 Teleport的渲染机制得到了改进
4、仅适用于vue3项目
5、需要更多配置,在一些复杂场景下,可能需要更复杂的配置
vue 3 Teleport使用
<template>
<teleport to="body">
<MyTooltip v-if="isTooltipOpen" />
</teleport>
<button @click="toggleTooltip">Toggle Tooltip</button>
</template>
<script>
import { ref } from 'vue';
export default {
components: {
Teleport,
MyTooltip,
},
setup() {
const isTooltipOpen = ref(false);
const toggleTooltip = () => {
isTooltipOpen.value = !isTooltipOpen.value;
};
return {
isTooltipOpen,
toggleTooltip,
};
},
};
</script>
【vue3】Teleport 示例:
假设有一个三级嵌套的组件结构
App.vue
<template>
<div class="app">
<h3>我是APP组件</h3>
<child />
</div>
</template>
<script setup lang="ts">
</script>
<style >
.app {
background-color: grey;
padding: 10px;
}
</style>
child.vue
<template>
<div class="child">
<h3>我是child组件</h3>
<myson />
</div>
</template>
<script >
import { ref } from "vue";
export default {
name: "child",
};
</script>
<style scoped >
.child {
background: pink;
padding: 10px;
}
</style>
myson.vue
<template>
<div class="myson">
我是myson 组件
<Dialog />
</div>
</template>
<script setup lang="ts">
</script>
<style scoped >
.myson {
background: rgb(43, 198, 226);
padding: 10px;
}
</style>
Dialog.vue
<template>
<div>
<button @click="isShow = true">点我显示</button>
<div class="dialog" v-if="isShow">
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<button @click="isShow = false">点我隐藏</button>
</div>
</div>
</template>
<script>
import { ref } from "vue";
export default {
name: "dialog",
setup() {
let isShow = ref(false);
return {
isShow,
};
},
};
</script>
<style >
.dialog {
width: 300px;
height: 300px;
background-color: green;
}
</style>
在myson组件中再引入一个类似于弹窗的组件,每次切换显示与隐藏的时候,弹窗组件的内容会撑开所有组件的高度
弹窗组件包裹在三层组件内
如果想修改弹窗的位置,开启定位的话,定位是针对父元素,光是一层一层往上定位,如果中间还有别的定位,最后就会很容易把弹窗的位置定偏了
用Teleport组件可以把弹窗传送走,你想让它在谁下面就可以在谁的下面直接展示:文章来源:https://www.toymoban.com/news/detail-639069.html
<template>
<div>
<button @click="isShow = true">点我显示</button>
<teleport to="body">
<div class="dialog" v-if="isShow">
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<div>内容</div>
<button @click="isShow = false">点我隐藏</button>
</div>
</teleport>
</div>
</template>
<script>
import { ref } from "vue";
export default {
name: "dialog",
setup() {
let isShow = ref(false);
return {
isShow,
};
},
};
</script>
<style >
.dialog {
width: 300px;
height: 300px;
background-color: green;
}
</style>
用了teleport传送到body之后,dialog与app就是平级的关系了
除了传送到body,还可以选择css选择器进行传送
文章来源地址https://www.toymoban.com/news/detail-639069.html
到了这里,关于【vue2】Vue Portal 和【vue3】Teleport的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!