插槽与生命周期

发布时间:2026/8/11 14:37:10
插槽与生命周期 第8课 插槽与生命周期理解插槽的作用让组件内容由使用方灵活定制掌握默认插槽、具名插槽、作用域插槽的写法与使用场景理解组件生命周期重点掌握onMounted初始加载和onUnmounted资源清理1. 插槽Slot组件内容的占位符痛点纯 props 只能传数据无法灵活改变组件内部的结构。插槽就像组件模板中的“填空位”使用方可以填入任意 HTML 内容。类比组件是相框固定外框插槽是放照片的凹槽内容自由换组件是快递柜固定格子插槽是柜门内放的包裹1.1 默认插槽子组件在模板中留一个slot/slot使用方写在组件标签内的内容会自动填充到这里。子组件CardBox.vuetemplate section classcard h3{{ title }}/h3 !-- 默认插槽 -- slot/slot /section /template父组件使用CardBox title公告 p系统维护通知.../p !-- 自动填入 slot 位置 -- /CardBox备用内容如果使用方没传任何内容则显示slot内部的默认内容。slot p classempty暂无内容/p /slot1.2 具名插槽当一个组件需要多个占位区如头部、主体、底部时给每个slot起一个名字。子组件定义template section classcard header slot nameheader默认标题/slot /header div classbody slot/slot !-- 没写 name 即为默认插槽 -- /div footer v-if$slots.footer slot namefooter / /footer /section /templatenamexxx定义具名插槽使用v-if$slots.footer可判断使用方是否传入了该插槽无内容时整块区域不渲染父组件使用必须用template #名字包裹内容以对号入座。CardBox template #header系统公告/template p维护通知内容.../p !-- 不写名字 → 默认插槽 -- template #footer a href#查看全部/a /template /CardBox#header是v-slot:header的简写具名内容必须写在template内否则会被当作默认插槽。1.3 作用域插槽场景子组件内部循环生成数据如列表但想让父组件自定义每一项的渲染方式。核心思路子组件把数据“递”到插槽父组件“接”过来自由显示。类比子组件是后厨把菜端到传菜窗口插槽父组件是客人从窗口取菜自己摆盘。子组件UserCardList.vuetemplate div v-foruser in users :keyuser.id !-- 通过 :useruser 将当前数据绑到插槽上 -- slot :useruser {{ user.name }} !-- 备用内容 -- /slot /div /template父组件使用UserCardList :usersusers !-- 接收插槽传出来的所有数据解构取出 user -- template #default{ user } img :srcuser.avatar / div b{{ user.name }}/b span{{ user.dept }}/span /div button clicklook(user)查看/button /template /UserCardList记忆口诀子组件**“:数据”绑定**传父组件**“{ 数据 }”解构**接。预告Element-Plus 表格的自定义列正是这种模式el-table-columntemplate #default{ row }.../template/el-table-column。2. 生命周期组件从创建到销毁的钩子每个 Vue 组件都会经历创建 → 挂载 → 更新 → 卸载四个阶段。我们可以在特定阶段执行代码钩子函数。2.1 常用生命周期钩子钩子触发时机典型用途onMounted组件挂载完成DOM 已可见初始化请求数据、启动定时器onUnmounted组件卸载前清理定时器、解绑事件防止内存泄漏onUpdated数据变化导致 DOM 更新后需要操作最新 DOM 时少用其他创建前/更新前等极少使用记忆方式重点掌握“一头一尾”——onMounted进门干事和onUnmounted出门收摊。2.2 onMounted页面打开自动加载数据管理系统标准模式进入页面 → 自动发请求 → 展示数据。script setup import { ref, onMounted } from vue const users ref([]) const loading ref(true) function fetchUsers() { loading.value true // 模拟接口请求第11课用 axios 替换 setTimeout(() { users.value [...] loading.value false }, 800) } onMounted(() { fetchUsers() // 组件渲染进页面后立刻执行 }) /script加载数据三步套路准备响应式空数据 loading状态编写请求函数完成后赋值并关闭loading在onMounted中调用该函数2.3 onUnmounted卸载前清理资源如果组件中启动了定时器如自动刷新、监听了全局事件、开启 WebSocket 等必须在组件销毁时手动清理否则它们会一直在后台运行导致内存泄漏。类比人离开房间组件卸载却忘了关水龙头定时器/监听水一直流代码一直跑久了系统变卡。清理示例script setup import { onMounted, onUnmounted } from vue let timer null onMounted(() { // 每3秒自动刷新 timer setInterval(() { fetchData() }, 3000) }) // 组件卸载前必须清理 onUnmounted(() { if (timer) { clearInterval(timer) timer null } }) /script清理原则谁开启谁负责关闭在onUnmounted中进行相反操作。3. 实战用户列表页综合案例将插槽与生命周期组合实现一个标准的管理系统列表页进入自动加载数据 (onMounted)列表使用作用域插槽让父组件自定义卡片样式支持“自动刷新”开关开启后定时拉取离开页面自动销毁定时器 (onUnmounted)关键代码片段App.vue 中控制组件挂载/卸载验证生命周期script setup import { ref } from vue const showUserPage ref(false) /script template button clickshowUserPage !showUserPage {{ showUserPage ? 退出 : 进入 }}用户管理页 /button UserListPage v-ifshowUserPage / /templateUserListPage.vue 核心逻辑script setup import { ref, onMounted, onUnmounted } from vue // 数据、loading、模拟请求、定时器见上文代码 onMounted(() fetchUsers()) onUnmounted(() clearInterval(timer)) /script4. 常见问题排查现象可能原因解决方法插槽内容不显示内容写在了组件标签外部确保内容在组件名和/组件名之间具名插槽内容跑到默认位置没用template #名称包裹具名内容必须放在template #xxx内无内容时没有默认内容备用内容写在了slot外面默认内容必须写在slot.../slot内部作用域插槽拿不到数据子组件绑定的属性名与父组件解构的不一致检查:useruser与{ user }是否匹配进入页面数据不加载忘记在onMounted中调用请求函数确认onMounted(() { ... })已写离开页面后控制台仍在打印/网络请求仍在发没有在onUnmounted中清理定时器等资源在onUnmounted中执行clearInterval/removeEventListener等总结速查默认插槽slot/slot父组件内容自动填入具名插槽slot namex→template #x作用域插槽子组件slot :datax→ 父组件template #default{ data }数据在子渲染在父onMounted初始化数据请求、开启定时器等onUnmounted清理定时器、解绑事件人走灯灭表格自定义列template #default{ row }即作用域插槽的应用插槽决定内容灵活度生命周期决定行为时机——两者结合才能真正驾驭组件化开发。