原文链接: vue3 teleport 类似 Portal 转移dom和组件
上一篇: 本子里的数学题....
下一篇: react 高阶组件 HOC
https://juejin.im/post/6868260498417123335
和react 的portal一样, 将组件挂载到指定的位置
传入的字符串为作为选择器, 所以尽量使用比较精确的选择器
teleport 有属性disable, 表示是否转移dom
如果转移的dom有css, 注意转移后的层级会变化, 所以会影响css
不仅可以转移dom, 也能够转移组件, 此时最好使用css-scoped
demo 效果, 将组件内的dom, 转移到组件外部
创建项目
npm i @vue/cli -g
vue add vue-next
vue create vue3-cli-demo
虽然报错了, 但是插件可以使用
vue的版本有点低的感觉
yarn add vue@rc
@vue/compiler-sfc
修改hello组件
dom的层级已经发生了变化
调整后的层级对css的影响
<template>
<div class="hello">
<teleport to="body">
<img name="img1" src="../assets/logo.png" alt="" />
</teleport>
<img name="img1" src="../assets/logo.png" alt="" />
</div>
</template>
<script>
export default {
};
</script>
<style>
body img {
background: black;
}
.hello img {
width: 100px;
background: blue;
}
</style>
app.vue
<template>
<HelloWorld />
<div class="rect top"></div>
<div class="rect bottom"></div>
<div class="rect left"></div>
<div class="rect right"></div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld,
},
};
</script>
<style>
html,
body {
padding: 0;
margin: 0;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.rect {
width: 200px;
height: 200px;
border: 1px solid black;
position: absolute;
}
.rect.left {
left: 0;
top: 30%;
}
.rect.top {
left: 0;
top: 0%;
left: 50%;
}
.rect.right {
top: 30%;
right: 0;
}
.rect.bottom {
left: 0;
left: 50%;
bottom: 0;
}
.rect .img {
background: chartreuse;
}
</style>
hello.vue
<template>
<div class="hello">
<teleport :to="target" :disabled="disabeled">
<img class="img" name="img1" src="../assets/logo.png" alt="" />
</teleport>
<div>
<button @click="move('top')">top</button>
<button @click="move('bottom')">bottom</button>
<button @click="move('left')">left</button>
<button @click="move('right')">right</button>
<button @click="move()">disabele</button>
</div>
</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const disabeled = ref(true);
const target = ref(".hello");
const move = (to) => {
console.log("move", to);
if (!to) {
disabeled.value = true;
} else if (to === "top") {
disabeled.value = false;
target.value = ".rect.top";
} else if (to === "left") {
disabeled.value = false;
target.value = ".rect.left";
} else if (to === "right") {
disabeled.value = false;
target.value = ".rect.right";
}else if (to === "bottom") {
disabeled.value = false;
target.value = ".rect.bottom";
}
};
return {
disabeled,
move,
target,
};
},
};
</script>
<style>
.hello .img {
width: 100px;
background: blue;
}
</style>