2024年Web前端最新学习vue源码(1) 手写与事件相关的实例方法(5),数据结构与算法面试题库及答案

算法刷题

大厂面试还是很注重算法题的,尤其是字节跳动,算法是问的比较多的,关于算法,推荐《LeetCode》和《算法的乐趣》,这两本我也有电子版,字节跳动、阿里、美团等大厂面试题(含答案+解析)、学习笔记、Xmind思维导图均可以分享给大家学习。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

写在最后

最后,对所以做Java的朋友提几点建议,也是我的个人心得:

  1. 疯狂编程

  2. 学习效果可视化

  3. 写博客

  4. 阅读优秀代码

  5. 心态调整

Vue.prototype.$emit = function (event) {

var vm = this;

var cbs = vm._events[event];

if (cbs) {

// const args = toArray(arguments,1);

cbs = cbs.length > 1 ? toArray(cbs) : cbs;

var args = toArray(arguments, 1);

var info = “event handler for “” + event + “””;

for (var i = 0, l = cbs.length; i < l; i++) {

try{

cbs[i].apply(vm,args)

}catch(e){

handleError(e,vm,event handler for "${event}")

}

}

}

return vm

};

使用event从vm._events中取出事件监听器回调函数列表,并将其赋值给变量cbs,如果cbs存在,依次调用每一个监听器回调并将其所有参数传给监听器回调。

toArray的作用是将类似于数组的数据换成真正的数组,它的第二个参数是起始位置,也就是说,args是一个数组,里面包含除第一个参数之外的所有参数。

o n 和 on和 on和emit可以结合起来使用,大部分用于父子组件传值,但是这里有一个问题

1、究竟是由子组件内部主动传数据给父组件,由父组件监听接收(由子组件中操作决定什么时候传值)

2、还是通过父组件决定子组件什么时候传值给父组件,然后再监听接收 (由父组件中操作决定什么时候传值)

两种情况都有

m e i t 事 件 触 发 , 通 过 子 组 件 内 部 的 事 件 触 发 自 定 义 事 件 meit事件触发,通过子组件内部的事件触发自定义事件 meit事件触发,通过子组件内部的事件触发自定义事件emit

m e i t 事 件 触 发 , 可 以 通 过 父 组 件 操 作 子 组 件 ( r e f ) 的 事 件 来 触 发 自 定 义 事 件 meit事件触发, 可以通过父组件操作子组件 (ref)的事件来触发 自定义事件 meit事件触发,可以通过父组件操作子组件(ref)的事件来触发自定义事件emit

第一种情况

父组件 所以msg打印出来就是蜡笔小柯南

子组件

第二种情况

父组件 通过ref操作子组件触发事件

子组件

将两者情况对比,区别就在于$emit 自定义事件的触发是有父组件还是子组件去触发

第一种,是在子组件中定义一个click点击事件来触发自定义事件$emit,然后在父组件监听

第二种,是在父组件中第一一个click点击事件,在组件中通过refs获取实例方法来直接触发事件,然后在父组件中监听

用法:

移除自定义事件监听器。

如果没有提供参数,则移除所有的事件监听器;

如果只提供了事件,则移除该事件所有的监听器;

如果同时提供了事件与回调,则只移除这个回调的监听器。

Vue.prototype.$off = function(event,fn){

const vm = this;

//1-1、没有提供参数的情况,此时需要移除所有事件的监听器

if(!arguments.length){

// 当arguments.lengtha为0时,说明没有任何参数,这时需要移除所有事件监听器

// 因此重置了vm._events属性,vm._events存储所有事件,所以将vm._events重置

// 为初始状态就等同于将所有事件都移除了。

vm._events = Object.create(null);

return vm;

}

// 1-2、vm.$off的第一个参数支持数组,当event为数组的时候,只需要将数组遍历一遍,然后

// 数组中的每一项依次调用vm.$off;

if(Array.isArray(event)){

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

this.$off(event[i],fn)

}

return vm;

}

// 2、只提供了事件名,则移除该事件所有的监听器,只需要将vm._events中的event重置为空就行

const cbs = vm._events[event];

if(!cbs){

return vm;

}

// 这里做了一个安全检测,如果这个事件没有被监听,vm._events内找不到任何监听器,直接退出

// 程序,然后判断是否只有一个参数,如果是,将事件名在vm._events中所有事件都移除,只需要

// 将vm._events上以该事件为属性的值设置为null即可

if(arguments.length === 1){

vm._events[event] = null;

return vm;

}

// 3、如果同时提供了事件与回调,那么只移除这个回调的监听器,将使用参数中提供的事件名从

// vm._events取出事件列表,然后从列表中找到与参数中提供的回调函数相同的那个函数,并

// 将它从列表中移除

if(fn){

// 先判断是否有fn参数,有则说明用户同时提供了event和fn两个参数,然后从vm._events

// 中取出事件监听器列表并遍历它,如果列表中的某一项与fn相同,或者某一项的fn属性与fn相同,

// 使用splice方法将它从列表中移除,当循环结束后,列表中所有与用户参数中提供的fn相同的监听器

// 都会被移除

const cbd = vm._events[event];

let cb;

let i = cbs.length;

while(i–){

// 这里有一个细节要注意,在代码中遍历列表是从后向前循环,这样在列表中移除当前

// 位置的监听器,不会影响列表中未遍历到的监听器位置,如果是从前向后遍历,那么当从

// 列表中移除一个监听器时,后面的监听器会自动向前移动一个位置,会导致下一轮循环

// 时跳过一个元素。

cb = cbs[i];

if(cb === fn || cb.fn === fn){

cbs.splice(i,1);

break;

}

}

}

return vm;

}

HTTP

  • HTTP 报文结构是怎样的?

  • HTTP有哪些请求方法?

  • GET 和 POST 有什么区别?

  • 如何理解 URI?

  • 如何理解 HTTP 状态码?

  • 简要概括一下 HTTP 的特点?HTTP 有哪些缺点?

  • 对 Accept 系列字段了解多少?

  • 对于定长和不定长的数据,HTTP 是怎么传输的?

  • HTTP 如何处理大文件的传输?

  • HTTP 中如何处理表单数据的提交?

  • HTTP1.1 如何解决 HTTP 的队头阻塞问题?

  • 对 Cookie 了解多少?

  • 如何理解 HTTP 代理?

  • 如何理解 HTTP 缓存及缓存代理?

  • 为什么产生代理缓存?

  • 源服务器的缓存控制

  • 客户端的缓存控制

  • 什么是跨域?浏览器如何拦截响应?如何解决?

    开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值