【vue2】Vue Portal 和【vue3】Teleport

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>

猜你喜欢

转载自blog.csdn.net/weixin_49668076/article/details/132217311