跳到内容
当前位置:首页>面试真题>第七章(Vue 面试真题)

第七章(Vue 面试真题)

  • 2026-09-22 23:08:00
第七章(Vue 面试真题)

一、Vue 基础真题

1. Vue 的双向绑定原理?

参考答案:

Vue 2 使用 Object.defineProperty,Vue 3 使用 Proxy。

// Vue 2 Object.defineProperty
functiondefineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
return val;
        },
set(newVal) {
            val = newVal;
update(); // 触发更新
        }
    });
}

// Vue 3 Proxy
functionreactive(obj) {
returnnewProxy(obj, {
get(target, key) {
track(target, key);
return target[key];
        },
set(target, key, value) {
            target[key] = value;
trigger(target, key);
        }
    });
}

2. Vue 的生命周期有哪些?

参考答案:

Vue 2:

  • beforeCreate → created → beforeMount → mounted → beforeUpdate → updated → beforeDestroy → destroyed

Vue 3:

  • setup → onBeforeMount → onMounted → onBeforeUpdate → onUpdated → onBeforeUnmount → onUnmounted
// Vue 3
import { onMounted, onUpdated, onUnmounted } from'vue';

exportdefault {
setup() {
onMounted(() => {
console.log('挂载完成');
        });
onUpdated(() => {
console.log('更新完成');
        });
onUnmounted(() => {
console.log('卸载完成');
        });
    }
}

3. Vue 的 computed 和 watch 的区别?

参考答案:

特性
computed
watch
缓存
✅
❌
适用场景
计算属性
监听数据变化
返回值
必须返回值
不需要
// computed - 有缓存
const double = computed(() => count.value * 2);

// watch - 监听数据变化
watch(count, (newVal, oldVal) => {
console.log('变化了', newVal, oldVal);
});

// 监听多个属性
watch([a, b], ([newA, newB]) => {
console.log(newA, newB);
});

// 深度监听
watch(obj, () => {}, { deep: true });

4. Vue 组件通信方式有哪些?

参考答案:

  1. props / $emit: 父子通信
  2. $attrs: 父子通信(跳过props)
  3. $refs: 父子通信
  4. provide / inject: 祖先向后代传值
  5. event bus: 兄弟/跨级通信
  6. Vuex/Pinia: 全局状态管理
// provide / inject
// 祖先
provide('theme', 'dark');

// 后代
const theme = inject('theme');

// $attrs
// 父组件
<Childname="Tom"age="25" />

// 子组件
props: ['name']
console.log(this.$attrs) // { age: '25' }

5. v-if 和 v-show 的区别?

参考答案:

特性
v-if
v-show
原理
DOM 删除/创建
CSS display
开销
高
低
适用场景
条件不常变化
频繁切换
<!-- v-if -->
<divv-if="show">内容</div>

<!-- v-show -->
<divv-show="show">内容</div>

二、Vue 进阶真题

6. Vue 3 的 Composition API 是什么?

参考答案:

Composition API 是 Vue 3 新增的 API,用函数方式组织组件逻辑。

import { ref, reactive, computed, watch, onMounted } from'vue';

exportdefault {
setup() {
// 响应式数据
const count = ref(0);
const state = reactive({ name: 'Tom' });

// 计算属性
const double = computed(() => count.value * 2);

// 监听
watch(count, (newVal) => {
console.log(newVal);
        });

// 生命周期
onMounted(() => {
console.log('mounted');
        });

return { count, state, double };
    }
}

7. Vue 3 的 ref 和 reactive 的区别?

参考答案:

// ref - 基础类型
const count = ref(0);
count.value = 1; // 访问值需要 .value

// reactive - 对象类型
const state = reactive({
name: 'Tom',
age: 25
});
state.name = 'Jerry'; // 直接访问

// ref 也支持对象,内部会调用 reactive
const obj = ref({ name: 'Tom' });
obj.value.name = 'Jerry'; // 内部转为 reactive

8. Vue 的 keep-alive 是什么?

参考答案:

keep-alive 是缓存组件,避免重复渲染。

<keep-alive:include="['Home', 'About']":exclude="['Login']">
<component:is="currentComponent" />
</keep-alive>

<!-- 路由缓存 -->
<router-viewv-slot="{ Component }">
<keep-alive>
<component:is="Component" />
</keep-alive>
</router-view>

生命周期变化:

  • 首次进入:onMounted → onActivated
  • 再次进入:onActivated
  • 离开:onDeactivated

9. Vue 的 nextTick 是什么?

参考答案:

nextTick 等待 DOM 更新后执行回调。

// 修改数据
this.msg = 'Hello';

// 此时 DOM 还未更新
console.log(this.$refs.text); // 旧内容

// 使用 nextTick
this.$nextTick(() => {
console.log(this.$refs.text); // 新内容
});

// async/await 方式
asyncfunctionupdate() {
this.msg = 'Hello';
awaitthis.$nextTick();
console.log(this.$refs.text);
}

10. Vue 的 Mixin 是什么?

参考答案:

Mixin 是复用组件逻辑的方式。

// myMixin.js
exportdefault {
data() {
return {
name: 'Tom'
        }
    },
methods: {
sayHello() {
console.log('Hello');
        }
    }
}

// 使用
import myMixin from'./myMixin';

exportdefault {
mixins: [myMixin],
mounted() {
this.sayHello(); // Hello
    }
}

三、Vue 面试真题

11. Vue 的响应式原理?

参考答案:

Vue 2 使用 Object.defineProperty 劫持 getter/setter。

functionobserve(obj) {
if (typeof obj !== 'object' || obj === null) return;

Object.keys(obj).forEach(key => {
let value = obj[key];
defineReactive(obj, key, value);
    });
}

functiondefineReactive(obj, key, value) {
observe(value); // 递归监听

Object.defineProperty(obj, key, {
get() {
return value;
        },
set(newVal) {
if (newVal !== value) {
                value = newVal;
observe(newVal);
update(); // 通知更新
            }
        }
    });
}

Vue 3 使用 Proxy,性能更好。


12. Vue 的 diff 算法?

参考答案:

Vue 的 diff 算法是同层比较,时间复杂度 O(n)。

// patch 函数
functionpatch(oldVnode, newVnode) {
if (sameVnode(oldVnode, newVnode)) {
patchVnode(oldVnode, newVnode);
    } else {
replaceNode(oldVnode, newVnode);
    }
}

functionsameVnode(a, b) {
return a.key === b.key && a.tag === b.tag;
}

优化:

  • 使用 key 识别节点
  • 列表对比使用双端比较

13. Vuex 的工作流程?

参考答案:

State → Getter → Component
   ↑              ↓
   └──── Mutation ← Action
// state
state: { count: 0 }

// mutation
mutations: {
increment(state) {
        state.count++;
    }
}

// action
actions: {
increment({ commit }) {
commit('increment');
    }
}

// getter
getters: {
double: state => state.count * 2
}

14. Vue 3 的 setup 函数?

参考答案:

setup 是 Composition API 的入口。

exportdefault {
setup(props, { attrs, slots, emit, expose }) {
// props 需要定义
const name = ref('Tom');

// 暴露给模板
return { name };

// 暴露给父组件
expose({ name });
    }
}

15. Vue 3 和 Vue 2 的区别?

参考答案:

特性
Vue 2
Vue 3
响应式
Object.defineProperty
Proxy
API
Options API
Composition API
生命周期
beforeCreate/created
setup
性能
中
高
TypeScript
弱
强
打包体积
中
小

16. Vue 组件通信方式?

参考答案:

// 1. Props / $emit
// 父组件
<Child :value="msg" @change="handleChange" />

// 子组件
props: { value: String }
this.$emit('change', 'new value')

// 2. Provide / Inject
// 父组件
provide: { name: 'Tom' }

// 子组件
inject: ['name']

// 3. Event Bus
// bus.js
const bus = newVue();
exportdefault bus;

// 使用
bus.$emit('event', data);
bus.$on('event', callback);

// 4. Vuex / Pinia
// 5. ref / defineExpose

17. Vue 路由守卫?

参考答案:

const router = newVueRouter({
routes: [
        {
path: '/user',
component: User,
beforeEnter: (to, from, next) => {
next();
            }
        }
    ]
});

// 全局守卫
router.beforeEach((to, from, next) => {
const isAuth = localStorage.getItem('token');
if (isAuth || to.path === '/login') {
next();
    } else {
next('/login');
    }
});

// 组件内守卫
beforeRouteEnter(to, from, next) {},
beforeRouteUpdate(to, from, next) {},
beforeRouteLeave(to, from, next) {}

18. Vue 自定义指令?

参考答案:

// 全局指令
Vue.directive('focus', {
inserted(el) {
        el.focus();
    }
});

// 组件指令
directives: {
focus: {
inserted(el) {
            el.focus();
        }
    }
}

// 使用
<input v-focus />

19. Vue 过滤器?

参考答案:

// 定义过滤器
filters: {
currency(value) {
return'¥' + value.toFixed(2);
    }
}

// 使用
{{ price | currency }}

// 链式
{{ price | currency | lowercase }}

20. Vue 动态组件?

参考答案:

<!-- is 属性 -->
<component :is="currentComponent" />

<!-- keep-alive 缓存 -->
<keep-alive>
    <component :is="currentComponent" />
</keep-alive>

21. Vue 异步组件?

参考答案:

// 方式1: defineAsyncComponent
import { defineAsyncComponent } from'vue';
constAsyncComp = defineAsyncComponent(() =>
import('./AsyncComp.vue')
);

// 方式2: 组件定义
exportdefault {
components: {
AsyncComp: () =>import('./AsyncComp.vue')
    }
}

22. Vue 混入 mixins?

参考答案:

// mixin.js
exportdefault {
data() {
return { name: 'Tom' }
    },
methods: {
hello() {
console.log(this.name);
        }
    }
}

// 使用
import myMixin from'./mixin';
exportdefault {
mixins: [myMixin]
}

23. Vue extend?

参考答案:

// 创建组件构造器
constProfile = Vue.extend({
template: '<p>{{ firstName }} {{ lastName }}</p>',
data() {
return { firstName: 'Tom', lastName: 'Jack' }
    }
});

// 创建实例
newProfile().$mount('#app');

24. Vue $nextTick?

参考答案:

methods: {
asyncupdate() {
this.msg = 'Hello';

// DOM 更新后执行
this.$nextTick(() => {
console.log(this.$refs.input.value);
        });

// async/await 写法
awaitthis.$nextTick();
console.log(this.$refs.input.value);
    }
}

25. Vue 响应式原理?

参考答案:

Vue 2 使用 Object.defineProperty,Vue 3 使用 Proxy。

// Vue 2
functiondefineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
return val;
        },
set(newVal) {
if (newVal !== val) {
                val = newVal;
update();
            }
        }
    });
}

// Vue 3
const handler = {
get(target, key) {
track(target, key);
returnReflect.get(target, key);
    },
set(target, key, value) {
Reflect.set(target, key, value);
trigger(target, key);
    }
};

26. Vue computed 和 watch?

参考答案:

computed: {
fullName() {
returnthis.firstName + ' ' + this.lastName;
    },
// setter
fullName: {
get() {
returnthis.firstName + ' ' + this.lastName;
        },
set(val) {
const [first, last] = val.split(' ');
this.firstName = first;
this.lastName = last;
        }
    }
}

watch: {
msg(newVal, oldVal) {
console.log(newVal, oldVal);
    },
// 深度监听
obj: {
handler(newVal) {},
deep: true
    },
// 立即执行
msg: {
handler() {},
immediate: true
    }
}

27. Vue slot?

参考答案:

<!-- 父组件 -->
<Child>
    <template v-slot:header>
        <h1>标题</h1>
    </template>

    <p>默认内容</p>

    <template v-slot:footer>
        <p>底部</p>
    </template>
</Child>

<!-- 子组件 -->
<div>
    <slot name="header"></slot>
    <slot></slot>
    <slot name="footer"></slot>
</div>

28. Vue 条件渲染?

参考答案:

<!-- v-if / v-else-if / v-else -->
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else>C</div>

<!-- v-show -->
<div v-show="show">显示/隐藏</div>

<!-- 区别:v-if 真正渲染,v-show 始终渲染并使用 display -->

29. Vue 列表渲染?

参考答案:

<!-- 数组 -->
<li v-for="(item, index) in items" :key="index">
    {{ index }} - {{ item.name }}
</li>

<!-- 对象 -->
<li v-for="(value, key, index) in obj" :key="key">
    {{ key }}: {{ value }}
</li>

<!-- 组件 -->
<my-component
    v-for="item in items"
    :key="item.id"
    :item="item"
/>

30. Vue 自定义 v-model?

参考答案:

<!-- 子组件 -->
<script>
export default {
    model: {
        prop: 'value',
        event: 'change'
    },
    props: {
        value: String
    },
    methods: {
        update(val) {
            this.$emit('change', val);
        }
    }
}
</script>

<!-- 使用 -->
<input :value="value" @input="update($event.target.value)" />

📌 面试重点:双向绑定原理、生命周期、Composition API、响应式原理是高频考点。