美文网首页JavaScript
前端面试题收集

前端面试题收集

作者: h2coder | 来源:发表于2023-08-23 10:23 被阅读0次

    HTML和CSS

    H5的新特性

    • 语义化标签
      • header,头部标签
      • footer,尾部标签
      • article,文章主体标签
      • section,内容块
      • nav,导航栏
      • aside,侧边栏
    • 媒体标签
      • audio,音频标签
      • video,视频标签
    • 地理定位API
    • WebStorage
      • localStorage,本地存储,相比cookie,大很多
      • sessionStorage,会话存储
    • WebSocket,全双工协议,一般用于作为即时通信
    • Canvas绘图

    CSS3新增的特性

    • 弹性布局Flex
    • 媒体查询
    • 结构伪类选择器
      • first-child
      • last-child
      • nth-child(n)
    • 伪元素选择器
      • 元素::before
      • 元素::after

    盒子、图片水平、垂直居中

    • 使用Flex布局,justify-contentalign-center都设置为center
    • 使用子绝父相,子元素绝对定位,父元素相对定位,子元素top:50%left:50%,让子盒子向右、向下移动父盒子宽高的一半,再通过transform-translate(-50%, -50%),向左、向上移动自身的一半

    CSS盒模型

    • 默认CSS盒模型,box-sizing的值是content-box,元素的宽高只是指内容的宽度、高度
    • 怪异盒模型,也叫IE盒模型,box-sizing的值是border-box,元素的宽高,除了包含内容的宽高,还包含内边距和边框

    块级元素和行内元素的特点和区别

    • 块级元素
      • 独占一行
      • 可以设置宽高
      • 可以设置内、外边距和边框
    • 行内元素
      • 一行显示多个
      • 宽高由内容撑开
      • 只能设置内边距、边框,设置外边距无效

    CSS选择器权重值

    • !important > 行内样式 > id选择器 > 类选择器 > 标签选择器 > 通配符选择器

    H5的事件有哪些?

    • input标签
      • input,输入改变事件
      • focus,获取焦点事件
      • blur,失去焦点事件
      • keydown,键盘按键按下事件
      • keyup,键盘按键弹起事件
    • mouseover,鼠标移入事件(mouseover支持冒泡,mouseenter不支持冒泡)
    • mousemove,鼠标移动事件
    • mouseout,鼠标移出事件

    H5的input标签的type值有哪些?

    • text,文本框
    • password,密码框
    • radio,单选框
    • checkbox,复选框
    • button,按钮
    • submit,提交按钮
    • date,日期选择
    • color,颜色选择

    JavaScript

    JS数据类型

    • 基础数据类型
      • 字符串 String
      • 数字 Number
      • 布尔 Boolean
      • undefined 未定义的值
      • null 空值
      • Symbol 标识,Symbol对象永远不相等,创建时传入的名称字符串,只是用来在debugger时用来区分,应用场景是给对象设置独一无二的属性,避免属性被覆盖和把原有属性覆盖
      • BigInt 大整数,拥有比Number类型更大的数值范围
    • 引用数据类型
      • 对象 Object(包含:函数 Function、数组 Array)

    回流和重绘

    • 回流:元素的大小、布局发生改变时,浏览器需要进行回流进行调整布局
    • 重绘:元素的颜色、字体等其他外观属性发生改变,浏览器需要进行重绘来更新外观
    • 回流和重绘都有一定的开销,因此应该要避免不必要的回流和重绘,可以通过优化后的CSS选择器,来减少回流的次数。或者使用缓存来避免重复的重绘
    • 可以使用requestAnimationFrame()函数来在浏览器的下一次重绘之前回调,实现特定的业务逻辑,例如可以在更新页面元素的外观时,将多个操作合并为一次重绘,减少重绘的次数

    原型和原型链

    • 每个构造函数都有一个prototype属性,指向一个原型对象,原型对象中,一般存放该构造函数的共享方法
    • 每个对象上,都有一个__proto__属性,指向了构造器的原型对象
    • 原型链,对象的成员查找提供的一种机制。当访问一个对象的某个成员时,优先查找对象本身,如果没有则查找该对象的的原型对象(也就是proto属性指向的原型对象),如果也没有找到,则查找原型对象的原型对象,依次类推,直到找到Object为止,也就是为null,就会报错

    this指向的问题

    • 在全局中调用函数,this指向window
    • 对象内的this,this指向对象本身
    • 在构造函数中的this,this指向该构造函数准备要构造出来的实例
    • 在事件回调函数中,this为触发该事件的DOM元素
    • 箭头函数中的this,箭头函数没有this,沿用它上一级的作用域的this
    • 可以通过call、apply、bind,改变this的指向

    forEach和map的区别

    • 作用不同:forEach是遍历数组,map是映射数组
    • 返回值不同:forEach没有返回值,map有返回值,返回的是映射后的新数组
    • 处理流程不同:forEach是按顺序遍历每个元素,并执行回调函数。map是除了按顺序遍历元素,执行回调函数外,还会把回调函数的返回值存到一个新数组中,并返回

    call、bind、apply的区别

    • call、bind、apply都可以改变函数的this指向
    • call和apply,都是改变this指向后,马上调用原函数,区别是函数的参数,call是一个接一个的传入,而apply是将参数放到数组中再传入函数
    • bind是改变完this后,不会立即调用函数,而是返回一个新函数,我们在调用新函数,参数也是一个接一个的传入

    浅拷贝和深拷贝

    • 浅拷贝,拷贝基础数据类型是值拷贝,而拷贝引用数据类型时,拷贝的是对象的内存地址,堆内存中依旧只有一个对象,所以原对象和克隆对象的引用类型属性,指向的是同一个内存地址的对象,修改其中一方会互相影响
    • 深拷贝,让引用类型数据的拷贝是完全的复制,在堆内存中是2个对象,修改其中一方不会互相影响
    • 浅拷贝,基础数据类型和引用数据类型,都可以使用...展开运算符来浅拷贝。引用数据,对象可以使用Object.assign(),数组可以使用Array.prototype.concat()
    • 深拷贝,可以使用JSON序列化和反序列化来实现,但会丢失掉undefind、Function类型的属性,并且不能处理环形结构的数据
    • 工作中,一般使用第三方库lodash,该库提供了浅拷贝、深拷贝的方法,并且能支持undefind、Function属性,环形结构的数据

    防抖和节流

    • 防抖和节流是常见性能优化手段,可以控制函数的执行频率
    • 防抖是一定时间内,只执行最后一次事件,一般使用延时器实现,每次调用都清除掉上一次的延时器,所以只有当用户停止操作,一定时间后才会执行,例如DOM元素点击事件、输入框自动联想搜索
    • 节流是单位事件内,控制事件以一定频率触发,一般使用延时器实现,控制事件在一个时间范围内,只触发一次,例如在处理窗口大小变化事件、页面滚动事件、音、视频的进度改变事件等时,需要频繁发送请求、读写localStorage

    ES6新特性

    • let和const,let拥有块级作用域,不存在变量提升,const是常量,赋值了就不能改变
    • 箭头函数,简化函数声明,箭头函数没有this,沿用上一级作用域的this
    • 模板字符串,比字符串拼接更简洁、更直观
    • 解构赋值,数组解构、对象解构
    • 剩余参数
    • 函数形参默认值
    • 类,引入类的改变,更加容易维护

    ES6新增方法

    • 数组
      • find(),查找元素
      • findIndex(),查找元素的下标
      • includes,判断元素是否包含
      • sort,排序
    • 对象
      • Object.keys(),获取对象的所有属性名
      • Object.values(),获取对象的所有属性值
      • Object.assign(),对象浅拷贝

    点击穿透现象以及解决方法

    • 点击穿透,指的是点击上层元素,下层元素也响应事件
    • 防止点击穿透:监听点击事件,在回调函数中,阻止默认点击行为
      • event.stopPropagation();
      • event.preventDefault();

    如何理解Promise

    • 一套异步编程的解决方案
    • 将异步操作的结果,封装为成功(fulfilled)、失败(rejected)和等待(pending),并且状态一经更改,就不可逆,如网络请求、读取文件
    • 解决回调函数嵌套地狱问题,提供链式编程来解决回调地狱的问题
    • Promise上有3个静态方法,Promise.all()、Promise.allSettled()、Promise.race()、Promise.any()
      • Promise.all(),需要传入一个数组,存放多个Promise,组合多个Promise为一个Promise,全部Promise都成功,才算成功,但有一个Promise失败,就当全部失败(请求商品三级分类,获取到商品一级分类后,并发请求所有二级分类)
      • Promise.allSettled(),也是传入多个Promise,组合为一个Promise,所有Promise都执行完毕,不管成功还是失败,才会进行回调(多个异步请求,都结束后,关闭Loading圈)
      • Promise.race(),赛跑机制,也是传入多个Promise,组合为一个Promise,但只要第一个Promise成功,就为成功,其他Promise的结果就不管了(并发请求缓存和发出请求,谁先获取到,就用谁的)
      • Promise.any(),同样将多个Promise包装为一个Promise,只要有一个Promise成功,就为成功,全部Promise失败时,才算失败

    async和await的理解

    • async和await是Promise的语法糖,async用于修饰方法,代表是异步方法,await是阻塞等待Promise的成功结果,如果失败会抛出异常,要使用try-catch进行捕获处理
    • async和await,将异步代码写法转变回同步写法,相比Promise更加直观

    sessionStorage和localStorage的区别

    • sessionStorage和localStorage都是用来存储数据到本地,存储大小大概有5M左右,而Cookie只能存储4k的大小
    • sessionStorage在浏览器关闭后,自动清除。而localStorage是永久持久化,除非用户手动删除
    • localStorage的存储容量,一般比sessionStorage大,不同浏览器可能有差异

    rem和em的区别

    • rem和em都是字体大小的单位,但计算方式不同
    • rem是相对于html根标签的font-size字体大小的比例计算
    • em是相对于父元素的字体大小的计算

    响应式布局

    • 响应式布局,根据用户的设备,手机、平板、PC等不同尺寸的设备,进行自适应,都能有良好的显示效果
    • 常见的响应式布局方式
      • 使用流式布局,用百分比设置元素的宽高,让元素在不同尺寸的设备上自动调整大小
      • 使用媒体查询,定义不同尺寸下元素的尺寸和样式,动态应用不同的样式
      • 使用Flex布局,让元素在一个容器中按照一定的规则进行布局

    视频控件

    • 视频控件,通常使用HTML5的video标签
    • 使用时,需要指定视频的地址、视频的宽高、是否自动播放
    • 可以控制播放、暂停、快进、快退

    什么是同源?

    • 协议、域名(IP)、端口号,3者都完全相同,才为同源
    • 3者有一部分不一样,都为不同源
    • 不同源时,发送ajax请求,产生跨域,请求会被浏览器拦截

    为什么会跨域?

    • 是浏览器的一种同源安全手段
      • 浏览器要求网页地址和请求地址,3部分都必须相同,否则就会产生跨域
      • 协议相同,例如http、https
      • 主机相同,域名、IP地址
      • 端口号相同
    • 以下3个标签,不受到跨域限制
      • img标签
      • link标签
      • script标签

    跨域怎么处理?

    • 使用代理服务,在本地搭建一个代理服务器,如Nginx,它负责转发请求,解决跨域问题
    • 使用JSONP,通过动态插入script标签的方式事件跨域访问,只支持GET请求,是一种很老的方式
    • 通过服务端配置CROS,CROS是一种跨域资源共享方式,服务端配置HTTP头信息,让浏览器允许跨域

    ES6中的var、let、const的区别

    • var,在ES6之前使用,存在变量提升、没有块级作用域等问题
    • let,用于替代var,没有变量提升,有块级作用域
    • const,用于定义常量,赋值后就不能修改

    怎么改变this指向

    • 通过call、apply、bind来改变函数的this指向
    • 如果想沿用上一级的this,可以使用箭头函数,或者在函数调用前先用一个变量that保存this

    for of 和 for in 的区别

    • for-of,遍历数组的值
    • for-in,遍历对象的属性名

    什么是同步和异步

    • JavaScript是单线程语言,同一时间只能执行一个任务,如果同步执行一个耗时任务,会阻塞执行,导致界面卡顿
    • 因此出现了异步编程,通过将耗时任务交给浏览器或操作系统去执行,任务结果通过回调函数或事件机制,回调通知或事件,通知主线程,不会阻塞执行

    宏任务和微任务

    • 宏任务和微任务,都用于处理耗时任务,有单独的任务队列来存放任务
    • 宏任务,例如交互事件、定时器、延时器、script标签的解析
    • 微任务,Promise.then()
    • 优先级:当队列,存在宏任务和微任务时,优先执行完微任务,再执行宏任务
    • 执行流程,JS解析器运行时,遇到同步代码,直接交给执行栈直接执行,如果遇到宏任务,则放入到宏任务队列,遇到微任务则放入到微任务队列。当执行完执行栈中的同步任务后,就会去微任务瞄一眼,如果有微任务则将微任务挪到执行栈,在执行栈中执行微任务,执行完所有的微任务,则再去宏任务队列瞄一眼。如有宏任务,则将宏任务挪到执行栈,执行宏任务。执行完一个宏任务后,又会去微任务瞄一眼,发现有微任务就执行。(总之,微任务的优先级比宏任务高,执行完一次宏任务都要去将微任务队列中,执行完所有的微任务,再执行下一个宏任务,这样设计,就让微任务有了插队的可能)这种不断往复的执行的流程,就是事件循环EventLooper

    什么是闭包

    • 闭包,具体表现形式:外层函数嵌套内层函数,内层函数使用外层函数的变量,外层函数返回内层函数
    • 作用:保护私有数据,防止全局变量污染
    • 问题:闭包会导致内存泄漏,需要手动将返回的内层函数的引用设置为null,置空引用,来防止内存泄漏

    介绍一下作用域

    • 全局作用域,在全局作用域下声明的变量和函数,在任何位置都能访问
    • 局部作用域,在函数内或块级作用域中可访问,出了函数作用域或块级作用域就访问不到了

    深拷贝,为什么能做到拷贝后互不影响

    • 因为深拷贝是将引用数据类型的属性,进行完整拷贝,而不是值的拷贝,也就是不是拷贝对象内存地址,是在堆内存中真的创建了一个新的对象

    说一下事件委托的应用场景

    • 事件委托的原理是事件冒泡,如果没有事件冒泡,就无法实现事件委托
    • 事件委托一般用于给动态生成的元素,绑定事件,例如列表或表格的列表项、表格项,绑定点击事件
    • 给父元素绑定一个事件处理函数,不需要给所有子元素绑定,能节省内存,提高性能

    什么是纯函数

    • 纯函数,只依赖传入的形参,不依赖函数外部的变量,传入相同的形参,总能得到相同的结果
    • 纯函数没有副作用
    • 如果传入相同的形参,得到不同的结果,那么就不是纯函数

    数组去重

    • Array.from() + new Set()
    • 拓展运算符 + 新数组 + new Set()
    • for循环 + indexOf() + 新数组push()
    • forEach循环 + indexOf() + 新数组push()
    • forEash循环 + includes() + 新数组push()

    什么是递归

    • 函数调用自身,就叫递归
    • 必须有终止条件,否则死循环会栈溢出

    封装axios的步骤

    • 创建一个request.js,引入axios
    • 使用axios.create()创建axios的实例,配置基地址和超时时间
    • 配置请求拦截器和响应拦截器,然后默认导出
    • 一般在请求拦截器中,添加token到请求头
    • 一般在响应拦截器中,判断服务端返回的状态码,例如判断登录状态失效,就跳转到登录页,或者解构固定的服务端响应解构数据,result.data.data

    JS怎么判断数据的类型

    • 使用typeof,只适用于基础数据类型
      • 基础数据类型,判断不了null,判断null会返回object
      • 判断NaN,判断的是number
      • 引用数据类型,只能判断Function,数组和其他都返回object
    • 使用instanceof,只能用于判断引用数据类型,不能判断基础数据类型
    • 使用Object.prototype.toString.call(),该方式兼容性最好,既能判断基础数据类型,也能判断引用数据类型

    图片懒加载的底层原理

    • img标签的src属性,设置为空字符串,将真实的图片地址放在一个自定义属性,例如data-origin中
    • 监听页面滚动事件,判断img标签是否可见,可见再把自定义属性中的值,设置到src属性中

    Git

    Git的常用命令

    • git add,添加到暂存区
    • git commit,提交代码到版本库
    • git push ,推送代码到远程仓库
    • git pull,拉取代码
    • git clone,克隆代码
    • git checkout,签出代码
    • git checkout -b,签出或创建新分支
    • git merge,合并分支

    Webpack

    Webpack的版本号

    • 2018,webpack4,可零配置运行,打包(构建)速度提高80%
    • 2020,webpack5,打包速度更快,开启文件缓存,明显提升打包速度

    HTTP协议

    HTTP有了解过吗?

    • HTTP协议,基于TCP\IP,是基于请求、响应模型,一个无状态的协议
    • HTTP协议,请求报文分为请求行、请求头、请求体。响应分为响应行(状态行)、响应头、响应体
    • HTTP协议可传输超文本HTML,也可以传输XML、JSON,目前常用是JSON
    • 常用请求方式:GET获取、POST提交、PUT更新、DELETE删除
    • 常见状态码:200成功,304读取缓存、401没有登录、403权限不足、500服务器内部错误

    HTTP不写端口时,默认是多少

    • HTTP默认端口为80
    • HTTP默认端口为443

    HTTP有哪些请求方法

    • GET 获取
    • POST 提交
    • PUT 更新
    • DELETE 删除

    HTTP常用状态码

    • 200成功
    • 304读取缓存
    • 401没有登录
    • 403权限不足
    • 500服务器内部错误

    HTTP的三次握手过程

    HTTP的四次挥手过程

    说一下在页面中输入URL到加载完成的过程

    HTTP和HTTPS的区别

    • 2者都是传输协议
    • 安全性:HTTPS在传输数据的基础上,增加了加密,防止数据不被窃取和修改
    • 证书,HTTP要求服务端安装SSL证书,验证服务端的身份,确保用户访问的是真实的网站
    • 端口号:HTTP的默认端口号是80,HTTPS的默认端口是443
    • HTTP协议的URL以http开头,HTTPS协议的URL以https开头

    MVVM

    说一下你对MVVM的理解

    • M是Model模型,是应用程序中的数据和逻辑
    • V是View视图,是用户看见的界面
    • VM是视图模型,数据驱动视图的框架
    • 优点:将视图和业务逻辑分离,以数据驱动视图变化,易维护和拓展

    Vue

    Vue的插槽

    • 默认插槽
      • 组件中只有一个插槽,父组件只能传递一个内容给子组件,其实默认插槽也是具名插槽,只是名字叫default
    • 具名插槽
      • 子组件可以有多个插槽,父组件可以传入多个内容给子组件,子组件需要指定插槽的名字
      • 作用域插槽,在具名插槽的基础上,让子组件传出数据给父组件,例如表格项-按钮组件,点击时,需要将当前项的数据,传出给表格父组件使用,例如删除数据、显示表格项详情等

    Vue的data,为什么一定是要一个函数

    • 因为组件复用时,每个组件都应该有自己的状态,如果data不是一个函数返回的新对象,而是同一个对象,则每个组件都公用一个数据对象,就会导致组件的状态混乱,互相影响

    Vue双向绑定的原理

    • 双向绑定的原理是数据劫持和观察者模式来实现的,大概分为2步:
      • 通过Object.defineProperty来劫持数据,收集依赖
      • 当数据变更时,通知依赖去响应视图的变化
    • 当Vue实例被创建时,会在内部遍历所有数据,并使用Object.defineProperty来对每个属性添加getter和setter。这样,当数据被改变时,Vue就可以捕获数据,并通知观察者,重新渲染页面

    使用Vuex的完整步骤

    • 导入vuex依赖
    • 创建store.js文件,创建vuex实例,并通过Vue.use(),使用Vuex插件,再挂载到Vue实例上
    • 创建module文件夹,配置模块的store.js
    • 配置state、mutations、actions、getters

    v-model的实现原理

    • v-model,其实是一种语法糖,作用是将数据和表单元素进行双向绑定,数据改变时更新视图,表单元素内容更新时,更新数据
    • 数据改变时,更新视图,其实是v-bind
    • 视图内容改变时,更新数据,其实是v-on
    • 例如input标签使用v-model,就是v-bind:value="",v-on:onclick="",也就是:value和@click

    什么是单页面应用

    • 单页面应用,也就是在HTML页面加载所有页面,通过JS切换视图达到切换页面的效果,而不需要像多页面应用需要重新发起请求由服务端进行渲染
    • 单页面应用的性能高,切换页面时,一些通用的头部、尾部等通用样式,不需要重复发出请求来获取,减轻服务端的负载
    • 单页面应用的SEO比较差,因为视图都是通过JS动态渲染的,搜索引擎爬虫无法运行JS脚本,只能抓取HTML里面的标签和文本来决定这个站点的价值。
    • 单页面应用可以通过服务端渲染SSR来解决单页面应用SEO差的问题

    如何解决单页面应用SEO难度大的问题

    • 单页面应用可以通过服务端渲染SSR来解决单页面应用SEO差的问题

    谈谈你对vue的理解

    • Vue,一个渐近式的UI视图框架,理念是使用数据驱动视图,不需要开发者手动操作DOM,让开发者更加关注数据和具体业务

    Vue中如何监听路由信息的改变

    • 通过watch监听器路由对象的变化
    • 使用路由提供的回调钩子函数

    nextTick的理解

    • 当我们修改响应式变量时,并不会马上就根据变量,重新渲染DOM,而是异步更新
    • 因为响应式变量可能在短时间内,频繁修改,如果同步渲染DOM,模板比较复杂时,会导致卡顿,产生性能问题
    • 由于Vue的DOM更新是异步的,我们直接在修改响应式变量后,就直接通过ref操作DOM元素,会发现获取不到,而Vue提供了nextTick函数,该函数会在异步更新DOM完毕后回调,我们在这个回调中再通过ref操作DOM就肯定能获取到DOM元素

    Vue中对象添加新属性,界面不自动刷新,怎么解决

    • 使用Vue实例的$set函数,this.$set(attr, index, val);,主动通知Vue劫持新的属性
    • 使用Vue包装过的数组方法,例如splice,arr.splice(index, 1, value);
    • 使用$fourceUpdate强制刷新
    • 使用中转变量,将新变量赋值原有响应式变量

    v-for中的key

    • key是Vue框架内部使用的,用于Vue框架复用视图时使用,不会对我们业务逻辑产生影响
    • 如果不使用key,会导致Vue无法精确复用视图,例如ul中有多个li,当我们删除第一个li时,Vue会删除最后的一个li,然后将内容网上挪,如果第一个li中有一个背景色,就会发现我们虽然删除了数组的第一个元素,但Vue并不是相应的删除第一个li标签,就会导致视图复用出现问题
    • 而设置了key,让每个li标签都有一个唯一标识,就能让Vue知道我们删除的数组数据对应哪个视图,就能删对li标签了

    说一下Vue组件通讯

    • 父、子组件传参
    • 父传子:props传参
    • 子传父:$emit(),发送自定义事件
    • 子孙通信:provide和inject
    • 跨组件通信:EventBus、Vuex

    说几个Vue的指令

    • v-text,相当于innerText
    • v-html,相当于innerHTML
    • v-if、v-else-if、v-else,相当于if、else if和else,条件渲染
    • v-show,和v-if效果类似,都是显示隐藏某个元素,但v-if是直接将DOM元素直接从DOM树移除,v-show是通过切换元素的CSS-display属性来实现显示隐藏
    • v-bind,动态绑定属性,可以简写为:号
    • :class,动态绑定class,当某个条件为true时,添加指定的class类名给DOM元素,语法::class="{类名: 条件表达式}",或者::class=[类名1, 类名2, 类名3]
    • :style,动态样式,当只想改变DOM元素的某个样式属性,而不想使用类名时使用,语法::style="{color: activeColor, backgroundColor: bgColor}"
    • v-model,视图和数据双向绑定,是:value和@input的合写,要求子组件必须有一个名叫value的属性名,当子组件经过一些UI操作后,内容发生变化后,发出的自定义事件的名称必须叫input
    • sync修饰符,v-model要求子组件只能有一个属性可以进行双向绑定,并且子组件的属性名和发出的事件名都是固定的,不能修改。当子组件有多个属性都可以提供双向绑定时,就可以使用sync修饰符,它可以自定义子组件的属性名和发出的事件名,语法:v-bind:属性名.sync="值",发出的事件的格式:update:属性名="新值"

    Vue的路由懒加载

    • 路由懒加载,可以让组件在路由被访问时,才加载对应的组件,也就是异步组件,避免一进入页面,就直接加载所有的路由组件,解决单页面应用首屏加载慢的问题

    Vuex的核心属性

    • state,状态,也就是数据
    • mutations,同步修改state的函数
    • actions,异步修改state的函数(异步后调用mutation的函数来实现修改)
    • getters,计算state为一个新的state,或者合并多个state,相当于计算属性

    Vue的路由模式

    • hash模式,使用H5的新特性,URL地址#/后路径变化时,浏览器不会发出请求,而是触发hashchange事件,但有#/,URL地址比较难看
    • history模式,浏览器一直都支持的模式,URL路径变化时,浏览器会发出请求,要求服务端返回新的页面,但单页面应用只有一个页面,URL的地址都没有对应的页面,只是用于VueRouter监听,切换对应的组件,从而显示不同的页面,该方式需要服务端进行配置,否则会出现404

    Vue路由之间的跳转方式

    • 有4种方式
    • 声明式导航,也就是使用标签来跳转
      • 使用a标签,设置href属性为目标页面的路由路径,主要必须加上#/
      • 使用router-link标签,设置to属性为目标页面的路由路径,不需要加#/,点击发起路由跳转
    • 编程式导航,也就是使用使用JS来跳转
    • 使用this.$router.push,发起路由跳转
    • 使用this.$router.replace
    • 使用go(N),N为数字,正数则前进页面、负数则回退页面

    Vue如何封装组件

    • 创建一个.vue的单文件
    • 通过props声明组件需要的参数
    • 组件进行一些UI操作后,使用$emit发送自定义事件,通知父组件更新数据
    • 父子组件通信,要遵守单向数据流,父组件传参给子组件,子组件使用事件通知父元素修改数据,不能子元素修改父元素的数据,要遵守数据谁持有,谁修改

    v-show和v-if的区别

    • v-show,使用元素的display属性,设置为none来实现隐藏元素
    • v-if,条件渲染,将元素直接在DOM树中移除,来实现隐藏元素
    • 如果需要频繁显示、隐藏,一般使用v-show,因为v-if会频繁创建、销毁元素,对性能有影响
    • 需要身份校验后,根据角色才显示某些按钮,使用v-if,可以避免敏感数据的隐藏

    Vue中v-for和v-if,为什么不能一起使用

    • 在Vue2中,v-for的优先级高于v-if,所以当2个指令放在同一个标签时,就是每次循环都要先判断,再决定显示或隐藏,会消耗很大的性能
    • 解决方案是多套一层div,将v-if放在外层,v-for放在里层,直接进行判断,为true再决定是否开始循环
    • Vue3解决了这个问题,将v-if优先级高于v-for

    Vue的生命周期

    • beforeCreate,创建Vue实例前回调
    • created,创建Vue实例后回调,此时vue实例身上的data数据还没有处理成响应式变量,所以不能在这里操作data中的数据,一般在这个回调函数中,发出接口请求
    • beforeMount,挂载前回调,此时页面还是模板内容,Vue实例的data中的数据,还没有填充到视图,此时还不能操作DOM元素,因为挂载数据的时候,是重新替换视图标签,如果在此时查找DOM元素,并不是最终的DOM树
    • mounted,挂载后回调,此时data的数据已经渲染到视图,可以进行查找DOM元素,操作DOM元素等,或者使用Vue提供的refs获取DOM元素
    • beforeUpdate,Vue实例的响应式变量准备更新前回调,此时去拿响应式变量的值,还是旧值
    • updated,响应式变量更新后,此时获取data中的数据是新值,注意建议不要在该回调中更新响应式变量,容易更新后,又调用updated,产生递归,出现栈溢出
    • beforeDestroy,准备销毁前回调,一般在该回调中清除定时器、延时器、取消Ajax请求等异步任务
    • destroyed,销毁后回调,在该回调中,Vue会取消data中数据的响应式,解绑DOM元素的事件监听,所以不要在该回调中,再操作响应式变量,是不会更新DOM的
    • 如果组件被keep-alive标签组件包裹,则该进入、离开该组件时,不会销毁组件,所以上面的生命周期不会重复调用,而是会调用activateddeactivatedactivated是组件被激活,也就是页面可见,而deactivated是页面失活

    Vue-Router的钩子函数

    • beforeEach,前置守卫,可以进行私有页面的权限判断,例如token为空,拦截掉跳转,跳转到登录页,强制用户登录

    Vue-Router的传参方式有哪些

    • 查询参数跳转传参
    • 动态路由跳转传参

    Vue-Router的前置守卫

    • 在路由跳转前,执行前置守卫,可以进行私有页面的权限校验,例如判断token是否为空,为空则拦截跳转,跳转到登录页

    Vue计算属性与watch的区别

    • computed计算属性,每次获取计算属性时,如果计算属性的依赖项没有发生变化,计算属性会使用之前的缓存值,而不是每次都重新计算,提升性能
    • watch侦听器(监听器),监听属性值的变化,当变化时,执行handler回调,适用于数据变化时,更新DOM元素
    • immediate属性,是否在第一次渲染的时候就执行回调函数
    • deep属性,如果需要监听的变量是引用数据类型,要监听它内部的属性变化,就要将该属性设置为true

    keep-alive,使用页面跳转后返回数据,原数据还在吗?

    • 使用keep-alive标签组件,包裹router-view路由视图组件,能让页面跳转,组件不被销毁,组件的data数据,自然就还在

    使用Vuex时,怎么实现数据的持久化

    • 在vuex的mutation函数中,调用本地存储进行数据持久化,并在state初始化时从本地存储中获取数据来初始化state

    前置守卫的应用场景

    • 私有页面的权限拦截,在前置守卫回调中,判断Token是否为空,不为空或白名单页面(注册、登录等),才放行,否则拦截,直接跳转到登录

    优化

    页面优化思路有哪些?

    项目的打包优化

    • 路由懒加载,让目标路由页面组件,在第一次加载时,才创建,避免单页面应用首屏加载慢的问题

    Axios拦截器

    • 请求拦截器
      • 请求前,显示Loading的Toast提示,添加token到请求头
      • 请求后,隐藏Toast提示
    • 响应拦截器
      • 响应成功,对数据进行数据剥离,例如减少一层data(axios会给数据加多了一层data)
      • 响应失败,根据服务端的响应错误信息,弹出错误的Toast提示

    Token失效的处理办法

    • 在axios的响应拦截器中,判断HTTP状态码,如果为和服务端约定的状态码,如约定是401,则为token过期,前端删除本地存储的过期token,弹出Toast提示用户当前登录状态已过期,再跳转到登录页面

    UniApp

    有用过UniApp进行多端开发吗?

    UniApp开发多端发布,要考虑哪些方面?

    UniApp开发一般适合什么项目?

    UniApp中父组件、子组件、兄弟组件的数据交互

    微信小程序

    小程序扫码进来,一条链接如何获取参数

    小程序的生命周期

    小程序的跳转方式

    小程序的数据绑定和Vue的数据绑定有什么区别?

    相关文章

      网友评论

        本文标题:前端面试题收集

        本文链接:https://www.haomeiwen.com/subject/eidpmdtx.html