Vue3 知识点总结 · 2026-03-20

Vue3 知识点总结 · 2026-03-20

本次共识别 13 个知识点,覆盖 7 个分类。
📂 提取来源(共 8 个文件,点击展开)

文件路径 识别到的知识点
src/views/commentAnalysis/components/period_detail/index.vue script setup, ref(), computed(), v-model, v-if / v-else, v-for, v-slot / #slot
src/views/commentAnalysis/components/period_detail/pick_list_modal/index.vue script setup, ref(), computed(), v-if / v-else, v-for, watch(), defineProps(), defineEmits()
src/views/commentAnalysis/components/period_overall/index.vue script setup
src/views/commentAnalysis/components/period_overall/overall_section/index.vue script setup, ref(), computed(), v-model, v-for, v-slot / #slot, onMounted(), onUnmounted(), nextTick()
src/views/commentAnalysis/components/period_overall/sku_section/index.vue script setup, ref(), v-slot / #slot, watch(), onMounted(), onUnmounted(), nextTick()
src/views/commentAnalysis/components/period_overall/trend_section/index.vue script setup, ref(), v-slot / #slot, watch(), onMounted(), onUnmounted(), nextTick()
src/views/commentAnalysis/index.vue script setup
src/views/makeVideo/components/header/index.vue script setup, ref(), computed(), v-model, v-for, v-slot / #slot

目录

  • [🚀 Vue3 基础](#🚀 Vue3 基础)
  • [⚡ 响应式 API](#⚡ 响应式 API)
  • [🎯 模板指令](#🎯 模板指令)
  • [👁️ 侦听器](#👁️ 侦听器)
  • [📡 组件通信](#📡 组件通信)
  • [🔌 生命周期](#🔌 生命周期)
  • [🔧 工具函数](#🔧 工具函数)

🚀 Vue3 基础

script setup

项目中的用法 (来自 src/views/commentAnalysis/components/period_detail/index.vuesrc/views/commentAnalysis/components/period_detail/pick_list_modal/index.vuesrc/views/commentAnalysis/components/period_overall/index.vuesrc/views/commentAnalysis/components/period_overall/overall_section/index.vuesrc/views/commentAnalysis/components/period_overall/sku_section/index.vuesrc/views/commentAnalysis/components/period_overall/trend_section/index.vuesrc/views/commentAnalysis/index.vuesrc/views/makeVideo/components/header/index.vue):

vue 复制代码
</template>

<script setup>
import { h } from "vue"
import { DownOutlined } from "@ant-design/icons-vue"
import handler from "@/views/commentAnalysis/handler"
import PickListModal from "./pick_list_modal/index.vue"

const needModalOpen = ref(false)
const skuModalOpen = ref(false)

是什么: 组合式 API 语法糖,顶层变量/函数自动暴露给模板,无需 return。

面试 Q&A:

Q:Vue2 Options API 和 Vue3 Composition API 有什么区别?

A:Options API 按选项类型组织代码(data/methods/computed),逻辑分散;Composition API 按功能聚合,逻辑复用靠 composable 函数,更适合大型项目。

Q:setup() 和 <script setup> 有什么不同?

A:setup() 是函数,需要手动 return 暴露给模板;<script setup> 是编译器语法糖,顶层声明自动暴露,代码更简洁,性能略优(编译阶段优化)。


⚡ 响应式 API

ref()

项目中的用法 (来自 src/views/commentAnalysis/components/period_detail/index.vuesrc/views/commentAnalysis/components/period_detail/pick_list_modal/index.vuesrc/views/commentAnalysis/components/period_overall/overall_section/index.vuesrc/views/commentAnalysis/components/period_overall/sku_section/index.vuesrc/views/commentAnalysis/components/period_overall/trend_section/index.vuesrc/views/makeVideo/components/header/index.vue):

vue 复制代码
import PickListModal from "./pick_list_modal/index.vue"

const needModalOpen = ref(false)
const skuModalOpen = ref(false)
const crowdModalOpen = ref(false)
const sceneModalOpen = ref(false)
const emotionModalOpen = ref(false)

const committedNeedIds = ref([])
const committedSkuIds = ref([])

是什么: 将基本类型包装为响应式对象,JS 中访问要加 .value,模板中自动解包。

面试 Q&A:

Q:ref 和 reactive 的区别?

A:ref 用于基本类型(内部用 RefImpl 包装),访问需 .value;reactive 用于对象/数组(基于 Proxy),直接访问属性。ref 也可包对象,内部会自动调用 reactive。

Q:模板里为什么不用写 .value?

A:模板编译时会自动对 ref 解包,访问 ref.value 的操作由编译器插入,开发者无感知。


computed()

项目中的用法 (来自 src/views/commentAnalysis/components/period_detail/index.vuesrc/views/commentAnalysis/components/period_detail/pick_list_modal/index.vuesrc/views/commentAnalysis/components/period_overall/overall_section/index.vuesrc/views/makeVideo/components/header/index.vue):

vue 复制代码
]

const filteredRows = computed(() => {
  let rows = handler.detailRows
  for (const [rowKey, idsRef] of filterChains) {
    if (!idsRef.value.length) continue
    rows = rows.filter((row) =>
      row[rowKey]?.some((id) => idsRef.value.includes(id))
    )
  }

是什么: 基于响应式数据派生的缓存值,依赖不变时不重新计算。

面试 Q&A:

Q:computed 和 methods 的区别?

A:computed 有缓存,依赖不变则直接返回缓存值,适合计算量大的场景;methods 每次调用都重新执行,适合需要触发副作用的操作。

Q:如何实现可写的 computed?

A:传入包含 get 和 set 的对象:computed({ get: () => x.value, set: v => x.value = v }),set 中手动更新源数据。


🎯 模板指令

v-model

项目中的用法 (来自 src/views/commentAnalysis/components/period_detail/index.vuesrc/views/commentAnalysis/components/period_overall/overall_section/index.vuesrc/views/makeVideo/components/header/index.vue):

vue 复制代码
      <div class="card_inner_title">评价明细</div>
      <PickListModal
        v-model:open="needModalOpen"
        title="查找需求"
        :width="440"
        :anchor="pickAnchor"
        :options="handler.needFilterOptions"
        :selected-ids="committedNeedIds"
        @confirm="onPickNeedConfirm"
      >

是什么: 双向绑定语法糖,等价于 :modelValue + @update:modelValue。

面试 Q&A:

Q:v-model 的实现原理?

A:编译器将 v-model 展开为 :modelValue='val' 和 @update:modelValue='val=$event'。组件内用 defineProps(['modelValue']) + defineEmits(['update:modelValue']) 配合使用。

Q:Vue3 和 Vue2 的 v-model 有什么变化?

A:Vue2 用 :value + @input,修改靠 .sync;Vue3 统一为 :modelValue + @update:modelValue,支持多个 v-model(v-model:title、v-model:content),去掉了 .sync。


v-if / v-else

出现在: src/views/commentAnalysis/components/period_detail/index.vuesrc/views/commentAnalysis/components/period_detail/pick_list_modal/index.vue

是什么: 条件渲染,false 时节点从 DOM 移除并销毁组件,适合不频繁切换的场景。

面试 Q&A:

Q:v-if 和 v-show 如何选择?

A:频繁切换用 v-show(只改 display,开销小);初始条件为假且不常切换用 v-if(减少初始渲染开销)。v-if 切换时组件会销毁重建,触发完整生命周期。

Q:v-if 和 v-for 的优先级?

A:Vue3 中 v-if 优先级高于 v-for(Vue2 相反)。不建议同时使用,应用 template 包裹 v-for,在内部元素上用 v-if,或用 computed 过滤数据。


v-for

项目中的用法 (来自 src/views/commentAnalysis/components/period_detail/index.vuesrc/views/commentAnalysis/components/period_detail/pick_list_modal/index.vuesrc/views/commentAnalysis/components/period_overall/overall_section/index.vuesrc/views/makeVideo/components/header/index.vue):

vue 复制代码
          <template v-else-if="column.key === 'sku'">
            <div class="sku_cell">
              <template v-for="(p, i) in record.skuParts" :key="i">
                <span :class="{ strike: p.strike }">{{ p.text }}</span>
                <br v-if="i < record.skuParts.length - 1" />
              </template>
            </div>
          </template>
          <template v-else-if="column.key === 'needs'">
            <div class="tags_cell">

是什么: 列表渲染,必须加 :key(唯一且稳定),key 用于 Diff 算法复用节点。

面试 Q&A:

Q:为什么 v-for 必须加 key?key 用 index 有什么问题?

A:key 让 Diff 算法识别节点身份,复用 DOM 减少操作。用 index 做 key 在列表增删时会导致错误复用(节点身份和数据不匹配),造成状态错乱,应用数据唯一 ID。

Q:Vue3 的 Diff 算法有什么优化?

A:Vue3 Diff 引入最长递增子序列(LIS)算法,最小化节点移动次数;同时增加静态标记(patchFlag)跳过静态节点对比,比 Vue2 快 1.3~2 倍。


v-slot / #slot

出现在: src/views/commentAnalysis/components/period_detail/index.vuesrc/views/commentAnalysis/components/period_overall/overall_section/index.vuesrc/views/commentAnalysis/components/period_overall/sku_section/index.vuesrc/views/commentAnalysis/components/period_overall/trend_section/index.vuesrc/views/makeVideo/components/header/index.vue

是什么: 插槽内容分发,支持默认插槽、具名插槽、作用域插槽。

面试 Q&A:

Q:默认、具名、作用域插槽的区别?

A:默认插槽:<slot> 接收未命名内容;具名插槽:<slot name='header'> + <template #header> 指定位置;作用域插槽:<slot :data='item'> + <template #default='{ data }'> 让父组件拿到子组件数据。


👁️ 侦听器

watch()

项目中的用法 (来自 src/views/commentAnalysis/components/period_detail/pick_list_modal/index.vuesrc/views/commentAnalysis/components/period_overall/sku_section/index.vuesrc/views/commentAnalysis/components/period_overall/trend_section/index.vue):

vue 复制代码
})

watch(
  () => props.open,
  (isOpen) => {
    if (isOpen) draftIds.value = props.selectedIds.slice()
  }
)

// 计算药丸样式

是什么: 侦听指定数据源,变化时执行回调,可获取新旧值,支持 deep/immediate。

面试 Q&A:

Q:watch 和 watchEffect 的核心区别?

A:watch 需要明确指定侦听源,懒执行(默认不立即执行),可拿到新旧值;watchEffect 自动收集依赖,立即执行一次,拿不到旧值。

Q:watch 监听对象的某个属性怎么写?

A:用 getter 函数:watch(() => obj.key, callback)。直接写 watch(obj.key, ...) 只是监听当时的值,不是响应式的。

Q:如何停止侦听?

A:const stop = watch(...); stop() 调用返回值即可停止。组件卸载时会自动停止,手动停止用于在卸载前提前结束侦听。


📡 组件通信

defineProps()

项目中的用法 (来自 src/views/commentAnalysis/components/period_detail/pick_list_modal/index.vue):

vue 复制代码
import pickHandler from "./handler"

const props = defineProps({
  open: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: ""

是什么: 声明组件接收的 props,父传子的核心方式,支持类型约束和默认值。

面试 Q&A:

Q:Vue3 有哪些组件通信方式?

A:① props/emit(父子)② v-model(双向)③ ref + defineExpose(父调子方法)④ provide/inject(跨层级)⑤ Pinia(全局状态)⑥ mitt 事件总线(任意组件)

Q:props 是单向数据流,子组件能直接修改吗?

A:不能直接修改,会报警告。正确做法:① emit 通知父组件修改 ② 将 prop 赋值给本地 ref 再修改本地数据 ③ 使用 v-model。


defineEmits()

项目中的用法 (来自 src/views/commentAnalysis/components/period_detail/pick_list_modal/index.vue):

vue 复制代码
})

const emit = defineEmits(["update:open", "confirm"])

const draftIds = ref([])

const isAnchored = computed(() => !!props.anchor)

const wrapCls = computed(() =>
  props.anchor ? `${props.wrapClassName} pick_list_modal_anchored` : props.wrapClassName

是什么: 声明组件可触发的自定义事件,子传父的核心方式。

面试 Q&A:

Q:emit 和 v-model 的关系?

A:v-model 本质是 :modelValue + @update:modelValue 的语法糖。子组件用 defineEmits(['update:modelValue']),然后 emit('update:modelValue', newVal) 即可实现双向绑定。


🔌 生命周期

onMounted()

项目中的用法 (来自 src/views/commentAnalysis/components/period_overall/overall_section/index.vuesrc/views/commentAnalysis/components/period_overall/sku_section/index.vuesrc/views/commentAnalysis/components/period_overall/trend_section/index.vue):

vue 复制代码
const resizeChart = () => chart && chart.resize()

onMounted(() => {
  nextTick(() => {
    if (!pieRef.value) return
    chart = echarts.init(pieRef.value)
    chart.setOption(buildPieOption())
    window.addEventListener("resize", resizeChart)
  })
})

是什么: 组件挂载到真实 DOM 后执行,可安全操作 DOM、发起请求。

面试 Q&A:

Q:Vue3 生命周期和 Vue2 的对应关系?

A:beforeCreate/created → setup();beforeMount → onBeforeMount;mounted → onMounted;beforeUpdate → onBeforeUpdate;updated → onUpdated;beforeDestroy → onBeforeUnmount;destroyed → onUnmounted。

Q:为什么不在 setup 顶层直接操作 DOM?

A:setup 执行时组件还未挂载,DOM 不存在。需要在 onMounted 里操作 DOM,此时模板已渲染完毕。


onUnmounted()

项目中的用法 (来自 src/views/commentAnalysis/components/period_overall/overall_section/index.vuesrc/views/commentAnalysis/components/period_overall/sku_section/index.vuesrc/views/commentAnalysis/components/period_overall/trend_section/index.vue):

vue 复制代码
})

onUnmounted(() => {
  window.removeEventListener("resize", resizeChart)
  chart?.dispose()
  chart = null
})
</script>

<style lang="less" src="./index.less" scoped></style>

是什么: 组件销毁后执行,必须在此清除定时器、取消订阅,防止内存泄漏。

面试 Q&A:

Q:不清除定时器会发生什么?

A:组件销毁后定时器仍在运行,回调中访问已销毁组件的数据会报错,且定时器无法被 GC 回收,导致内存泄漏。每次重新挂载组件还会叠加创建新定时器。


🔧 工具函数

nextTick()

项目中的用法 (来自 src/views/commentAnalysis/components/period_overall/overall_section/index.vuesrc/views/commentAnalysis/components/period_overall/sku_section/index.vuesrc/views/commentAnalysis/components/period_overall/trend_section/index.vue):

vue 复制代码
onMounted(() => {
  nextTick(() => {
    if (!pieRef.value) return
    chart = echarts.init(pieRef.value)
    chart.setOption(buildPieOption())
    window.addEventListener("resize", resizeChart)
  })
})

是什么: 等待下一次 DOM 更新后执行,用于数据修改后立即操作更新后的 DOM。

面试 Q&A:

Q:nextTick 的原理?

A:Vue 的 DOM 更新是异步批量的(微任务队列)。修改数据后 DOM 不会立即更新,nextTick 将回调推入同一微任务队列的末尾,等 DOM 更新完成后执行。底层用 Promise.then 实现。

Q:nextTick 和 setTimeout 的区别?

A:nextTick 用微任务(Promise),在当前宏任务结束、下一个宏任务开始前执行,时机更早;setTimeout 是宏任务,会在所有微任务执行完后才运行,时机更晚,可能看到中间状态。


由 vue_learn.py 自动生成 · 2026-03-20 13:23

相关推荐
木斯佳2 小时前
前端八股文面经大全:Bilibili 前端实习面(2026-03-20)·深度解析
前端·sse·ssr·rag
比特森林探险记2 小时前
Element Plus 实战指南
前端·javascript
Fairy要carry2 小时前
面试-Dispatch Tools
前端·chrome
IT_陈寒2 小时前
JavaScript开发者必看:3个让代码效率翻倍的隐藏技巧
前端·人工智能·后端
嘉琪0012 小时前
Day8 完整学习包(Vue 基础 & 响应式)——2026 0320
前端·vue.js·学习
FlyWIHTSKY2 小时前
Vue3 单文件中不同的组件
前端·javascript·vue.js
一字白首2 小时前
小程序组件化进阶:从复用到通信的完整指南DAY04
前端·小程序·apache
读忆2 小时前
你是否用过Tailwind CSS?你是在什么情况下使用的呢?
前端·css·经验分享·笔记·taiiwindcss
阿珊和她的猫2 小时前
探秘小程序:为何拿不到 DOM 相关 API
前端·小程序