【DAY49】Teleport/Keep alive

console.log(1);
setTimeout(function () {
console.log(2);
}, 0);
new Promise((resolve) => {
console.log(3);
resolve();
}).then(() => {
console.log(4);
});
console.log(5);

1 3 5 4 2  

通过 console.log 知道它们的输出顺序:

  • 首先,代码执行到 console.log(1),输出 1
  • 接着,进入异步事件队列,执行 setTimeout,将回调函数压到异步事件队列末尾,因为定时器时间是 0,所以其实现是非常快的,不会阻塞线程。回调函数是异步执行的,不会阻塞后续代码的执行。所以,往后的同步代码可以继续执行。
  • 然后,遇到 Promise,输出 3
  • 执行 resolve(),由于 resolve 函数是异步调用的,所以会将 then 方法中的回调函数加入到微队列的末尾,等待同步代码执行完后依次执行,这就是 Promise 解决回调地狱的本质原因。
  • 然后,执行 console.log(5),输出 5
  • 此时执行完后续同步任务,先去微任务队列里面查看是否有任务,发现了 Promise.then() 中的回调函数,输出 4
  • 最后,到达异步事件队列的末尾,执行 setTimeout 的回调函数,输出 2

综上所述,这段代码的输出顺序是 1 -> 3 -> 5 -> 4 -> 2

如果没有resolve();的执行结果是什么?

如果没有执行 resolve(),则 Promise 对象一直处于未决状态,不会将回调函数加入到微队列中。因此,输出结果将不会包含回调函数中的内容,即

1
3
5
2

其中,第 4 个 console.log() 语句不会执行,因为 Promise 的 then() 方法没有被调用。

KeepAlive

KeepAlive 是 Vue.js 内置组件,主要用于优化应用程序的性能和交互体验,它可以将不需要销毁的组件缓存起来,以便下次访问时能够快速呈现,有效减少渲染和加载的时间,提高应用性能。

当 KeepAlive 包裹的组件被缓存时,其生命周期钩子函数将会发生以下变化:

  • 当组件被离开时,它的 beforeUnmounted() 钩子函数会被调用,然后它被缓存。
  • 如果缓存被激活,缓存的组件会被重新挂载,并且可以通过 activated() 钩子函数被激活。
  • 如果缓存被销毁,则 deactivated() 钩子函数会被执行。
<template>
  <div>
    <KeepAlive>
      <router-view />
    </KeepAlive>
  </div>
</template>
<template>
  <div>
    <KeepAlive :include="'Home'">
      <router-view />
    </KeepAlive>
  </div>
</template>

 vue的组件(页面)有自己的生命周期,比如create创建组件、mounted往组件上挂数据、update更新组件上挂的数据,destroy把组件实例销毁。

// #App.vue中
<template>
  <div class="box">
    <!-- 路由导航 -->
    <div class="nav">
      <router-link to="/">去home页面</router-link>
      <router-link to="/about">去about页面</router-link>
      <router-link to="/detail">去detail页面</router-link>
    </div>
    <!-- 路由导航对应的内容区 -->
    <main>
      <router-view></router-view>
    </main>
  </div>
</template>


// home.vue中,放置一个复选框
<el-checkbox v-model="checked">备选项</el-checkbox>

// about.vue中,放置一个输入框
<el-input v-model="input" placeholder="请输入内容"></el-input>

// detail.vue中方式一个下拉框
<el-select v-model="value" placeholder="请选择">
  <el-option
    v-for="item in options"
    :key="item.value"
    :label="item.label"
    :value="item.value"
  >
  </el-option>
</el-select>
<template>
  <div class="box">
    <!-- 路由导航 -->
    <div class="nav">
      <router-link to="/">去home页面</router-link>
      <router-link to="/about">去about页面</router-link>
      <router-link to="/detail">去detail页面</router-link>
    </div>
    <!-- 路由导航对应的内容区 -->
    <main>
      <keep-alive> <!-- 使用keep-alive包了一层,就可以缓存啦 -->
        <router-view></router-view>
      </keep-alive>
    </main>
  </div>
</template>

使用keep-alive包住以后,我们发现,我们勾选、输入、下拉选择的内容,在路由来回切换的时候,就不会丢失了,即使用keep-alive保存了之前的组件状态

keep-alive的应用场景:如
查看表格某条数据详情页,返回还是之前的状态,比如还是之前的筛选结果,还是之前的页数等
填写的表单的内容路由跳转返回还在,比如input框、下选择拉框、开关切换等用户输入了一大把东西,跳转再回来不能清空啊,不能让用户再写一遍啊,

  1. 可以使用 exclude 属性为 KeepAlive 排除一些不需要缓存的组件,或者使用 max 属性控制最大缓存组件数量,默认值为 Infinity
<template>
  <div>
    <KeepAlive :include="'Home'" :exclude="'About'" :max="5">
      <router-view />
    </KeepAlive>
  </div>
</template>

  1. 在缓存的组件中可以通过 activated 和 deactivated 钩子函数执行一些特定的逻辑。
<template>
  <div>
    <h1>Home Component</h1>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  name: 'Home',
  activated() {
    console.log('Home Component activated')
  },
  deactivated() {
    console.log('Home Component deactivated')
  },
  data() {
    return {
      message: 'Hello World!'
    }
  }
}
</script>

另外,还有一些需要注意的点:

  1. 每一个缓存的组件都必须有一个唯一的 name 属性。

  2. 任何有状态的组件都不能被缓存,因为这些组件内部的数据会因为其内部状态的变化而变化。

  3. 如果缓存组件与路由共用同一个组件名称,需要在路由的 meta 字段中为缓存和非缓存组件分别设置 keepAlive 属性。

const router = new VueRouter({
  routes: [
    {
      path: '/home',
      name: 'Home',
      component: Home,
      meta: {
        keepAlive: true // 缓存组件
      }
    },
    {
      path: '/about',
      name: 'About',
      component: About
    }
  ]
})

Teleport

Teleport 是 Vue.js 3.0 新增的一个组件,它可以让开发者在组件树之外的任何地方渲染一个组件,而不需要在组件的父组件中嵌套完整的模板。使用 Teleport 组件可以轻松实现一些复杂的场景,例如弹出框、对话框、下拉菜单等。

Teleport 的主要作用是将指定的内容渲染到指定的出口(即 <Teleport> 的 to 属性),从而实现在 DOM 结构中跨越组件边界的渲染,它可以将内容渲染到 DOM 中任何一个有效的位置,而不必依赖于父组件的位置或者组件层次结构。

使用 Teleport 的示例代码如下:

<template>
  <div>
    <button @click="showDialog = true">Show Dialog</button>
    <Teleport to="body">
      <div v-if="showDialog">
        <h1>Dialog Title</h1>
        <p>Dialog Content</p>
        <button @click="showDialog = false">Close</button>
      </div>
    </Teleport>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showDialog: false
    }
  }
}
</script>

在上述示例中,当用户点击按钮时,条件渲染的 div 元素会被 Teleport 渲染到 body 元素以外的一个容器中,所以不会被原有的 div 容器包含,从而实现了弹出框的功能。

需要注意的是,在使用 Teleport 进行渲染时,目标容器必须存在于 DOM 中,否则渲染将失败。此外,当一个组件被多次渲染到多个位置时,应该通过指定 key 值来确保不同渲染之间的独立性。与 keep-alive 进行缓存相似,Teleport 可以通过使用 disabled 属性来实现临时禁用,或使用 fallback 属性来提供备用的渲染方式,以确保组件使用的安全性和可靠性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值