Vue 高级组件 & 插件 & SSR

本章主题: 掌握 Vue组件的高级用法、自定义插件和自定义指令的使用、SSR 同构的概念

一、组件的高级用法

1.1 动态组件

场景: 根据业务形态决定组件的类型

html 复制代码
<template>
        <component :is="component" :key="component"></component>
</template>

面试官: 动态组件的生命周期是什么样子的? | 动态组件是否会缓存? | 动态组件是否会存在不刷新的情况?

异步组件不会预加载 & 切换展示时才会初始化生命周期。

切换异步组件是一次性操作 | 每一次的切换都会更新生命周期(重新渲染实例)

面试官: 如何优化组件的加载?

加载文件 => 1. 独立拆包 2. 按需加载

面试官追问: 渲染时优化除了动态组件还有哪些方式?

控制引用 => 动态组件 | 异步加载组件 | 打包优化(external)
结论: 动态组件具备性能优势

动态组件( 一种类型 ) & 异步组件指加载时机

动态指类型动态, 异步指加载时机不同。

动态占位 + 运行时切换 => 控制实时渲染 + 空间保留。

不会影响首屏渲染 和 缓存遗留。

1.2 内置高级组件

模板层的拓展

1.2.1 keepalive 缓存组件

面试官: 动态组件如何缓存? 持久化? 保留组件状态 | 如何实现组件状态的缓存 / 反销毁?

keep-alive - 保留实例 & 状态

追问: 控制缓存变量?

keep-alive 三个参数 include / exclude / max

include 需要缓存的组件: 字符串 | 数组 | 正则

exclude 不需要缓存的组件

max 先到先得 max="10" 我只缓存前 10 个。涉及缓存的一定要考虑阈值。

面试官: keep-alive 的使用场景

取决于业务中对于实例、生命周期的要求。Exclude

否则 KeepAlive

面试官: keep-alive 的实现原理

存在内存中, 实例名称(key): VNode(value)

LRU 算法策略:最近使用的进行永久存储, 达到极值删除最长时间没有使用的实例

html 复制代码
<keep-alive include exclude max>       
    <router-view></router-view>     
</keep-alive>

1.2.2 teleport 传送门组件

需求: 将组件渲染在与 app 同级的位置 , 即 body 下 和 其它任何地方

html 复制代码
    <!-- 使用 teleport 将模态窗口渲染到 body -->
    <teleport to="body">
      <div v-if="showModal" class="modal-overlay" @click="closeModal">
        <div class="modal-content" @click.stop>
          <h2>模态窗口</h2>
          <p>这是一个使用 Vue Teleport 渲染的模态窗口。</p>
          <button @click="closeModal">关闭</button>
        </div>
      </div>
    </teleport>

1.2.3 suspense 等待加载组件 | pending 组件

异步组件有异步加载时间的。加载需要等待。

需求: 感知加载和加载完成。

作用: 判断异步组件是否加载成功

html 复制代码
<template>
  <Suspense>
    <!--使用异步组件-->
    <AsyncDialog />
    <template #fallback>
      <div>loading</div>
                </template>
  </Suspense>
</template>

优化加载体验

1.2.4 transition 过度态

html 复制代码
<template>
  <transition name="run">
    <Suspense>
      <!--使用异步组件-->
      <AsyncDialog />
      <template #fallback>
        <div>loading</div>
      </template>
    </Suspense>
  </transition>
</template>

三、自定义插件

custom.js

js 复制代码
export default {
  // app.use 就会调用 install
  install: (app, options) => {
    // app vue 实例
    // options 传参
    console.log(`app use`,app, options)
    // app.config.globalProperties 拓展
    app.config.globalProperties.$myPlugin = () => {
      console.log("hello my plugin", options.version)
    }
    // 全局挂载如何使用呢?
  }
}

main.js

js 复制代码
import defaultPlugin from "custom.js"
app.use(defaultPlugin,{})

底层实现, 非代码层面的功能统一注入。

四、自定义指令

全局代码指令

如 v-if v-for v-show....
permission.js

import directive from "../plugins/permission.js"

app.use(directive)

js 复制代码
export default {
  install: (app) => {
    // app.directive 指令生成器
    // <button v-permission="1">删除</button>
    app.directive('permission', (el, binding){
         // el 获取到绑定的节点
         // binding => 1
         
        // 1.代表管理员
        if (binding.value === 1) return
                    // 非管理员账号 - 不展示当前按钮
        if (el.parentNode) {
          el.parentNode.removeChild(el)
        } else {
          el.style.display = 'none'
        }                                                           
    })
  }
}

追问: 插件 & 指令 使用场景的区别

指令能实现的能力, 插件一定能实现。

插件是更底层的一种 vue 的拓展方式。

指令主要专注于 节点的 操作。

  • 层级上插件更底层, 接近设计模式
  • 指令更贴近节点

五、服务端渲染 SSR

生成服务

同构代码

entry-client.js

entry-service.js

app.js

作用维护状态

相关推荐
惜.己11 分钟前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称35 分钟前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色1 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2341 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河1 小时前
CSS总结
前端·css
NiNg_1_2341 小时前
Vue3 Pinia持久化存储
开发语言·javascript·ecmascript
读心悦1 小时前
如何在 Axios 中封装事件中心EventEmitter
javascript·http
BigYe程普2 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
神之王楠2 小时前
如何通过js加载css和html
javascript·css·html
余生H2 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈