【Vue.js 3.0】Day-18 Vue3 新的组件

1.Fragment —— 片段组件 

  • 在Vue2中: 组件必须有一个根标签。

  • 在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个内置Fragment虚拟元素中, 最后是不参与页面渲染的! 

  • 好处: 减少标签层级, 减小内存占用。

<template>
    <fragment>
      .....
    </fragment>
</template>

2.Teleport——瞬间移动组件 

什么是Teleport?—— Teleport 是一种能够将我们的组件html结构移动到指定位置的技术。

基础语法

<!--to属性的属性值: 是css的选择器 -->
<teleport to="移动位置">
	<div v-if="isShow" class="mask">
		<div class="dialog">
			<h3>我是一个弹窗</h3>
			<button @click="isShow = false">关闭弹窗</button>
		</div>
	</div>
</teleport>

使用场景 ? 

复用 Dialog 组件时 ,html结构会很深层次! 编写Dialog 组件样式、定位等css属性就不容易控制!Teleport 瞬移组件可以把藏的深层次的组件的html结构,给它拎出来,放置到指定节点位置元素下,方便css样式的可控性!

src/components/Dialog.vue

<template>
  <div>
    <button @click="isShow = !isShow">点我谈个窗</button>
   
    <!-- 使用瞬移组件: 将telepor 组件包裹的html结构,瞬移到body节点下  -->
    <teleport to="body">
      <!-- 遮罩层弹窗是一体的给遮罩层上控制、遮罩层显示顺带着弹窗就出来了; 很多ui组件也是这样控制的 -->
      <!-- v-if= false: 代表直接将dom元素节点直接移除 -->
      <div v-if="isShow" class="mask">
        <div class="dialog">
          <h3>我是一个弹窗</h3>
          <h4>我是一下内容</h4>
          <button @click="isShow = !isShow">关闭弹窗</button>
        </div>
      </div>
    </teleport>
  </div>
</template>

<script>
import { ref } from "vue";
export default {
  name: "Dialog",
  // 数据驱动着页面的显示
  setup() {
    let isShow = ref(false);
    return { isShow };
  },
};
</script>

<style scoped>
.mask {
  position: relative;
  /* 将元素撑开 */
  top: 0; bottom: 0; left: 0;right: 0;
  background-color: rgba(0, 0, 0, 0.5);
}
.dialog {
  position: absolute;
  top: 50%;left: 50%;
  transform: translate(-50%, -50%);
  width: 300px;
  height: 300px;
  background-color: pink;
  opacity: 0.7;
  text-align: center;
  border-radius: 10%;
}
</style>

src/components/Son.vue

<template>
  <div class="son">
    <h3>我是Son组件!</h3>
    <!-- 使用Dialog组件, 但是Dialog组件的html 不在.son div的结构下,而是瞬移到了body节点下-->
    <Dialog/>
  </div>
</template>

<script>
import Dialog from './Dialog.vue'
export default {
  name: "Son",
  components: {Dialog}
};
</script>

<style>
.son {
  background-color: orange;
  padding: 10px;
}
</style>

3.Suspense——异步组件

Suspense——Vue3中的新组件,并且官方说这个组件目前属于实验阶段! 以后与这个组件相关的API,或者说一些写法还有可能改!   

Suspense 等待异步组件时渲染一些额外内容,让应用有更好的用户体验。

使用步骤:

1.异步引入组件

import {defineAsyncComponent} from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child.vue'))

2.使用Suspense包裹组件,并配置好defaultfallback

<template>
	<div class="app">
		<h3>我是App组件</h3>
		<Suspense>
			<template v-slot:default>
				<Child/>
			</template>
			<template v-slot:fallback>
				<h3>加载中.....</h3>
			</template>
		</Suspense>
	</div>
</template>

eg:演示案例, 异步加载组件 

src/App.vue

<template>
  <div class="app">
    <h1>我是App组件</h1>
    <!-- 
      Suspense: 异步组件
       1.底层也是用插槽实现的; 
       2.内部准备好了两个插槽, default展示真实放置的内容、
    -->
    <Suspense>
      <!-- 放置真正所展示的组件、注意: 指明插槽名是 default, 因为内部是写了两个插槽  -->
      <template v-slot: default>
        <Child></Child>
      </template>
      <!-- 由于某种原因 Child 组件加载慢了! 就会展示插槽名为 fallback 中的内容信息  -->
      <template v-slot:fallback>
        <h3>加载中,稍等...</h3>
      </template>
    </Suspense>
  </div>
</template>

<script>
// app、child 组件都属于静态组件
import { defineAsyncComponent } from "vue";
/* 
  静态引用 
    解析过程: 只要没有引入 Child 组件成功, 整个App 组件都不进行渲染! 
    缺点: 同步执行代码,会造成阻塞渲染页面白屏!  
*/
// import Child from "./components/Child";

/*
  动态、异步引入
    解析过程: 组件异步加载, 不会阻塞进程!
    缺点: 异步加载成功代码,间接的渲染到页面, 会造成页面的抖动、用户体验效果不好! 
*/
const Child = defineAsyncComponent(() => import("./components/Child"));

export default {
  name: "App",
  components: { Child },
  setup() {},
};
</script>

<style>
.app {
  background-color: gray;
  padding: 10px;
}
</style>

src/components/Child.vue

<template>
  <div class="child">
    <h1>我是Child组件!</h1>
    {{ sum }}
  </div>
</template>

<script>
import {ref} from 'vue'
export default {

  name: "Child",
  setup() {
    let sum = ref(0)
    // 让组件等一等 
    return new Promise((resolve, reject) =>{
      setTimeout(()=>{
        resolve({sum})
      }, 1000)
    })
  }
};
</script>

<style>
.child {
  background-color: skyblue;
  padding: 10px;
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值