赞
踩
目录
实例: 实现一个点击按钮做 inx++,并展示出inx的功能。
阅读vue3源码的时候,发现会根据不同shapeFlag来做不一样的渲染,进而发现了vue3的一些新特性。好吧,我承认这个先后顺序可能有点点反。好了,让我们进入正题吧。
官方说明:在正确渲染组件之前进行一些异步请求是很常见的事。suspense允许将等待过程提升到组件树中处理,而不是在单个组件中。
为了显示友好,我们会在请求返回前显示一个Loading。
进入页面,显示 Loading,3秒后,显示为 Hello
在vue2中,通常我们是定义一个变量来操作这个loading的显示与否
- <template>
- <div class="pager">
- <div v-if="loading">Loading</div>
- <div v-else>{{data}}</div>
- </div>
- </template>
- <script>
- export default {
- data() {
- return {
- loading: true,
- data: ''
- }
- },
- created() {
- this.load();
- },
- methods: {
- load() {
- this.loading = true;
- return new Promise((resolve) => {
- setTimeout(()=>{
- this.data= 'hello'
- this.loading = false;
- resolve('hello')
- }, 3000)
- })
- }
- }
- }
- </script>

- //父组件
-
- <script setup>
- import HelloWorld from './components/HelloWorld.vue'
- </script>
-
- <template>
- <suspense>
- <template #default>
- <HelloWorld/>
- </template>
- <template #fallback>
- Loading
- </template>
- </suspense>
- </template>

- //子组件 - HelloWorld
-
- <script setup>
- import { ref } from 'vue';
- const data = ref('');
-
- const load = function() {
- return new Promise((resolve) => {
- setTimeout(()=>{
- data.value = 'hello'
- resolve('hello')
- }, 3000)
- })
- }
-
- await load();
-
- </script>
-
- <template>
- {{data}}
- </template>

关键点:await将setup隐性添加了一个async的关键字,也就是 Promise的返回
1.使用要点:子组件的加载方式为异步加载 ,或者子组件的setup应返回一个Promise,async关键字为隐性的Promise返回。
远距离传送, 可以将teleport内的element移到组件外的特定位置。
官方说明:Teleport 提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下渲染了 HTML,而不必求助于全局状态或将其拆分为两个组件。
优点:添加组件的灵活性,原先由于布局、层级等原因【类似按钮和触发弹窗等】,需要拆分到不同位置【不同组件】的相关联操作,也可以更好的封装起来。
props:【官方摘要】
to
-string。必填
,必须是有效的查询选择器或 HTMLElement (如果在浏览器环境中使用)。指定将在其中移动<teleport>
内容的目标元素disabled
-boolean
。可选,此属性可用于禁用<teleport>
的功能,这意味着其插槽内容将不会移动到任何位置,而是在你在周围父组件中指定了<teleport>
的位置渲染。
- <template>
- <div class="pager">
- <div class="pager__left">
- <button @click="inx++">click</button>
- </div>
- <div class="pager__right">
- {{inx}}
- </div>
- </div>
- </template>
方案一:同层级的组件传送
- //父組件
- <template>
- <Pager />
- <PagerButton/>
- </template>
-
- //子組件 - Pager
- <template>
- <div class="pager">
- <div class="pager__left"></div>
- <div class="pager__right"></div>
- </div>
- </template>
-
- //子組件 - PagerButton
- <template>
- <teleport to=".pager__left">
- <button @click="inx++">click</button>
- </teleport>
- <teleport to=".pager__right">
- <span>{{inx}}</span>
- </teleport>
- </template>

注意:同层级的挂载渲染从上而下,故PagerButton应放在Pager上方。
方案二:不同层级的组件传送【父传子】
- //父组件
- <template>
- <Pager />
- <teleport to=".pager__left">
- <button @click="inx++">click</button>
- </teleport>
- <teleport to=".pager__right">
- <span>{{inx}}</span>
- </teleport>
- </template>
1.传送目标组件应先挂载好。而同一组件内,挂载顺序是,子组件先挂载完,父组件后挂载,故子组件要挂载到父组件是行不通的,会报warning。如果实在是有这方面的需求,延迟延迟子组件的渲染,也可以【onMounted + v-if】。
传送方向:父 传 子, 后 传 前。
或者若是在index.html上开辟一块地来挂载特殊的东西,也未尝不可。
2.挂载只是移动的过程,而不是销毁和重建的过程哦。
目前这个例子看起来,代码量变大的样子,但是如果pager__left 和pager__right,原先就有大量的代码逻辑呢?或者我们需要对一些组件【例如:tooltip】进行统一管理的时候,teleport可能是个不错的选择。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。