面试题答案
一键面试1..stop和.prevent修饰符的实现机制(从Vue源码角度)
- .stop修饰符:
- 在Vue模板编译阶段,模板编译器会将带
.stop
修饰符的事件绑定转化为对应的JavaScript代码。 - 当事件触发时,会执行
event.stopPropagation()
方法,阻止事件冒泡到父级元素。例如,模板<button @click.stop="handleClick">点击</button>
,编译后在事件处理函数内部会添加event.stopPropagation()
逻辑,使得该按钮点击事件不会传递到父级元素。
- 在Vue模板编译阶段,模板编译器会将带
- .prevent修饰符:
- 同样在模板编译阶段,模板编译器处理带
.prevent
修饰符的事件绑定。 - 当事件触发时,会执行
event.preventDefault()
方法,阻止事件的默认行为。比如<a @click.prevent="handleClick" href="#">链接</a>
,点击链接时,默认的跳转行为会被阻止,因为在事件处理函数内部添加了event.preventDefault()
逻辑。
- 同样在模板编译阶段,模板编译器处理带
2. 在自定义指令中模拟这两个修饰符功能的设计与实现
- 实现思路:
- 自定义指令需要在绑定元素的事件触发时,判断是否需要模拟
.stop
或.prevent
的行为。 - 可以通过指令的
bind
或inserted
钩子函数来绑定事件监听器,在事件监听器函数中实现.stop
和.prevent
的逻辑。
- 自定义指令需要在绑定元素的事件触发时,判断是否需要模拟
- 关键代码片段:
// 自定义指令模拟.stop和.prevent修饰符
Vue.directive('myEvent', {
bind(el, binding) {
const handler = function (event) {
if (binding.modifiers.stop) {
event.stopPropagation();
}
if (binding.modifiers.prevent) {
event.preventDefault();
}
// 执行用户自定义的事件处理函数
if (typeof binding.value === 'function') {
binding.value.call(el, event);
}
};
// 根据指令绑定的事件类型添加监听器
const eventType = binding.arg;
el.addEventListener(eventType, handler);
},
unbind(el, binding) {
const eventType = binding.arg;
const handler = function (event) {
if (binding.modifiers.stop) {
event.stopPropagation();
}
if (binding.modifiers.prevent) {
event.preventDefault();
}
if (typeof binding.value === 'function') {
binding.value.call(el, event);
}
};
el.removeEventListener(eventType, handler);
}
});
在模板中使用:
<template>
<div>
<button v-myEvent:click.stop.prevent="handleClick">点击</button>
</div>
</template>
<script>
export default {
methods: {
handleClick(event) {
console.log('按钮被点击');
}
}
};
</script>
在上述代码中,自定义指令v - myEvent
通过bind
钩子函数为元素添加事件监听器,在监听器函数中判断是否有.stop
和.prevent
修饰符,并执行相应的逻辑。unbind
钩子函数用于移除事件监听器,以避免内存泄漏。