当前位置: 首页 > news >正文

Vue3-Day3

1. 插槽

插槽就是子组件预留的占位坑位,让父组件可以自定义插入 HTML / 组件内容,实现组件内容灵活复用。
简单比喻:
子组件是一个相框,<slot> 就是相框中间空白区域;父组件传入图片 / 文字,填进这个空白位置。

在Vue中,有三种插槽,对应不同的使用方式

  • 默认插槽(匿名插槽):该插槽一个组件只能存在一个
  • 具名插槽:子组件多处需要自定义内容,给每个 slot 起名字,父组件对应 v-slot:名字(简写 #名字)。
  • 作用域插槽:
    • 普通插槽:父只能把内容传给子;
    • 作用域插槽:子组件内部数据,反向传给父组件使用。
    • 适用场景:表格、列表循环,子循环列表,父自定义每一行渲染。
      子组件:给 slot 绑定自定义属性向外抛数据

子组件Card

<!-- components/Card.vue --> <template> <div class="card"> <h1> <!-- 默认插槽:一个组件只有一个默认插槽 --> <slot></slot> </h1> <h2> <!-- 具名插槽:需要多个插槽可以取名字 --> <slot name="name1"></slot> </h2> <h2> <slot name="name2"></slot> </h2> </div> </template> <script setup> </script>

子组件List

<template> <div> <div v-for="item in list" :key="item.id"> <!-- 子给插槽传数据:item ,别名row --> <!-- 作用域插槽 --> <slot :row="item"></slot> </div> </div> </template> <script setup> const list = [ { id:1, name:'张三' }, { id:2, name:'李四' } ] </script>

父组件

<script setup lang="ts"> import Card from './Card.vue' import List from './List.vue' </script> <template> <div> 父组件 <Card> <p>父组件使用子组件默认插槽</p> <template #name1> <p>父组件使用子组件具名插槽1</p> </template> <template #name2> <p>父组件使用子组件具名插槽2</p> </template> </Card> </div> <div> <List> <!-- 父组卷使用子组件作用域插槽 --> <template #default="{ row }"> <div>{{ row.id }} - {{ row.name }}</div> </template> </List> </div> </template>

2. defineOptions

  • 版本要求
    Vue ≥ 3.3 / Vite / Vue CLI 新版内置支持,无需导入,直接使用宏
    作用:在<script setup>内声明组件选项(name、inheritAttrs、props、emits 等)
  • 注意
    • 在Vite中,会自动命名name,但是推荐还是要写,不然会出现小问题
    • 命名了name后在Vue DevTools中可以看到自定义名称,而非匿名组件

常用于定义组件name

<script setup> // 直接定义组件名称,无需额外script块 defineOptions({ name: 'UserCard' }) </script> <template> <div>用户卡片</div> </template>

所有选项

<script setup> defineOptions({ // 组件名称(最重要,用于递归组件、devtools、keep-alive) name: 'TableList', // 是否继承父组件非props属性 inheritAttrs: false, // 自定义渲染函数(极少用) render: () => {}, // 静态props、emits(setup内优先用defineProps/defineEmits) props: [], emits: [], // 其他原生选项:components、directives 等不推荐在这里写 }) </script>

3. 动态组件

  • 作用:同一位置切换多个组件,不用 v-if/v-else 一堆判断,通过 is 属性指定要渲染的组件。
  • 每次切换组件
    • 旧组件执行 unmounted 销毁
    • 新组件重新 mounted 创建
    • 表单输入、滚动位置、接口数据全部丢失
    • 想要保留状态,就套上<KeepAlive>

3.1 实现组件切换

父组件 - Tab0

<script setup lang="ts"> import { ref } from 'vue' import Tab1 from './Tab1.vue' import Tab2 from './Tab2.vue' defineOptions({ name: 'Tab0' // 组件名称 }) // 初始值 const current = ref(Tab1); </script> <template> <button @click="current = Tab1">切换页面1</button> <button @click="current = Tab2">切换页面2</button> <!-- 通过:is绑定组件 --> <component :is="current" /> </template>

子组件 - Tab1

<script setup lang="ts"> defineOptions({ name: 'Tab1' }) </script> <template> <P>我是子组件1</P> </template>

子组件 - Tab2

<script setup lang="ts"> defineOptions({ name: 'Tab2' }) </script> <template> <P>我是子组件2</P> </template>

3.2 实现组件切换保留缓存

  • <keepAlive>可以实现缓存不活动的组件实例,不销毁,再次切换时直接复用,保留:表单值、滚动位置、接口缓存数据、定时器等。

基础用法(包裹动态组件):此时切换 Tab1 / Tab2,数据不会重置。

<KeepAlive> <component :is="current" /> </KeepAlive>

include(依赖组件 name):只缓存 TabOne、TabTwo,其他组件 每次切换销毁重建

<KeepAlive include="TabOne,TabTwo"> <component :is="current" /> </KeepAlive>

exclude:排除指定 name,不缓存

<KeepAlive exclude="TabTwo">

max:最大缓存实例数,超出数量后,最久没使用的组件自动销毁

<KeepAlive max="5">

子组件中缓存专属生命周期钩子(只有被 KeepAlive 缓存才触发):被缓存的组件切换时不会执行 onMounted / onUnmounted,只会走 activated / deactivated。

<script setup> import { onActivated, onDeactivated, onMounted } from "vue" // 只会首次创建执行 onMounted(() => { console.log("组件创建") }) // 每次切进来都执行 onActivated(() => { console.log("组件激活,刷新列表/重置查询条件") }) // 每次切走执行 onDeactivated(() => { console.log("组件失活,清除定时器") }) </script>

路由场景最常用(页面缓存)

<KeepAlive include="UserList,OrderPage"> <router-view /> </KeepAlive>

踩坑点:Vue Router4 内部重构了 渲染机制,路由视图是动态异步组件,不能直接作为 的子节点。
必须通过 v-slot 取出底层组件实例,再用 渲染,才能被 KeepAlive 正常捕获缓存。
官方标准插槽写法(现在必须用)

<router-view v-slot="{ Component }"> <KeepAlive include="UserList,OrderPage"> <component :is="Component" /> </KeepAlive> </router-view>

4. router

  • Vue Router 是 Vue.js 的官方路由管理器。

  • 单页应用的特点:页面跳转不会重新加载整个 HTML 页面,仅局部更新视图;

  • 作用:建立 URL 地址与页面组件之间的映射关系,根据当前 URL 渲染匹配的组件。

  • 用法

    1. 安装vue-router
      npm install vue-router@4
    2. 创建路由文件 src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router' import type { RouteRecordRaw } from 'vue-router' // 路由配置 const routes: RouteRecordRaw[] = [ {path: '/',redirect: '/home'}, {path: '/home',name: 'Home',component: () => import('@/views/Home.vue')}, {path: '/about',name: 'About',component: () => import('@/views/About.vue')} ] // 创建路由 const router = createRouter({ history: createWebHistory(), routes }) export default router
  1. main.ts中引入和注册
import router from './router' app.use(router)

就可以成功通过改变URL加载不同组件了

http://www.jsqmd.com/news/1110042/

相关文章:

  • 佳能打印机开机报P07和5B00怎么维修?别慌,这只是需要清零一下就好了,别傻傻送到维修店了,维修店收你180维修费的,这种故障自己在家就可以修好,2分钟完美修复,G3800,G3810,G2810
  • Python开发中五个提升代码效率的小技巧
  • Anthropic归零提示层:隐式结构化推理与零提示开销实践
  • 文字到多模态:三层架构实现语义一致的图文音视频生成
  • ICM-42688-P与PIC32MX534F064H在运动控制与振动监测中的应用
  • 一条命令。自然语言。你的 Elasticsearch 数据,直接进入终端
  • RAG中Chunk Size如何选择:语义完整性与向量检索的平衡术
  • 无人机设计塑胶材料选型指南
  • 后端架构演进:从单体到微服务的实践之路
  • Anthropic的‘归零层’:将合规约束编译进大模型推理内核
  • NanoGPT实现原生函数调用:从零构建结构化输出能力
  • 2026玉米增产指南:海力冠水溶肥5个关键施用技巧
  • Anthropic架构归零:请求编排层的原生化革命
  • CellCog AI 引擎工具简介
  • BMI270与PIC18LF24K50低功耗运动感知方案详解
  • DeepSeek R1:面向工程落地的可验证大模型架构解析
  • Anthropic Zero-Layer:消除LLM解释性幻觉的架构级蒸发技术
  • 如何5步搭建Sunshine游戏串流服务器:打造你的私人云游戏平台
  • 2026年国产智能体agent选型深度分析:谈谈企业级agent的数据安全性和信创适配为什么重要?
  • 5分钟掌握微博备份终极方案:Speechless一键导出PDF完整指南
  • 深圳科创公司生成式引擎优化(GEO)找谁做?
  • AI模型集成与智能代理架构实战指南
  • 如何5分钟搭建个人HTTP文件服务器:图形化共享工具的完整指南
  • Zotero PDF翻译插件:20+翻译引擎一键搞定学术文献翻译
  • WordPress主题资源推荐
  • GitHub今日热榜 | 2026-07-01:健身数据集登顶
  • 计算机Java毕设实战-基于 SpringBoot 的高校摄影社团成员信息运维系统的设计与实现 校园摄影赛事报名管理系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 2026春招AI抢人大战:小白程序员如何抓住高薪风口,手把手教你收藏必看攻略!
  • 大模型Function Calling实战:让Agent拥有工具调用能力
  • ChatGPT如何重塑职场沟通:原理、提示词工程与风险防控