Appearance
Vue 组件封装与进阶
JSX · 组件透传 · Composition 封装第三方组件 · 项目性能优化 · SPA 首屏
一、Vue JSX
JSX 是 createElement 的语法糖,template 编译后就是 createElement 调用。
JSX 与 template 核心差异:
| 特性 | template | JSX |
|---|---|---|
| v-model | v-model="val" | value={this.val} onInput={handler} |
| v-if | v-if="cond" | cond ? <A/> : <B/> |
| v-for | v-for="item in list" | list.map(item => <li>{item}</li>) |
| 事件监听 | @click="fn" | onClick={fn} |
二、Vue 组件透传(属性/事件/插槽)
三种透传方式:
| 透传类型 | Vue2 | Vue3 |
|---|---|---|
| 属性 | v-bind="$attrs" | v-bind="$attrs" |
| 事件 | v-on="$listeners" | 合并到 $attrs($listeners 已移除) |
| 插槽 | $scopedSlots | $slots(所有插槽均为函数) |
JSX 中优雅透传(Vue2):
jsx
<BaseInput {...{ attrs: this.$attrs, on: this.$listeners, scopedSlots: this.$scopedSlots }} />模板写法(通用):
html
<BaseInput v-bind="$attrs" v-on="$listeners">
<template v-for="(_, name) in $scopedSlots" v-slot:[name]="data">
<slot :name="name" v-bind="data"/>
</template>
</BaseInput>三、Vue3 Composition API 封装第三方组件
vue
<!-- MyInput.vue — 封装 el-input -->
<template>
<div class="my-input">
<el-input v-bind="attrs" ref="elInputRef">
<template v-for="k in Object.keys(slots)" #[k] :key="k">
<slot :name="k"></slot>
</template>
</el-input>
</div>
</template>
<script>
export default { name: 'MyInput', inheritAttrs: false }
</script>
<script setup>
import { ref, useAttrs, useSlots } from 'vue'
const attrs = useAttrs() // 透传所有非 props 的 attribute + 事件
const slots = useSlots() // 获取所有插槽
const elInputRef = ref(null)
defineExpose({ elInputRef }) // 暴露内部组件实例
</script>各要素说明:
| 要素 | Vue3 API | 作用 |
|---|---|---|
| Props + Events | useAttrs() + v-bind="attrs" | 透传所有未声明的属性和事件 |
inheritAttrs: false | 普通 <script> 中声明 | 阻止 attrs 自动绑定到根元素 |
| Slots | useSlots() + v-for 动态插槽 | 遍历父组件传入的所有插槽动态转发 |
| Methods | ref + defineExpose | 暴露内部组件实例给父组件调用 |
四、Vue 项目性能优化
v-ifvsv-show:频繁切换用 v-show,首次渲染用 v-ifv-for的 key:列表变化时用唯一不变 key 借助本地复用- 多用
computed:依赖不变不重新计算 - 合理使用
destroyed清理事件/定时器;动态组件用keep-alive缓存 - 不需要响应式的数据用
Object.freeze冻结 - 第三方插件按需加载
- 使用运行时版本(vue.runtime.esm.js)比完整版小约 30%
五、SPA 首屏优化
- 减小入口文件体积(splitChunks + 路由懒加载)
- 静态资源本地缓存(浏览器缓存 + HTTP 缓存控制)
- UI 框架按需加载
- 图片资源压缩
- 开启 GZip 压缩
- 使用 SSR
- CDN externals 减小 vendor.js
更多性能优化手段详见 性能优化专题