前言
三月份了,金三银四了吗,答案是没有,公司的项目还是那样的让人乏味,走也走不掉,学也学不起来,那就看看视频吧,今天看到一个视频是讲vue3中的Teleport,今天就来简单的了解下。
Teleport介绍
Teleport按照英文字面的意思是:远距离传送,他的作用是将一个组件传送到指定的位置。
网上有很多的例子来讲这个Teleport,最明显的例子就是弹框,这里简单的介绍下。
用到的文件有三个,app.vue HelloWorld.vue test1.vue
app.vue
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
components: {HelloWorld},
}
</script>
<template>
<div>疯狂星期四</div>
<HelloWorld msg="Vite + Vue"/>
</template>
HellWorld.vue
<script>
import { ref,defineComponent } from 'vue'
import test1 from './test1.vue'
export default defineComponent({
components: {test1},
setup(props, content) {
const show_test1 = ref(false);
const getparam = (val) => {
show_test1.value = val
}
return {show_test1, getparam}
}
})
</script>
<template>
<div>
世界之大,无奇不有
<button @click="show_test1 = !show_test1">显示或隐藏组件test1</button>
<test1 v-show="show_test1" @Tohidden_test1="getparam"></test1>
</div>
</template>
<style scoped>
.read-the-docs {
color: #888;
}
</style>
test1.vue
<template>
<div id="test1">
这是测试组件test1
<br/>
<button @click="hidden_test1">隐藏组件1</button>
</div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
setup(props,content){
const hidden_test1 = ()=>{
content.emit('Tohidden_test1',false)
}
return{ hidden_test1 }
}
})
</script>
<style scoped>
#test1{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #747bff;
}
</style>
默认显示页面如下:
当点击"显示或隐藏组件test1"时,页面如下:
点击”隐藏组件1"又会和默认显示的页面一样。这样的一个弹框看似没有什么太大的毛病,那就一定是有问题的
加入我们给父组件HellWorld添加一层蒙版,让他变得模糊时,页面是这样的。
HellWorld.vue:
<script>
import { ref,defineComponent } from 'vue'
import test1 from './test1.vue'
export default defineComponent({
components: {test1},
setup(props, content) {
const show_test1 = ref(false);
const getparam = (val) => {
show_test1.value = val
}
return {show_test1, getparam}
}
})
</script>
<template>
<div id="add_opacity">
世界之大,无奇不有
<button @click="show_test1 = !show_test1">显示或隐藏组件test1</button>
<test1 v-show="show_test1" @Tohidden_test1="getparam"></test1>
</div>
</template>
<style scoped>
.read-the-docs {
color: #888;
}
#add_opacity{
opacity: 0.3;
}
</style>
当点击"显示或隐藏组件test1"时,页面如下:
很显然的这层蒙版影响到了子组件test1的显示。
这个时候就到了Teleport大显身手的时候了,我们可以利用它来与app.vue页面保持在一个等级。
首先是index.html中添加一个id为test_Teleport的div
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
<div id="test_Teleport"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
修改test1中的代码如下:
<template>
<Teleport to="#test_Teleport">
<div id="test1">
这是测试组件test1
<br/>
<button @click="hidden_test1">隐藏组件1</button>
</div>
</Teleport>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
setup(props,content){
const hidden_test1 = ()=>{
content.emit('Tohidden_test1',false)
}
return{ hidden_test1 }
}
})
</script>
<style scoped>
#test1{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #747bff;
}
</style>
这样我们就能保证当前的弹框是在最顶层的,与#app是在同一级的。
效果如下:
动态传送位置,状态不发生改变
HelloWorld.vue
<script>
import { ref,defineComponent } from 'vue'
import test1 from "./test1.vue";
export default defineComponent({
components: {test1},
setup(props, content) {
const show_test1 = ref(false);
const direction = ref('#one');
const changeDirection = () => {
show_test1.value = true
if (direction.value == '#one') {
direction.value = '#two';
} else {
direction.value = '#one';
}
}
return {show_test1, direction, changeDirection}
}
})
</script>
<template>
<div>世界之大,无奇不有</div>
<button @click="changeDirection">改变传送放向</button>
<test1 :param="direction" v-if="show_test1"></test1>
<div id="one">1</div>
<div id="two">2</div>
</template>
<style scoped>
.read-the-docs {
color: #888;
}
#one{
height: 200px;
width: 400px;
border: 1px solid black;
}
#two{
height: 200px;
width: 400px;
border: 1px solid lightgray;
}
</style>
test1.vue
<template>
<Teleport :to="params">
<div id="test">
<div>⏲计时开始:{{ number }}</div>
</div>
</Teleport>
</template>
<script>
import {defineComponent, ref, onMounted, defineProps,watch } from "vue";
export default defineComponent({
props: {
param: {
type: String,
default: '#one'
}
},
setup(props, content) {
const number = ref(0);
const params = ref(props.param);
watch(() => props.param, () => {
params.value = props.param
})
onMounted(() => {
setInterval(() => {
number.value++;
}, 1000)
})
return {number, params}
}
})
</script>
<style scoped>
#test {
width: 300px;
height: 300px;
}
</style>
页面效果如下:
当点击:改变传送方向时,计时器不会从零开始,依然保持原有的状态。
Teleport属性disabled,当值为tue时不发生传送,当值为false时发生传送