有点难度Vue 面试题+详解答案,阿里p8岗需要几轮面试

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
img

正文

const name: ?string = getComponentName(componentOptions);

const { include, exclude } = this;

// 不走缓存

if (

// not included 不包含

(include && (!name || !matches(include, name))) ||

// excluded 排除里面

(exclude && name && matches(exclude, name))

) {

//返回虚拟节点

return vnode;

}

const { cache, keys } = this;

const key: ?string =

vnode.key == null

? // same constructor may get registered as different local components

// so cid alone is not enough (#3269)

componentOptions.Ctor.cid +

(componentOptions.tag ? ::${componentOptions.tag} : “”)
vnode.key;

if (cache[key]) {

//通过key 找到缓存 获取实例

vnode.componentInstance = cache[key].componentInstance;

// make current key freshest

remove(keys, key); //通过LRU算法把数组里面的key删掉

keys.push(key); //把它放在数组末尾

} else {

cache[key] = vnode; //没找到就换存下来

keys.push(key); //把它放在数组末尾

// prune oldest entry //如果超过最大值就把数组第0项删掉

if (this.max && keys.length > parseInt(this.max)) {

pruneCacheEntry(cache, keys[0], keys, this._vnode);

}

}

vnode.data.keepAlive = true; //标记虚拟节点已经被缓存

}

// 返回虚拟节点

return vnode || (slot && slot[0]);

},

};

4.Vue.set 方法原理

了解 Vue 响应式原理的同学都知道在两种情况下修改数据 Vue 是不会触发视图更新的

1.在实例创建之后添加新的属性到实例上(给响应式对象新增属性)

2.直接更改数组下标来修改数组的值

Vue.set 或者说是$set 原理如下

因为响应式数据 我们给对象和数组本身都增加了__ob__属性,代表的是 Observer 实例。当给对象新增不存在的属性 首先会把新的属性进行响应式跟踪 然后会触发对象__ob__的 dep 收集到的 watcher 去更新,当修改数组索引时我们调用数组本身的 splice 方法去更新数组

相关代码如下

export function set(target: Array | Object, key: any, val: any): any {

// 如果是数组 调用我们重写的splice方法 (这样可以更新视图)

if (Array.isArray(target) && isValidArrayIndex(key)) {

target.length = Math.max(target.length, key);

target.splice(key, 1, val);

return val;

}

// 如果是对象本身的属性,则直接添加即可

if (key in target && !(key in Object.prototype)) {

target[key] = val;

return val;

}

const ob = (target: any).ob;

// 如果不是响应式的也不需要将其定义成响应式属性

if (!ob) {

target[key] = val;

return val;

}

// 将属性定义成响应式的

defineReactive(ob.value, key, val);

// 通知视图更新

ob.dep.notify();

return val;

}

5.Vue.extend 作用和原理

官方解释:Vue.extend 使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。

其实就是一个子类构造器 是 Vue 组件的核心 api 实现思路就是使用原型继承的方法返回了 Vue 的子类 并且利用 mergeOptions 把传入组件的 options 和父类的 options 进行了合并

相关代码如下

export default function initExtend(Vue) {

let cid = 0; //组件的唯一标识

// 创建子类继承Vue父类 便于属性扩展

Vue.extend = function (extendOptions) {

// 创建子类的构造函数 并且调用初始化方法

const Sub = function VueComponent(options) {

this._init(options); //调用Vue初始化方法

};

Sub.cid = cid++;

Sub.prototype = Object.create(this.prototype); // 子类原型指向父类

Sub.prototype.constructor = Sub; //constructor指向自己

Sub.options = mergeOptions(this.options, extendOptions); //合并自己的options和父类的options

return Sub;

};

}

Vue 组件原理详解 传送门

6.写过自定义指令吗 原理是什么

指令本质上是装饰器,是 vue 对 HTML 元素的扩展,给 HTML 元素增加自定义功能。vue 编译 DOM 时,会找到指令对象,执行指令的相关方法。

自定义指令有五个生命周期(也叫钩子函数),分别是 bind、inserted、update、componentUpdated、unbind

  1. bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  2. inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  3. update:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。

  4. componentUpdated:被绑定元素所在模板完成一次更新周期时调用。

  5. unbind:只调用一次,指令与元素解绑时调用。

原理

1.在生成 ast 语法树时,遇到指令会给当前元素添加 directives 属性

2.通过 genDirectives 生成指令代码

3.在 patch 前将指令的钩子提取到 cbs 中,在 patch 过程中调用对应的钩子

4.当执行指令对应钩子函数时,调用对应指令定义的方法

7.Vue 修饰符有哪些

事件修饰符

  • .stop 阻止事件继续传播

  • .prevent 阻止标签默认行为

  • .capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理

  • .self 只当在 event.target 是当前元素自身时触发处理函数

  • .once 事件将只会触发一次

  • .passive 告诉浏览器你不想阻止事件的默认行为

v-model 的修饰符

  • .lazy 通过这个修饰符,转变为在 change 事件再同步

  • .number 自动将用户的输入值转化为数值类型

  • .trim 自动过滤用户输入的首尾空格

键盘事件的修饰符

  • .enter

  • .tab

  • .delete (捕获“删除”和“退格”键)

  • .esc

  • .space

  • .up

  • .down

  • .left

  • .right

系统修饰键

  • .ctrl

  • .alt

  • .shift

  • .meta

鼠标按钮修饰符

  • .left

  • .right

  • .middle

8.Vue 模板编译原理

Vue 的编译过程就是将 template 转化为 render 函数的过程 分为以下三步

第一步是将 模板字符串 转换成 element ASTs(解析器)

第二步是对 AST 进行静态节点标记,主要用来做虚拟DOM的渲染优化(优化器)

第三步是 使用 element ASTs 生成 render 函数代码字符串(代码生成器)

相关代码如下

export function compileToFunctions(template) {

// 我们需要把html字符串变成render函数

// 1.把html代码转成ast语法树 ast用来描述代码本身形成树结构 不仅可以描述html 也能描述css以及js语法

// 很多库都运用到了ast 比如 webpack babel eslint等等

let ast = parse(template);

// 2.优化静态节点

// 这个有兴趣的可以去看源码 不影响核心功能就不实现了

// if (options.optimize !== false) {

// optimize(ast, options);

// }

// 3.通过ast 重新生成代码

// 我们最后生成的代码需要和render函数一样

// 类似_c(‘div’,{id:“app”},_c(‘div’,undefined,_v(“hello”+_s(name)),_c(‘span’,undefined,_v(“world”))))

// _c代表创建元素 _v代表创建文本 _s代表文Json.stringify–把对象解析成文本

let code = generate(ast);

// 使用with语法改变作用域为this 之后调用render函数可以使用call改变this 方便code里面的变量取值

let renderFn = new Function(with(this){return ${code}});

return renderFn;

}

9.生命周期钩子是如何实现的

Vue 的生命周期钩子核心实现是利用发布订阅模式先把用户传入的的生命周期钩子订阅好(内部采用数组的方式存储)然后在创建组件实例的过程中会一次执行对应的钩子方法(发布)

相关代码如下

export function callHook(vm, hook) {

// 依次执行生命周期对应的方法

const handlers = vm.$options[hook];

if (handlers) {

for (let i = 0; i < handlers.length; i++) {

handlers[i].call(vm); //生命周期里面的this指向当前实例

}

}

}

// 调用的时候

Vue.prototype._init = function (options) {

const vm = this;

vm.$options = mergeOptions(vm.constructor.options, options);

callHook(vm, “beforeCreate”); //初始化数据之前

// 初始化状态

initState(vm);

callHook(vm, “created”); //初始化数据之后

if (vm.$options.el) {

vm. m o u n t ( v m . mount(vm. mount(vm.options.el);

}

};

10.函数式组件使用场景和原理

函数式组件与普通组件的区别

1.函数式组件需要在声明组件是指定 functional:true

2.不需要实例化,所以没有this,this通过render函数的第二个参数context来代替

3.没有生命周期钩子函数,不能使用计算属性,watch

4.不能通过$emit 对外暴露事件,调用事件只能通过context.listeners.click的方式调用外部传入的事件

5.因为函数式组件是没有实例化的,所以在外部通过ref去引用组件时,实际引用的是HTMLElement

6.函数式组件的props可以不用显示声明,所以没有在props里面声明的属性都会被自动隐式解析为prop,而普通组件所有未声明的属性都解析到$attrs里面,并自动挂载到组件根元素上面(可以通过inheritAttrs属性禁止)

优点 1.由于函数式组件不需要实例化,无状态,没有生命周期,所以渲染性能要好于普通组件 2.函数式组件结构比较简单,代码结构更清晰

使用场景:

一个简单的展示组件,作为容器组件使用 比如 router-view 就是一个函数式组件

“高阶组件”——用于接收一个组件作为参数,返回一个被包装过的组件

相关代码如下

if (isTrue(Ctor.options.functional)) {

// 带有functional的属性的就是函数式组件

return createFunctionalComponent(Ctor, propsData, data, context, children);

}

const listeners = data.on;

data.on = data.nativeOn;

installComponentHooks(data); // 安装组件相关钩子 (函数式组件没有调用此方法,从而性能高于普通组件)

11.能说下 vue-router 中常用的路由模式实现原理吗

hash 模式

  1. location.hash 的值实际就是 URL 中#后面的东西 它的特点在于:hash 虽然出现 URL 中,但不会被包含在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。

  2. 可以为 hash 的改变添加监听事件

window.addEventListener(“hashchange”, funcRef, false);

每一次改变 hash(window.location.hash),都会在浏览器的访问历史中增加一个记录利用 hash 的以上特点,就可以来实现前端路由“更新视图但不重新请求页面”的功能了

特点:兼容性好但是不美观

history 模式

利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。

Vue 面试题

1.Vue 双向绑定原理
2.描述下 vue 从初始化页面–修改数据–刷新页面 UI 的过程?
3.你是如何理解 Vue 的响应式系统的?
4.虚拟 DOM 实现原理
5.既然 Vue 通过数据劫持可以精准探测数据变化,为什么还需要虚拟 DOM 进行 diff 检测差异?
6.Vue 中 key 值的作用?
7.Vue 的生命周期
8.Vue 组件间通信有哪些方式?
9.watch、methods 和 computed 的区别?
10.vue 中怎么重置 data?
11.组件中写 name 选项有什么作用?
12.vue-router 有哪些钩子函数?
13.route 和 router 的区别是什么?
14.说一下 Vue 和 React 的认识,做一个简单的对比
15.Vue 的 nextTick 的原理是什么?
16.Vuex 有哪几种属性?
17.vue 首屏加载优化
18.Vue 3.0 有没有过了解?
19.vue-cli 替我们做了哪些工作?

算法

  1. 冒泡排序
  2. 选择排序
  3. 快速排序
  4. 二叉树查找: 最大值、最小值、固定值
  5. 二叉树遍历
  6. 二叉树的最大深度
  7. 给予链表中的任一节点,把它删除掉
  8. 链表倒叙
  9. 如何判断一个单链表有环
  10. 给定一个有序数组,找出两个数相加为一个目标数

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!有需要的程序猿(媛)可以帮忙点赞+评论666

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
的原理是什么?
16.Vuex 有哪几种属性?
17.vue 首屏加载优化
18.Vue 3.0 有没有过了解?
19.vue-cli 替我们做了哪些工作?

[外链图片转存中…(img-HkO8Dvbu-1713088447405)]

算法

  1. 冒泡排序
  2. 选择排序
  3. 快速排序
  4. 二叉树查找: 最大值、最小值、固定值
  5. 二叉树遍历
  6. 二叉树的最大深度
  7. 给予链表中的任一节点,把它删除掉
  8. 链表倒叙
  9. 如何判断一个单链表有环
  10. 给定一个有序数组,找出两个数相加为一个目标数

    [外链图片转存中…(img-C8C8Mi7t-1713088447405)]

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!有需要的程序猿(媛)可以帮忙点赞+评论666

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-D8eqsdEe-1713088447406)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 28
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值