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

Vue3 面试题及详细答案120道(16-30 )

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux… 。

前后端面试题-专栏总目录

在这里插入图片描述

文章目录

  • 一、本文面试题目录
      • 16. Vue3 中如何创建响应式对象?
      • 17. Vue3 中如何监听数据变化?
      • 18. Vue3 的生命周期钩子有哪些?与 Vue2 有何区别?
      • 19. Vue3 中如何实现父子组件通信?
      • 20. setup 函数的作用是什么?它有哪些参数?
      • 21. Vue3 中如何实现计算属性(computed)?
      • 22. Vue3 中如何实现跨层级组件通信(祖孙组件)?
      • 23. Vue3 中如何使用插槽(Slot)?
      • 24. Vue3 中如何使用 Teleport 组件将内容渲染到指定位置?
      • 25. Vue3 中 Suspense 组件的作用是什么?如何使用?
      • 26. Vue3 中 `<script setup>` 如何声明 props 和 emits?
      • 27. Vue3 中如何动态绑定样式(class 和 style)?
      • 28. Vue3 中如何注册全局组件?
      • 29. Vue3 中如何实现自定义指令?
      • 30. Vue3 中 `nextTick` 的作用是什么?如何使用?
  • 二、120道面试题目录列表

一、本文面试题目录

16. Vue3 中如何创建响应式对象?

在 Vue3 中,创建响应式对象主要通过 reactiveref 两个 API 实现:

  • reactive:用于将对象或数组转换为响应式数据,基于 Proxy 实现,直接代理整个对象。示例:
    import { reactive } from 'vue';
    const user = reactive({name: '张三',age: 25
    });
    // 修改属性时会触发响应式更新
    user.age = 26;
    
  • ref:主要用于基本数据类型(如字符串、数字等),也可用于对象。它会将数据包装为一个带有 value 属性的响应式对象,访问或修改时需通过 .value。示例:
    import { ref } from 'vue';
    const count = ref(0);
    // 访问
    console.log(count.value); // 0
    // 修改
    count.value++; // 触发更新
    
  • 区别:reactive 仅支持对象/数组,且访问属性无需额外操作;ref 支持所有数据类型,但需通过 .value 访问(模板中使用时会自动解包,无需 .value)。

17. Vue3 中如何监听数据变化?

Vue3 提供 watchwatchEffect 两种方式监听数据变化:

  • watch:需明确指定监听的数据源,支持监听单个或多个数据,可获取新旧值。示例:
    import { ref, watch } from 'vue';
    const count = ref(0);
    // 监听单个数据
    watch(count, (newVal, oldVal) => {console.log(`count从${oldVal}变为${newVal}`);
    });
    // 监听多个数据
    watch([count, () => user.age], ([newCount, newAge], [oldCount, oldAge]) => {console.log('count或age变化了');
    });
    
  • watchEffect:自动收集依赖,无需指定数据源,回调函数中使用的响应式数据变化时会触发执行,且初始会执行一次。示例:
    import { ref, watchEffect } from 'vue';
    const count = ref(0);
    watchEffect(() => {console.log(`count当前值:${count.value}`); // 初始执行,后续count变化时再执行
    });
    
  • 适用场景:watch 适合需要明确监听目标或需要新旧值对比的场景;watchEffect 适合依赖不明确、需要自动追踪的场景。

18. Vue3 的生命周期钩子有哪些?与 Vue2 有何区别?

Vue3 保留了 Vue2 的核心生命周期概念,但在组合式 API 中以函数形式提供,部分钩子名称略有调整:

  • 常用钩子:onBeforeMount(挂载前)、onMounted(挂载后)、onBeforeUpdate(更新前)、onUpdated(更新后)、onBeforeUnmount(卸载前)、onUnmounted(卸载后)、onErrorCaptured(捕获子组件错误)。
  • 与 Vue2 的区别:
    1. 写法不同:Vue3 需从 vue 中导入钩子函数,在 setup 中使用;Vue2 是在组件选项中定义(如 mounted() {})。
    2. 名称调整:Vue2 的 beforeDestroy 改为 onBeforeUnmountdestroyed 改为 onUnmounted
    3. 新增钩子:onRenderTracked(追踪响应式依赖时触发,用于调试)、onRenderTriggered(响应式依赖变化触发更新时触发,用于调试)。
  • 示例(组合式 API 中使用):
    import { onMounted, onUnmounted } from 'vue';
    setup() {onMounted(() => {console.log('组件已挂载');});onUnmounted(() => {console.log('组件已卸载');});
    }
    

19. Vue3 中如何实现父子组件通信?

父子组件通信主要通过 props 传值事件触发 实现:

  • 父传子(props)
    1. 父组件在使用子组件时,通过属性传递数据:
      <ChildComponent :message="parentMsg" :count="10" />
      
    2. 子组件通过 defineProps 声明接收的 props(<script setup> 中):
      import { defineProps } from 'vue';
      const props = defineProps({message: String, // 类型校验count: {type: Number,required: true, // 必传default: 0 // 默认值(非必传时生效)}
      });
      // 使用
      console.log(props.message);
      
  • 子传父(自定义事件)
    1. 子组件通过 defineEmits 声明可触发的事件,然后通过 emit 触发:
      import { defineEmits } from 'vue';
      const emit = defineEmits(['change', 'submit']); // 声明事件
      // 触发事件并传递数据
      const handleClick = () => {emit('change', '新数据');emit('submit');
      };
      
    2. 父组件监听子组件触发的事件:
      <ChildComponent @change="handleChange" @submit="handleSubmit" />
      <script setup>
      const handleChange = (data) => {console.log('子组件传递的数据:', data);
      };
      </script>
      

20. setup 函数的作用是什么?它有哪些参数?

setup 是 Vue3 中 Composition API 的入口函数,用于组织组件逻辑,在组件创建前(beforeCreate 之前)执行。

  • 作用
    1. 替代 Vue2 中的 datamethods 等选项,将组件逻辑以函数形式组织。
    2. 提供响应式 API(如 refreactive)、生命周期钩子等的使用入口。
    3. 返回的对象属性或方法可直接在模板中使用。
  • 参数
    1. props:接收父组件传递的 props,是响应式对象,不可直接解构(需用 toRefs 解构)。
    2. context:包含组件上下文信息,如 attrs(非 props 属性)、slots(插槽)、emit(触发事件的函数)。
  • 示例:
    import { toRefs } from 'vue';
    setup(props, context) {// 解构 props(保持响应式)const { message } = toRefs(props);// 使用 contextconst { emit, attrs, slots } = context;const handleClick = () => {emit('submit'); // 触发事件};// 返回给模板return { message, handleClick };
    }
    

21. Vue3 中如何实现计算属性(computed)?

计算属性通过 computed 函数创建,用于依赖响应式数据的衍生值,具有缓存特性(依赖不变时不会重新计算)。

  • 基本用法
    import { ref, computed } from 'vue';
    const count = ref(0);
    // 只读计算属性
    const doubleCount = computed(() => {return count.value * 2;
    });
    console.log(doubleCount.value); // 0(初始值)
    count.value = 1;
    console.log(doubleCount.value); // 2(依赖变化后重新计算)
    
  • 可写计算属性(需指定 getset):
    const fullName = computed({get: () => `${firstName.value} ${lastName.value}`,set: (newValue) => {const [f, l] = newValue.split(' ');firstName.value = f;lastName.value = l;}
    });
    // 赋值时触发 set
    fullName.value = '李四 王';
    
  • 特点:依赖变化时自动更新,适合处理需要基于现有数据计算衍生值的场景(如过滤列表、格式化数据)。

22. Vue3 中如何实现跨层级组件通信(祖孙组件)?

跨层级通信可通过 provideinject 实现,无需手动逐层传递 props:

  • 祖先组件提供数据(provide)
    import { provide, ref } from 'vue';
    setup() {const theme = ref('dark');// 提供数据(key 为标识,value 为数据)provide('themeKey', theme);provide('userInfo', { name: '张三', age: 25 });
    }
    
  • 后代组件接收数据(inject)
    import { inject } from 'vue';
    setup() {// 接收数据(第一个参数为 key,第二个参数为默认值)const theme = inject('themeKey', 'light'); // 响应式数据(保持响应式)const userInfo = inject('userInfo', { name: '默认名称' }); // 普通数据return { theme, userInfo };
    }
    
  • 注意:
    1. provide 传递响应式数据(如 ref/reactive 对象)时,后代组件接收后可感知数据变化。
    2. 若需在后代组件修改祖先提供的数据,建议祖先同时提供修改方法(如 provide('updateTheme', (newVal) => { theme.value = newVal; }))。

No.大剑师精品GIS教程推荐
0地图渲染基础- 【WebGL 教程】 - 【Canvas 教程】 - 【SVG 教程】
1Openlayers 【入门教程】 - 【源代码+示例 300+】
2Leaflet 【入门教程】 - 【源代码+图文示例 150+】
3MapboxGL【入门教程】 - 【源代码+图文示例150+】
4Cesium 【入门教程】 - 【源代码+综合教程 200+】
5threejs【中文API】 - 【源代码+图文示例200+】

23. Vue3 中如何使用插槽(Slot)?

插槽用于父组件向子组件传递模板内容,Vue3 中插槽用法与 Vue2 类似,但支持更简洁的语法:

  • 默认插槽
    1. 子组件中用 <slot> 定义插槽位置:
      <!-- 子组件 -->
      <div class="container"><slot></slot> <!-- 父组件传递的内容会插入这里 -->
      </div>
      
    2. 父组件使用子组件时,在标签内写入内容:
      <ChildComponent><p>这是默认插槽的内容</p>
      </ChildComponent>
      
  • 具名插槽(多个插槽区分):
    1. 子组件用 name 属性定义具名插槽:
      <slot name="header"></slot> <!-- 头部插槽 -->
      <slot></slot> <!-- 默认插槽(name 默认为 default) -->
      <slot name="footer"></slot> <!-- 底部插槽 -->
      
    2. 父组件用 v-slot:name(或缩写 #name)指定内容插入的插槽:
      <ChildComponent><template #header><h1>页面标题</h1></template><p>默认内容</p><template #footer><p>页脚信息</p></template>
      </ChildComponent>
      
  • 作用域插槽(子组件向父组件传递数据):
    1. 子组件在插槽中通过 v-bind 传递数据:
      <slot :user="userInfo" :count="10"></slot>
      
    2. 父组件接收数据并使用:
      <ChildComponent><template #default="slotProps"> <!-- 接收数据 --><p>用户名:{{ slotProps.user.name }}</p><p>数量:{{ slotProps.count }}</p></template>
      </ChildComponent>
      

24. Vue3 中如何使用 Teleport 组件将内容渲染到指定位置?

Teleport(瞬移)用于将组件内的部分内容渲染到 DOM 树的其他位置(如 <body>),解决样式层级限制问题(如模态框、弹窗)。

  • 基本用法
    <template><button @click="showModal = true">打开弹窗</button><!-- to 指定目标位置(CSS 选择器或 DOM 元素) --><Teleport to="body"><div v-if="showModal" class="modal"><p>这是弹窗内容</p><button @click="showModal = false">关闭</button></div></Teleport>
    </template>
    <script setup>
    import { ref } from 'vue';
    const showModal = ref(false);
    </script>
    
  • 特点
    1. 渲染位置改变,但内容仍受当前组件的响应式数据控制(如 showModal)。
    2. 可避免弹窗被父组件的 overflow: hiddenz-index 样式影响。
    3. to 属性支持动态值(如 :to="targetElement")。

25. Vue3 中 Suspense 组件的作用是什么?如何使用?

Suspense 用于处理异步操作(如异步组件、异步数据加载),在等待异步内容时显示占位符(loading 状态),提升用户体验。

  • 使用步骤
    1. 定义异步组件(通过 defineAsyncComponent 创建):
      import { defineAsyncComponent } from 'vue';
      const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue') // 动态导入(返回 Promise)
      );
      
    2. Suspense 包裹异步组件,通过 default 插槽放异步内容,fallback 插槽放加载提示:
      <Suspense><template #default><AsyncComponent /> <!-- 异步组件 --></template><template #fallback><div>加载中...</div> <!-- 等待时显示 --></template>
      </Suspense>
      
  • 注意
    1. Suspense 仅能处理返回 Promise 的异步操作(如异步组件、setup 中使用 await 的组件)。
    2. 若异步操作失败,需配合错误边界(onErrorCaptured)处理错误。

26. Vue3 中 <script setup> 如何声明 props 和 emits?

<script setup> 是 Vue3 中简化组件写法的语法糖,声明 props 和 emits 需使用 definePropsdefineEmits 编译宏(无需导入):

  • 声明 props
    // 方式1:数组形式(仅指定名称)
    const props = defineProps(['name', 'age']);// 方式2:对象形式(带类型校验和配置)
    const props = defineProps({name: {type: String,required: true, // 必传default: '默认名称' // 非必传时的默认值},age: {type: Number,validator: (value) => { // 自定义校验return value >= 0;}}
    });// 使用
    console.log(props.name);
    
  • 声明 emits
    // 方式1:数组形式(仅指定事件名)
    const emit = defineEmits(['change', 'delete']);// 方式2:对象形式(带参数校验)
    const emit = defineEmits({change: (value) => { // 校验参数return typeof value === 'string';},delete: null // 无参数
    });// 触发事件
    const handleClick = () => {emit('change', '新值');emit('delete');
    };
    

27. Vue3 中如何动态绑定样式(class 和 style)?

动态绑定样式通过 :class:style 实现,支持对象、数组等形式:

  • 动态 class
    1. 对象形式(键为类名,值为布尔值,true 则添加类):
      <div :class="{ active: isActive, 'text-danger': hasError }"></div>
      <script setup>
      import { ref } from 'vue';
      const isActive = ref(true);
      const hasError = ref(false);
      </script>
      
    2. 数组形式(直接指定类名列表):
      <div :class="[activeClass, errorClass]"></div>
      <script setup>
      const activeClass = ref('active');
      const errorClass = ref('text-danger');
      </script>
      
  • 动态 style
    1. 对象形式(键为样式名,值为样式值):
      <div :style="{ color: textColor, fontSize: `${fontSize}px` }"></div>
      <script setup>
      import { ref } from 'vue';
      const textColor = ref('red');
      const fontSize = ref(16);
      </script>
      
    2. 数组形式(多个样式对象合并):
      <div :style="[baseStyle, customStyle]"></div>
      <script setup>
      const baseStyle = ref({ backgroundColor: 'white' });
      const customStyle = ref({ border: '1px solid black' });
      </script>
      

28. Vue3 中如何注册全局组件?

注册全局组件需通过 app.component 方法,在应用实例上注册,所有组件均可直接使用:

  • 步骤
    1. 导入组件:
      import GlobalButton from './components/GlobalButton.vue';
      import GlobalCard from './components/GlobalCard.vue';
      
    2. 在创建应用实例后,通过 component 方法注册:
      import { createApp } from 'vue';
      import App from './App.vue';const app = createApp(App);
      // 注册单个组件(参数:组件名,组件对象)
      app.component('GlobalButton', GlobalButton);
      // 链式注册多个
      app.component('GlobalCard', GlobalCard).component('GlobalInput', GlobalInput);app.mount('#app');
      
    3. 在任意组件中直接使用,无需局部导入:
      <GlobalButton label="全局按钮"></GlobalButton>
      <GlobalCard></GlobalCard>
      
  • 注意:全局组件名建议使用 kebab-case 格式(如 global-button),符合 HTML 标签规范。

29. Vue3 中如何实现自定义指令?

自定义指令用于封装 DOM 操作,通过 app.directive 注册,支持多个钩子函数(如 mountedupdated 等):

  • 全局注册
    import { createApp } from 'vue';
    import App from './App.vue';const app = createApp(App);
    // 注册自定义指令(参数:指令名,配置对象)
    app.directive('focus', {// 钩子函数:元素挂载到 DOM 时执行mounted(el) {el.focus(); // 自动聚焦},// 元素更新时执行(如组件重新渲染)updated(el) {el.focus();}
    });app.mount('#app');
    
  • 局部注册(仅在当前组件生效):
    // 在组件中
    export default {directives: {focus: {mounted(el) {el.focus();}}}
    };
    
  • 使用自定义指令
    <input v-focus type="text" /> <!-- 应用指令,会自动聚焦 -->
    
  • 常用钩子函数:
    • mounted:元素挂载后执行(初始化操作)。
    • updated:元素更新时执行(更新操作)。
    • unmounted:元素卸载时执行(清理操作)。

30. Vue3 中 nextTick 的作用是什么?如何使用?

nextTick 用于在 DOM 更新完成后执行回调函数,解决数据修改后立即操作 DOM 无法获取最新状态的问题(Vue 会批量更新 DOM,而非同步更新)。

  • 作用:等待当前组件的 DOM 完成更新后,再执行后续逻辑(如获取更新后的 DOM 尺寸、操作新渲染的元素等)。
  • 使用方式
    import { ref, nextTick } from 'vue';const count = ref(0);
    const el = ref(null);const handleClick = async () => {count.value++; // 修改数据,触发 DOM 更新(异步)// 此时直接操作 DOM 可能获取旧状态console.log(el.value.offsetHeight); // 可能为更新前的高度// 等待 DOM 更新完成后执行await nextTick();console.log(el.value.offsetHeight); // 最新高度
    };
    
  • 场景:
    • 数据修改后需要立即获取 DOM 元素的位置、尺寸等。
    • 数据修改后需要操作新渲染的 DOM 元素(如滚动到指定位置)。
  • 注意:nextTick 返回 Promise,可配合 async/await 使用,也可使用回调函数(nextTick(() => { ... }))。

二、120道面试题目录列表

文章序号vue3面试题120道
1vue3 面试题及详细答案(01 - 15)
2vue3 面试题及详细答案(16 - 30)
3vue3 面试题及详细答案(31 - 45)
4vue3 面试题及详细答案(46 - 60)
5vue3 面试题及详细答案(61 - 75)
6vue3 面试题及详细答案(76 - 90)
7vue3 面试题及详细答案(91 - 105)
8vue3 面试题及详细答案(106 - 120)
http://www.dtcms.com/a/292539.html

相关文章:

  • SonarQube+Git
  • Dify-13: 文本生成API端点
  • 使用mybatis实现模糊查询和精准查询切换的功能
  • Cy3-NH2 花菁染料Cy3-氨基,星戈瑞
  • CMOS知识点 物理气相沉积
  • ECMAScript(简称 ES)和 JavaScript 的关系
  • Qt文件操作:读写文件的各种方法
  • 如何安装没有install.exe的mysql数据库文件
  • uniapp打开导航软件并定位到目标位置的实现
  • k8s:离线部署tomcatV11.0.9,报Cannot find /opt/bitnami/tomcat/bin/setclasspath.sh
  • docker pull 用法
  • WebAssembly浏览器指纹识别技术——实验评估与应用展望(下篇)
  • el-input 动态获焦
  • 11.【C语言学习笔记】指针(三)(回调函数、qsort排序函数、sizeof关键字和strlen函数)
  • 2025年7月中科院一区-向光生长优化算法Phototropic growth algorithm-附Matlab免费代码
  • 【文献笔记】From words to routes: Applying large language models to vehicle routing
  • 嵌入式学习的第三十三天-进程间通信-UDP
  • SciTE(Scintilla Text Editor)的配置文件多个详解笔记250722
  • Web开发 05
  • 云祺容灾备份系统Hadoop备份与恢复实操手册
  • 188粉福
  • 【第三节】Class与Style绑定
  • 网络基础15-16:MSTP +VRRP综合实验
  • 单张显卡运行多个vllm模型
  • 零基础数据结构与算法——第五章:高级算法-回溯算法子集全排列问题
  • ZooKeeper学习专栏(六):集群模式部署与解析
  • C++ new 创建数组的内在原理详解
  • linux 环境服务发生文件句柄泄漏导致服务不可用
  • ELF 文件操作手册
  • python学习-读取csv文件