前端面试题js+vue(2024年2月总结)

2 篇文章 0 订阅

大部分来源于互联网,本人仅做了总结!!!

js、H5、css部分

css部分

less特点:1. 变量 2. 混合(Mixins) 3. 嵌套规则 4. 运算 5. 函数 6. 命名空间 7. 作用域 8. 注释 9. 导入(Import)

数据类型

1,介绍js的基本数据类型。    

Undefined、Null、Boolean、Number、String

2,类型判断用到哪些方法?

typeof

typeof xxx得到的值有以下几种类型:undefined boolean number string object function、symbol ,比较简单,不再一一演示了。这里需要注意的有三点:

* typeof null结果是object ,实际这是typeof的一个bug,null是原始值,非引用类型

* typeof [1, 2]结果是object,结果中没有array这一项,引用类型除了function其他的全部都是object

* typeof Symbol() 用typeof获取symbol类型的值得到的是symbol,这是 ES6 新增的知识点

instanceof

用于实例和构造函数的对应。例如判断一个变量是否是数组,使用typeof无法判断,但可以使用[1, 2] instanceof Array来判断。因为,[1, 2]是数组,它的构造函数就是Array。同理:

function Foo(name) {

   this.name = name

}

var foo = new Foo('bar’)

console.log(foo instanceof Foo) // true

3,JavaScript有几种类型的值?,你能画一下他们的内存图吗?

栈:原始数据类型(Undefined,Null,Boolean,Number、String)

堆:引用数据类型(对象、数组和函数)

两种类型的区别是:存储位置不同;

(1)原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;

(2)引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体

在参数传递方式上,原始类型是按值传递,引用类型是按共享传递

JS 中这种设计的原因是:按值传递的类型,复制一份存入栈内存,这类类型一般不占用太多内存,而且按值传递保证了其访问速度。按共享传递的类型,是复制其引用,而不是整个复制其值(C 语言中的指针),保证过大的对象等不会因为不停复制内容而造成内存的浪费。

4,介绍js有哪些内置对象?    

Object 是 JavaScript 中所有对象的父对象  

数据封装类对象:Object、Array、Boolean、Number 和 String    

其他对象:Function、Arguments、Math、Date、RegEx、Error

5,如何区分数组和对象?    

1、从原型入手,Array.prototype.isPrototypeOf(obj);  利用isPrototypeOf()方法,判定Array是不是在obj的原型链中,如果是,则返回true,否则false。Array.prototype.isPrototype([]) //true

2、也可以从构造函数入手,利用对向的constructor属性

3、根据对象的class属性(类属性),跨原型链调用toString()方法。Object.prototype.toString.call(Window);

4、Array.isArray()方法。

6,null,undefined 的区别?

console.log(null==undefined);    //true  因为两者都默认转换成了false
console.log(typeof undefined);    //"undefined"  
console.log(typeof null);       //"object"  
console.log(null===undefined);    //false   "==="表示绝对相等,null和undefined类型是不一样的,所以输出“false”

null表示没有对象,即该处不应该有值

1) 作为函数的参数,表示该函数的参数不是对象

2) 作为对象原型链的终点

undefined表示缺少值,即此处应该有值,但没有定义

1)定义了形参,没有传实参,显示undefined

2)对象属性名不存在时,显示undefined

3)函数没有写返回值,即没有写return,拿到的是undefined

4)写了return,但没有赋值,拿到的是undefined

null和undefined转换成number数据类型

null 默认转成 0

undefined 默认转成 NaN

数组和对象有哪些原生方法,列举一下?

 数组的常用方法:

方法

说明

slice() 数组对象.slice(start,end)

获取数组中的某段数组元素

unshift() 数组对象.unshift(新元素1,新元素2,…,新元素n);

在数组开头添加元素

push() 数组对象.push(新元素1,新元素2,…,新元素n);

在数组末尾添加元素

shift() 数组对象.shift();

删除数组中第一个元素

pop() 数组对象.pop();

删除数组最后一个元素

toString() 数组对象.toString()

将数组转换为字符串

join() 数组对象.join("分隔符")

将数组元素连接成字符串

concat() 数组1.concat(数组2,数组3,…,数组n)

多个数组连接为字符串concat,就是“合并”的意思。

sort() 数组对象.sort(函数名)

数组元素正向排序

reverse() 数组对象.reverse();

数组元素反向排序

 对象的常用方法

obj.assign(),

字符串有哪些原生方法,列举一下?

charAt()    返回在指定位置的字符。
charCodeAt()    返回在指定的位置的字符的 Unicode 编码。
concat()    连接字符串。
indexOf()    检索字符串。
match()    找到一个或多个正则表达式的匹配。
replace()    替换与正则表达式匹配的子串。
search()    检索与正则表达式相匹配的值。
slice()    提取字符串的片断,并在新的字符串中返回被提取的部分。
split()    把字符串分割为字符串数组。
toLocaleLowerCase()    把字符串转换为小写。
toLocaleUpperCase()    把字符串转换为大写。
toLowerCase()    把字符串转换为小写。
toUpperCase()    把字符串转换为大写。
substr()    从起始索引号提取字符串中指定数目的字符。
substring()    提取字符串中两个指定的索引号之间的字符。
 

 null和undefined的区别

null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。

== 和 === 的区别 

 1.===:三个等号我们称为等同符,当等号两边的值为相同类型的时候,直接比较等号两边的值,值相同则返回true,若等号两边的值类型不同时直接返回false。

     例:

100===“100”   //返回false
abc===“abc”   //返回false
 ‘abc’===“abc”  //返回true
NaN===NaN   //返回false
 false===false  //返回true

2.==:两个等号我们称为等值符,当等号两边的值为相同类型时比较值是否相同,类型不同时会发生类型的自动转换,转换为相同的类型后再作比较。
类型转换规则:

1)如果等号两边是boolean、string、number三者中任意两者进行比较时,优先转换为数字进行比较。
 2)如果等号两边出现了null或undefined,null和undefined除了和自己相等,就彼此相等
     例:

 100==“100”    //返回true
 1==true          //返回true
“1”==“01”      //返回false,此处等号两边值得类型相同,不要再转换类型了!!
 NaN==NaN  //返回false,NaN和所有值包括自己都不相等。

关于变量和常量

let

let 用来声明变量,类似于变量,但是所声明的变量,只在let命令所在的代码块内有效

需要注意的地方:

1.不存在变量提升,未声明直接报错

2.暂时性死区

3.for循环具有两个作用域,外面的变量和里面的变量互不干扰

const

用来声明一个只读的常量,一旦尚明,常量的值就不可以改变了,而且声明的时候必须赋值

js垃圾回收:

1.什么是垃圾

一般来说没有被引用的对象就是垃圾,就是要被清除, 有个例外如果几个对象引用形成一个环,互相引用,但根访问不到它们,这几个对象也是垃圾,也要被清除。

2.如何检垃圾

一种算法是标记 标记-清除 算法,还想说出不同的算法可以参考这里

更深入一些的讲解 http://newhtml.net/v8-garbage...

需要注意的地方:

引用类型储存的是一个地址,所以用const声明的引用数据类型,只要不改变指针地址,就可以

如果为常量赋其他的值,就会报错。

数组的深拷贝

const a1 = [1,2];

1.const a2 = [...a1];

2.const [...a2] = a1;

关于本地存储和会话存储

常用浏览器存储方案有,cookie,session,localstorage,sessionstroage,区别在于:

1.方式: cookie通过请求头发送,在浏览器与服务器之间来回传递,sessionStroage与   localStroage不会把数据发给服务器,仅在本地保存

2.存储量​:cookie存储量小,一般在4到8kb,其余存储量大5M

3.数据有效期不同,

     sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保存

     localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据

     cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。

4.作用域​

     sessionStorage不能在不同的浏览器窗口中共享,即使是同一个页面;

     localStorage 在所有同源窗口中都是共享的

     cookie也是在所有同源窗口中都是共享的。

关于异步处理:Generator   async   promise  的区别

详细理解:promise、generator、async的简单应用 - 简书

移动端适配的技术方案:

(1)通过媒体查询的方式即CSS3的meida queries

(2)以天猫首页为代表的 flex 弹性布局

(3)以淘宝首页为代表的 rem+viewport缩放 (推荐)

(4)rem 方式(推荐)

详细参考:移动端前端适配方案(总结) -- 面试重点_移动端适配-CSDN博客

ES6常用特性

变量定义(let和const,可变与不可变,const定义对象的特殊情况)

解构赋值

模板字符串

数组新API(例:Array.from(),entries(),values(),keys())

箭头函数(rest参数,扩展运算符,::绑定this)

特点:箭头函数中的this始终指向箭头函数定义时的离this最近的一个函数,如果没有最近的函数就指向window。

1不能作为构造函数,不能使用new

2不能使用argumetns,取而代之用rest参数...解决

3不绑定this,会捕获其定义时所在的this指向作为自己的this。由于在vue中自动绑定 this 上下文到实例中,因此不能使用箭头函数来定义一个周期方法。箭头函数的this永远指向上下文的this,call、apply、bind也无法改变

4箭头函数没有原型对象

箭头函数其实只是一个匿名函数的语法糖,区别在于普通函数作用域中的this有特定的指向,一般指向window,而箭头函数中的this只有一个指向那就是指当前函数所在的对象,其实现原理其实就是类似于之前编程的时候在函数外围定义that一样,用了箭头函数就不用定义that了直接使用this

参考:箭头函数和普通函数的区别 - 简书

Set和Map数据结构(set实例成员值唯一存储key值,map实例存储键值对(key-value))

(1) Set 类似于数组,但数组可以允许元素重复,Set 不允许元素重复 


(2)Map 类似于对象,但普通对象的 key 必须是字符串或者数字,而 Map 的 key 可以是任何数据类型 


Promise对象(前端异步解决方案进化史,generator函数,async函数)

Class语法糖(super关键字)

总结前端性能优化的解决方案

javascript - 前端性能优化 24 条建议(2020) - 个人文章 - SegmentFault 思否

Ajax原理

(1)创建对象

var xhr = new XMLHttpRequest();

(2)打开请求

xhr.open('GET', 'example.txt', true);

(3)发送请求

xhr.send(); 发送请求到服务器

(4)接收响应

xhr.onreadystatechange =function(){}

(1)当readystate值从一个值变为另一个值时,都会触发readystatechange事件。

(2)当readystate==4时,表示已经接收到全部响应数据。

(3)当status ==200时,表示服务器成功返回页面和数据。

(4)如果(2)和(3)内容同时满足,则可以通过xhr.responseText,获得服务器返回的内容。

浅拷贝和深拷贝

jQuery.extend第一个参数可以是布尔值,用来设置是否深度拷贝的

jQuery.extend(true, { a : { a : "a" } }, { a : { b : "b" } } );
jQuery.extend( { a : { a : "a" } }, { a : { b : "b" } } ); 

最简单的深拷贝

aa = JSON.parse( JSON.stringify(a) )

浅复制--->就是将一个对象的内存地址的“”编号“”复制给另一个对象。深复制--->实现原理,先新建一个空对象,内存中新开辟一块地址,把被复制对象的所有可枚举的(注意可枚举的对象)属性方法一一复制过来,注意要用递归来复制子对象里面的所有属性和方法,直到子子.....属性为基本数据类型。总结,深复制理解两点,1,新开辟内存地址,2,递归来刨根复制。

事件冒泡和事件捕捉 JS的事件冒泡和事件捕获-CSDN博客

闭包   Javascript闭包——懂不懂由你,反正我是懂了_js闭包反正我懂了-CSDN博客

div上下左右居中

position: absolute;
margin: auto;
top: 0; left: 0; bottom: 0; right: 0;

参考:css 上下左右居中(9种)_上下左右居中 css-CSDN博客

js面试题扩展:2019JS必看面试题 - 简书

js设计模式:

https://www.cnblogs.com/imwtr/p/9451129.html

HTTP协议:

https://www.cnblogs.com/123blog/articles/10297650.html

vue部分

重中之重、Vue的双向数据绑定原理是什么?

实现数据绑定的做法有大致如下几种:

  • 发布者-订阅者模式(backbone.js)
  • 脏值检查(angular.js)
  • 数据劫持(vue.js)

答:vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

这里写图片描述
具体步骤:

已经了解到vue是通过数据劫持的方式来做数据绑定的,其中最核心的方法便是通过Object.defineProperty()来实现对属性的劫持,达到监听数据变动的目的。 
要实现mvvm的双向绑定,就必须要实现以下几点: 
1、实现一个数据监听器Observer,遍历data中的属性,使用 Object.defineProperty 的get/set方法对其进行数据劫持,达到监听数据变动的目的,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数 
3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图 
4、mvvm入口函数,整合以上三者

详细理解:vue双向绑定原理及实现 - 简书

provide/inject的学习

vue.js - vue中的provide/inject的学习 - 流年的樱花逝 - SegmentFault 思否

一、什么是MVVM?
MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

二、mvvm和mvc区别?它和其它框架(jquery)的区别是什么?哪些场景适合?
mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
区别:vue数据驱动,通过数据来显示视图层而不是节点操作。
场景:数据操作比较多的场景,更加便捷

三、vue的优点是什么?
低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

四、 组件之间的传值?(重点)

1.父组件与子组件传值
父组件传给子组件:子组件通过props方法接受数据;
子组件传给父组件:$emit方法传递参数
2.非父子组件间的数据传递,兄弟组件传值
eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。)

父子组件互相调用方法

父组件中定义好了方法 hello(),在子组件中直接用:this.$parent.hello();

父组件调用子组件的方法:this.$refs.pass.fn1;

vue-router基本原理:(重点)

vue-router通过hashHistory interface两种方式实现前端路由,更新视图但不重新请求页面。

主要有两种方式:

1、hash ---- 利用URL中的hash(“#”)

2、利用History interface在 HTML5中新增的方法,

详细理解:浅谈vue-router原理 - 简书

七、vue如何实现按需加载配合webpack设置
webpack中提供了require.ensure()来实现按需加载。以前引入路由是通过import 这样的方式引入,改为const定义的方式进行引入。
不进行页面按需加载引入方式:import home from '../../common/home.vue'
进行页面按需加载的引入方式:
const home = r => require.ensure( [], () => r (require('../../common/home.vue')))

八、vuex面试相关(重点)
(1)vuex是什么?怎么使用?哪种功能场景使用它?
vue框架中状态管理。在main.js引入store,注入。新建一个目录store,…… export 。场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车
(2)vuex有哪几种属性?

工作原理:

通过官方文档提供的流程图我们知道,vuex的工作流程,

1、数据从state中渲染到页面;

2、在页面通过dispatch来触发action

3、action通过调用commit,来触发mutation

4、mutation来更改数据,数据变更之后会触发dep对象的notify,通知所有Watcher对象去修改对应视图(vue的双向数据绑定原理)。


(3)不用Vuex会带来什么问题?
可维护性会下降,想修改数据要维护三个地方;
可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的;
增加耦合,大量的上传派发,会让耦合性大大增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。

详细理解:https://www.jianshu.com/p/1fdf9518cbdf

九、 v-show和v-if指令的共同点和不同点
v-show指令是通过修改元素的display的CSS属性让其显示或者隐藏
v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果

十二、Vue中引入组件的步骤?
1)采用ES6的import … from …语法或CommonJS的require()方法引入组件
2)对组件进行注册,代码如下

十三、如何让CSS只在当前组件中起作用?

将当前组件的<style>修改为<style scoped>

十四、在Vue中使用插件的步骤
采用ES6的import … from …语法或CommonJSd的require()方法引入插件
使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })

十五、请列举出3个Vue中常用的生命周期钩子函数
created: 实例已经创建完成之后调用,在这一步,实例已经完成数据观测, 属性和方法的运算, watch/event事件回调. 然而, 挂载阶段还没有开始, el属性目前还不可见mounted:el被新创建的vm. el属性目前还不可见mounted : el被新创建的 vm.el属性目前还不可见mounted:el被新创建的vm.el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
activated: keep-alive组件激活时调用

十六、active-class是哪个组件的属性?
vue-router模块的router-link组件。

十九、生命周期相关面试题
总共分为8个阶段:

beforeCreate(创建前) 在数据观测和初始化事件还未开始
created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

(1)、什么是vue生命周期
答: Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

(2)、vue生命周期的作用是什么
答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

(3)、vue生命周期总共有几个阶段
答:可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后

(4)、第一次页面加载会触发哪几个钩子
答:第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

(5)、DOM 渲染在 哪个周期中就已经完成
答:DOM 渲染在 mounted 中就已经完成了。

(6)、简单描述每个周期具体适合哪些场景
答:生命周期钩子的一些使用方法:
beforecreate : 可以在这加个loading事件,在加载实例时触发
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
mounted : 挂载元素,获取到DOM节点
updated : 如果对数据统一处理,在这里写上相应函数
beforeDestroy : 可以做一个确认停止事件的确认框
nextTick : 等到整个视图都渲染完毕,才会执行 vm.$nextTick 

mounted: function () {
this.$nextTick(function () {

// Code that will run only after the
// entire view has been rendered
})
}

详细原理请看:https://www.jianshu.com/p/69d447321740

二十、说出至少4种vue当中的指令和它的用法?
v-if:判断是否隐藏;v-for:数据循环;v-bind:class:绑定一个属性;v-model:实现双向绑定

二十二、scss是什么?在vue.cli中的安装使用步骤是?有哪几大特性?
答:css的预编译。
使用步骤:
第一步:先装css-loader、node-loader、sass-loader等加载器模块
第二步:在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展.scss
第三步:在同一个文件,配置一个module属性
第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”
特性:
可以用变量,例如($变量名称=值);
可以用混合器,例如()
可以嵌套

二十四、为什么避免 v-if 和 v-for 用在一起
当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,通过v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运算 v-for。

vue中修改了数据但视图无法更新的情况

参考:vue中修改了数据但视图无法更新的情况_vue3更改数组的属性,视图不刷新怎么解决?-CSDN博客

从项目加载时以及运行时两方面进行优化?

如何进行加载时的优化?

1.CSS 写头部,JavaScript 写底部

2.使用服务器端渲染

3.减少HTTP请求

4.静态文件使用CDN

5.字体图标代替图片图标

6.利用缓存不重复加载相同的资源

7.图片优化

8.通过 webpack 按需加载代码

那如何进行运行时的优化?

1.减少重绘重排,使用class 来改变样式

2.使用事件委托

3.不要覆盖原生方法

4.降低CSS 选择器的复杂度

5.使用 flexbox 布局

6.用 transform 和 opacity 属性实现动画

7.防抖和节流

从输入URL到页面加载的全过程

1.在浏览器中输入一个url

2.根据域名解析出ip地址(dns的过程)

(1)先检查浏览器缓存,如果有,返回,没有,下一步

(2)检查系统缓存,hosts文件

(3)检查网络中路由器的dns缓存

(4)递归查询,不优先查找浏览器所在的本地域名服务器,先查找其他域名服务器,看有没有,如果没有,再查找本地域名服务器,本地域名服务器用迭代查询来查找

(5)迭代查询,不断向上访问,查找

3.根据找到的ip地址建立tcp连接

三次握手
4.发送http请求,get请求

5.如果发生重定向,状态码是3开头,那么返回第一步,继续匹配重定向的服务器

6.向重定向的服务器发送http请求

7.服务器处理请求,并且服务器发送html响应

8.tcp断开连接

9.根据响应,得到html,渲染出界面

10.其他内容,如图片url,返回第一步重新请求,如果请求过,就从浏览器缓存中得到

vue2和vue3的区别有哪些

盘点 Vue3 与 Vue2 的区别 - 掘金 (juejin.cn)

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值