Vue3 新的组件

news/2024/7/10 2:51:19 标签: vue

文章目录

  • fragment组件
  • teleport组件
  • Suspence组件

fragment组件

在Vue2中:组件必须有一个根标签
在Vue3中:组件可以没有根标签,内部会将多个标签包含在一个 Fragment 虚拟元素中
好处:减少标签层级,减小内存占用

teleport组件

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

<teleport to="移动位置">
	<div v-if="isShow" class="mask">
		<div class="dialog">
			<h3>我是一个弹窗</h3>
			<button @click="isShow = false">关闭弹窗</button>
		</div>
	</div>
</teleport>

我们先做这样一个效果
在这里插入图片描述

App.vue

<template>
  <div class="app">
    <h3>我是App组件</h3>
    <Child/>
  </div>
</template>

<script>
import Child from "@/components/Child";

export default {
  name: 'App',
  components: {Child}
}
</script>

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

Child.vue

<template>
  <div class="child">
    <h3>我是Child组件</h3>
    <Son/>
  </div>
</template>

<script>
import Son from "@/components/Son";

export default {
  name: 'Child',
  components: {
    Son
  }
}
</script>

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

Son.vue

<template>
  <div class="son">
    <h3>我是Son组件</h3>
    <Dialog/>
  </div>
</template>

<script>
import Dialog from "@/components/Dialog";

export default {
  name: 'Son',
  components: {
    Dialog
  }
}
</script>

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

Dialog.vue

<template>
  <div>
    <button @click="isShow = true">点我弹个窗</button>
    <div class="dialog" v-if="isShow">
      <h3>我是弹框</h3>
      <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: 100px;
  height: 100px;
  background-color: green;
}
</style>

可以看到当 Son 中的 Dialog 展开时,所有父组件都被撑开了,我们可以用 teleport 将弹框移动到 body 里,展示到屏幕中间

在这里插入图片描述

<template>
  <div>
    <button @click="isShow = true">点我弹个窗</button>
    <teleport to="body">
      <div class="mask"  v-if="isShow">
        <div class="dialog" v-if="isShow">
          <h3>我是弹框</h3>
          <button @click="isShow = false">关闭弹框</button>
        </div>
      </div>
    </teleport>
  </div>
</template>

<script>
import {ref} from 'vue'

export default {
  name: 'Dialog',
  setup() {
    let isShow = ref(false)
    return {isShow}
  }
}
</script>

<style>
.dialog {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%);
  text-align: center;
  width: 100px;
  height: 100px;
  background-color: green;
}

.mask {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: rgb(0, 0, 0, 0.5);
}
</style>

Suspence组件

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

使用步骤:
1、异步引入组件

import {defineAsyncComponent} from "vue";//动态引入
const Child = defineAsyncComponent(()=>import('./components/Child'))

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

<template>
  <div class="app">
    <h3>我是App组件</h3>
    <suspense>
      <template #default>
        <Child/>
      </template>
      <template #fallback>
        <h3>加载中......</h3>
      </template>
    </suspense>
  </div>
</template>

首先演示下异步插件。App 内异步引入 Child 组件

<template>
  <div class="app">
    <h3>我是App组件</h3>
    <Child/>
  </div>
</template>

<script>
//静态引入
//import Child from "@/components/Child";
import {defineAsyncComponent} from "vue";//动态引入
const Child = defineAsyncComponent(()=>import('./components/Child'))

export default {
  name: 'App',
  components: {Child}
}
</script>

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

为了清楚的看到效果,我们把网络调成高速3G,然后刷新页面,可以很清楚的看到 App组件先展示出来,然后 Child 组件才展示
在这里插入图片描述
这样体验不是太好,我们可以使用 suspence 来解决这个问题,Suspense 是 Vue3 推出的一个内置的特殊组件,有两个 template slot,刚开始会渲染一个 fallback 内容,直到达到某个条件以后才会渲染正式的内容

修改 App.vue 中代码:

<template>
  <div class="app">
    <h3>我是App组件</h3>
    <suspense>
      <template #default>
        <Child/>
      </template>
      <template #fallback>
        <h3>加载中......</h3>
      </template>
    </suspense>
  </div>
</template>

在这里插入图片描述
刚才除了把网速调慢可以让 Child 晚一点加载出来,或者修改 Child.vue

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

<script>
import {ref} from "vue"

export default {
  name: 'Child',
  async setup() {
    let sum = ref(0)
    let p = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({sum})
      }, 2000)
    })
    return await p;
  }
}
</script>

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

在这里插入图片描述


http://www.niftyadmin.cn/n/1816669.html

相关文章

详解C语言实现哈夫曼编码压缩

更新 这个项目是大一写的&#xff0c;现在大三了&#xff0c;将它重新实现了一下&#xff08;语义化、整洁性、健壮性、扩展性更好&#xff09;。 新的链接在这里手把手教你C语言哈夫曼压缩/解压缩 下面的都是以前写的&#xff0c;比较笨拙&#xff0c;但保留了原始的思路。…

Vue3中其他的改变

文章目录vue2 和 vue3生命周期对比全局API的转移其他改变vue2 和 vue3生命周期对比 图片来源 注意观察最后 beforeDestroy和destroyed 改为了 beforeUnmount和unmounted 与 2.x 版本生命周期相对应的组合式 API beforeCreate -> 使用 setup() created -> 使用 setup()…

Python实现QQ模拟登录

用了pyautogui库&#xff0c;扩展参数confidence依赖opencv-python库 然后用py2exe打包成可执行文件即可。 可执行文件说明源码下载 提取码: utt9 pyautogui这个库真的很简单&#xff0c;几乎只需要会英语就OK了。 import pyautogui as pg from time import sleepwith open(&q…

【ES6】let、const、解构赋值、模板字符串

文章目录let 关键字const 关键字解构赋值模板字符串ES6学习&#xff1a;尚硅谷Web前端ES6教程&#xff0c;涵盖ES6-ES11ES6 入门教程 阮一峰let 关键字 【特性】 let 关键字用来声明变量&#xff0c;使用 let 声明的变量有几个特点&#xff1a; 不允许重复声明&#xff1b;块…

jquery.min.map详见

温故而知新&#xff0c;翻出来阮前辈的文章记录一下 日期&#xff1a;2013年1月23日 上周&#xff0c;jQuery 1.9发布。 这是2.0版之前的最后一个新版本&#xff0c;有很多新功能&#xff0c;其中一个就是支持Source Map。 访问 http://ajax.googleapis.com/ajax/libs/jquer…

部分undefined reference to `__imp_XXXX‘错误解决方案

今天临时又用到函数mciSendString、PlaySound&#xff0c;编译报错undefined reference to __imp_XXXX&#xff0c;一下子没想起来怎么解决。 在正常使用的情况下是这样&#xff1a; 对于VS2019&#xff0c; 有效解决方案是&#xff1a;在头文件后#pragma comment(lib,"…

【ES6】对象方法简化写法、箭头函数、参数默认值、rest参数

文章目录简化对象和函数写法箭头函数参数默认值rest 参数简化对象和函数写法 【介绍】 ES6 允许在大括号里面&#xff0c;直接写入变量和函数&#xff0c;作为对象的属性和方法。这样的书写更加简洁 let name "张三";let talk function () {console.log("你…

详解C语言实现植物大战僵尸阳光9999

文章目录效果展示工具&#xff1a;要求(建议)一、CE部分&#xff1a;二、核心代码部分三、润色效果展示 另外点击还会有"德玛西亚&#xff01;"音效 工具&#xff1a; 核心代码&#xff1a;Devcpp足够&#xff1b; 对话框界面和资源文件的添加&#xff1a;CodeBloc…