前端高频面试题(正逐步完善中,比较简单的暂没写)

1.前端加密的方式有哪些?

JShaman加密(不可逆,加密代码和数据)
    直接到JShaman(www.jshaman.com)平台提交代码,得到加密后的js代码。这个方法很好用。
MD5加密(不可逆,加密数据) 
    MD5.js是通过前台js加密的方式对用户信息,密码等私密信息进行加密处理的工具,也可称为插件。
base64加密(可逆,加密数据)

2.说一哈 $nextTick?使用场景?

$nextTick 是在DOM更新完成之后执行回调函数的方法
修改data中的数据,会引起视图的更新,而vue更新dom是异步的,不能立马获取更新后的dom,这时候就需要使用$nextTick
​
怎么才能获取:
​
1.)在updated钩子函数中可以获取更新后的dom,但是不推荐,会造成代码的分离
​
2.)使用vue中的$nextTick方法:有延迟回调的作用,可以获取更新后的dom
​
在我以前做过的项目中,有一个需求,在员工页面点击员工的头像时,展示一个二维码,这个二维码弹框是由el-dialog组件和canvas画布组成的,它本来是隐藏的,点击之后弹出,想要把地址转化为二维码,需要先获取画布的DOM,才能进行地址转化为二维码的操作,但是Vue中页面的更新是异步的,此时就要用到$nextTick了
​
​
在vue中如何获取DOM?
​
(1)通过原生获取DOM的方式
​
(2)通过ref
​
第一步:在标签中添加ref属性
​
第二步:通过this. $refs.属性名获取DOM

3.transition和animate的区别?

1. transition是一个过渡的效果,没有中间状态,需要设置触发事件(如hover等)才能执行;
​
2. animation是一个动画的效果,有多个中间帧,可以在任意一个中间帧设置状态,不需要设置触发事件就能执行。

4.介绍一下插槽?

插槽的使用是为了解决组件中内容不确定时,使用slot进行占位。父组件传递什么内容,slot对应的子组件就显示什么内容。
​
插槽分为具名插槽和作用域插槽
​
具名插槽:当一个组件里,出现了两个及以上标签内容不确定需要slot占位时,这时就需要用到具名插槽,用name属性来区分不同标签。
​
作用域插槽:数据在子组件中,但父组件要用子组件中的数据。子组件通过row属性传递数据,父组件通过s1ot-scope=“scope”来接收数据

5.promise作用?

promise是一个对象,可以从对象获取异步操作的消息
它主要解决地狱回调的问题
​
为什么多个回调函数嵌套:下一个接口的参数依赖于上一个接口返回的结果
​
promise语法: 方法中有两个参数
    new Promise( function(resolve.reject){ } ).then(( ) =>{ }).catch(( ) =>{ })
             resolve代表调用成功,会走then
             reject代表调用失败,会走catch

6.什么是地狱回调?

多层回调函数的嵌套,使代码结构看起来很乱,难维护
​
使用场景:1.延时器的嵌套
        2.下一个接口的参数依赖于上一个接口返回的结果
       
如何解决回调地狱:通过promise的链式调用来解决

7.介绍一下async和await?

1.await修饰的是promise,会强制等待promise中resolve执行成功后的结果;
2.await必须搭配async使用,在await的父级方法中加async,不加的话会强制等待,阻塞其他代码的执行,加上async后,async修饰的方法会变成一个异步方法;
3.async修饰的方法会返回一个promise,因此可以用promise修饰;
4.async和await捕获错误是通过try{}和catch(error){}进行的

8.token的持久化存储

1.什么是token?
​
token是登录接口调用成功之后.后台返回的一个值,它是一个凭证,在调用有权限的接口时要传递过去,接口才能调通,因此token需要做一个存储
​
2.token如何进行存储?
​
人资项目在token存储在vue中的同时,又顺便在cookie缓存里面存储一份,达到持久化存储的一个目的,由于在vuex中存储的数据,在刷新浏览器时会丢失,因此需要在缓存中存储一份

9.call apply bind三种方式的区别?

 共同点:
​
 1、都是用来改变函数的 this 指向
 2、第一个参数都是 this 要指向的对象。 
 3、都可以利用后续参数传参。 
 区别:
call和apply 都是Function对象的方法,它们的主要作用是改变函数的运行环境。
​
call和apply方法都是接受两个参数,第一个参数是需要改变上下文的对象,而call的第二个参数是参数列表,apply第二个参数是参数数组。
​
bind方法也是Function的方法,bind 主要是返回一个函数的副本并指定参数,并不会立即运行函数。

10.vue中的$set方法有什么作用?

vue2中修改数据视图不能及时重新渲染,因此要用$set,$set是为了解决数据没有被双向绑定。
$set有3个参数,参数1是需要更新的对象和数组,参数2是要更新的数组的下标,或者对象的属性名,参数3是要更新的内容

11.v-mode双向绑定:

数据驱动视图,视图驱动数据改变
​
v-model双向绑定的原理:v-model是一个语法糖,他是动态属性value和@input事件的结合体
v-model实际是通过v-bind绑定value然后通过v-on定义input事件去更新绑定的值,这样就实现了双向绑定,可以说是一种语法糖
​
v-model主要是给表单元素使⽤,获取的是value的值,有时候封装组件也可以进⾏v-model绑定数据,⽐如定义⼀个组件,⽤props接收value,再⽤$emit给 input传值,这个组件就可以被绑定v-model了  

12.Vue 数据双向绑定的原理是什么?

Vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
1、需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter,这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化
2、compile 解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
3、Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要做的事情是:
3.1)在自身实例化时往属性订阅器(dep)里面添加自己 自身必须有一个 update()方法
3.3)待属性变动 dep.notice()通知时,能调用自身的 update()方法,并触发 Compile 中绑定的回调,则功成身退。
4、MVVM 作为数据绑定的入口,整合 Observer、Compile 和 Watcher 三者,通 Observer 来监听自己的 model 数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起 Observer和 Compile 之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据 model变更的双向绑定效果
​

------------------------

13.什么是路由懒加载?

项目性能优化的方案之一,当跳转到这个页面时,才去加载这个页面所对应的组件,而不是一次性引入,减少了项目打包之后的提交,提升了页面的渲染性能,尤其是首页的渲染性能

14.人资项目中为什么要有路由模块的划分?

是因为项目中牵扯到静态路由和动态路由
​
1.)什么是静态路由?
​
任何用户都可以去访问这个页面
​
2.)什么是动态路由?
​
有权限的用户才能访问某个页面,没有权限访问不了,是根据用户权限去分配的
​
3.)为什么每个路由模块都引入了layout布局?
因为要做动态路由管理,每个路由模块都应该属于自己的完整布局

15.路由跳转方式有哪些?

第一种: 通过a标签的href属性 (不常用)
第二种: 声明式导航的router-link进行跳转
第三种: 编程式导航的push,replace,go,back等 如This$router.push('/')
1、<router-link to="需要跳转到⻚⾯的路径">
2、this.$router.push()跳转到指定的 url,并在 history 中添加记录,点击回退返回到上⼀个
⻚⾯
3、this.$router.go(n)向前或者后跳转 n 个⻚⾯,n 可以是正数也可以是负数
4、this.$router.replace()跳转到指定的 url,但是 history 中不会添加记录
5、this.$router.back()回退到上⼀个⻚⾯
(1) 通过path匹配路由的编程式导航形式 通过this.$router.push 用$route.params/query.传递的参数
(2)通过name匹配路由的编程式导航形式 this.$router.push 用$route.query/params.传递的参数
(3)在跳转时通过path搭配query进行跳转(不能用path搭配params进行传参)

1X.路由传参的⽅式有哪些?

两大方式:
声明式的导航和编程式的导航 router.push 
(1)编程式:
    第一种: 在跳转时通过name搭配params进行传参
​
    第二种: 在跳转时通过name搭配query的方式传参
​
    第三种: 在跳转时通过path搭配query进行跳转
    备注:不能用path搭配params进行传参
    name 和 params的搭配传参
    this.$router.push({name:"news",params:{userId:123}) 
    path 和 query的搭配传参 
    this.$router.push({path:"/news',query:{uersId:123})
(2)声明式导航: 
    命名路由: <router-link :to:"{name:'news',params:{userid:1111}}"></route-link>
    查询参数: <router-link :to="{path:'/news',query:{userId:1111}}"></router-link>

16.路由中携带的参数接收方式有哪几种?

1、?形式的参数使用this.$route.query接收参数,结果是一个对象
2、:形式的参数使用this.$route.params接收参数,结果也是一个对象

17.$route和$router 的区别是什么

(1) $router里面存 放的是所有的路由信息,可以通过this. $router.options.routes获取
​
(2) $router可以操作路由, 例如: this. $router.push('/")
​
(3) $route存放的是单个路由地址信息;
    例如:可以在里面可以获取到路由地址携带的参数      
         this.$route.palms.参数名称

18.路由 (什么是路由?)(为什么学路由)

1.什么是路由:
路径和组件(或者页面 )一一对应的映射关系
​
2.为什么要学路由?
通过路由实现的项目是一个单页面应用,路由地址发生变化,页内容局部更新,用户体验良好
​
3.什么是单页面应用(应为缩写SPA)
项目中只有一个html文件,所有的业务功能都是在这一个页面切换
​
4.如何在项目中使用路由:
安装一个包:vue-router
​
5.什么是组件的分类
组件分类是开发者,人为的去进行划分的,一般分为页面组件、复用组件(公共组件),
为了项目管理和维护
一般情况下,页面组件放在views文件夹,公共组件放在component文件夹
​
6.vue-route的基础使用
    1.安装插件vue.route
    2.准备要切换的页面,在views文件夹下创建
    3.在App.vue中准备了跳转按钮
    4.配置路由
      1.)在main.js中引入路由
      2.)注册路由模块包 Vue.use()
      3.)配置路由规则
      4.)创建路由实例
      5.)将路由实例添加到vue实例配置项中
      6.)   在跟组件中配置路由挂载点,也叫容器

19.路由的跳转方式

第一种:通过a标签的href属性    <a href="#/find">发现音乐</a>  (不常用)
​
第二种:通过vue内置的组件router-link进行跳转,又叫声明式导航
​
       声明式导航的特点:底层还是a标签,但是多了激活的class类名,可以实现高亮功能
​
第三种:编程式导航跳转(也叫js的跳转方式,最常用)
​
      1.)通过path跳转 this.$router.push(path:路由地址)
​
      2.)  通过name跳转 this.$router.push({name: 路由名称})
​
      通过name跳转的前提是在路由规则里面配置name属性
​

20.编程式导航的传参方式:

第一种: 在跳转时通过name搭配params进行传参
​
第二种:在跳转时通过name搭配query的方式传参
​
第三种:在跳转时通过path搭配query进行跳转
​
备注:不能用path搭配params进行传参

21.声明式导航的传参方式:

1.)路由地址后面通过?拼接的方式进行传参,在页面中接受是采用:$route.query.参数名称接受
​
2.)采用动态路由传参的方式,首先得在路由规则中配置要传递的参数
​
    path: '/part/:username', //username是要传递的参数
​
    <router-link to="/part/username">朋友2</router-link>
​
    通过$route.params.username接收

22.路由重定向

使用场景:网页一打开的时候,一般默认都是一个空路径,就不会显示页面内容
​
怎么能默认一个页面内容进行显示?
​
采用路由重定向的方式默认一个页面进行展示

23.路由模式的分类

1.)hash模式:特点  路由地址里面有#  默认就是hash模式
​
2.)history模式,特点时路由地址没有#,在上线之后需要服务端的支持,需要去配置 mode:history

24.路由模式:哈希模式和history模式的区别

1.路径表现的外观上:
​
    在vue的路由配置中有mode选项 最直观的区别就是在url中 hash 带了一个很丑的 # 而history是没有#的
​
2.本质上:
​
    hash-----虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
​
    history -----利用了 HTML5 History Interface 中新增的 history.pushState() 和 replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。

25.vue-router的实现原理是什么? (是不是浏览器对象的封装)

1.hash ---- 利用URL中的hash(“#”),hash,只会替换掉url中#以后的路径,而不会管前面的,hash不能对完全相同的url产生变化,所以说Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据

2.利用History interface在 HTML5中新增的方法,history会改变整个url就算一样的url还是会产生路由记录(history.pushState API)

---------------------------

26.在vue中如何获取DOM?

(1)通过原生获取DOM的方式
(2)通过ref
   第一步:在标签中添加ref属性
   第二步:通过this. $refs.属性名获取DOM

什么是虚拟dom?(面试题)

本质是一个js对象,里面存放的是真实dom的重要信息,虚拟dom是通过template模板标签转化而来的;
​
虚拟dom最终的作用:新旧虚拟dom做对比,只更新变化了的部分,类似于打补丁,最终减少了操作真实 dom的次数,提高了页面的渲染性能

27.new操作符做了什么?

1.创建一个空的对象
2.将空对象的proto属性指向构造函数原型
3.将this的指向这个原型
4.返回这个对象

28.描述一下js中的事件流?

事件流就是事件的流向,分为事件捕获阶段,目标阶段,事件冒泡阶段

29.组件缓存如何实现?

使用Keep-alive内置组件将动态组件包真起来,就可以实现组件的缓存

30.keep-alive的实际应该场景 (组件缓存或页面状态的缓存)

keep-alive主要⽤于动态组件和路由,进⾏组件或者⻚⾯状态的缓存,常⽤于列表⻚和列表详 情⻚之间切换的场景,优点是可以保留进⼊详情⻚之前列表的滚动位置,缺点是不会更新列 表,当然也可以在activated⽣命周期重新发起ajax获取数据

31.vue之间的组件通信

1.父传子
    通过父组件,在子组件标签上,绑定一个属性:users="users",子组件通过props接收
2.子传父
    子传父:
        1.在子组件中通过$emit()方法定义事件,参数1:'自定义事件名',参数2:要传给父组建的参数
        2.在父组件中通过v-on指令监听自定义事件,然后在监听的回调中取得数据
        子组件:<button v-for="item in categroies" :key="item.id" @click="getData(item)">{{item.name}}</button>
         getData(item){
             //子传父:1.通过自定义事件
             this.$emit('itemclick',item);
         }
         父组件:
            <cpn @itemclick="getChild"></cpn>
            //2.在父组件中取得数据
                getChild(item){
                    console.log(item);
                }
3.兄弟相传(有吗?)
    vuex
4.父访问子
    //通过$refs:需要在子组件上加上ref属性值为子组件名字(例如:cpn),然后通过$refs.设置的名字获取到相应的子组件
    this.$refs.cpn.showMessage();
5.子访问父
    //通过$parent访问父组件
    console.log(this.$parent);
6.访问root组件
    //访问根组件:通过$root
    console.log(this.$root);

32.vuex持久化的实现

要想实现vuex刷新后数据不丢失,一般使用localStorage来完成,也可以使用vuex-persist插件来完成,它不需要你手动存取storage状态保存至localStorage中

33.es6的新特性

1.箭头函数
2.解构赋值
3.模板字符串
4.拓展运算符
5.let,const

34.项目优化

基础的 Web 技术层面的优化:
1.合理使用v-if和v-show
2.computed 和 watch 区分使用场景
3.v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
4.图片资源懒加载
5.路由懒加载
6.浏览器缓存
7.CDN的使用
8.前后端开启gzip压缩,前后端只需要简单配置
- 减少http请求
- 减少对DOM的操作
- 使用JSON格式来进行数据交换
- 高效使用HTML标签和CSS样式
- 将CSS和JS放到外部文件中引用,CSS方头部,JS放尾部
- 精简CSS和JS文件
- 压缩图片和使用图片Sprite(精灵图)技术,图片懒加载
- 注意控制Cookie大小和污染
webpac配置优化:
1.Webpack 对图片进行压缩
2.减少 ES6 转为 ES5 的冗余代码
3.提取公共代码
​

35. 在浏览器里面输入一个URL地址,敲回车键经历了什么?

第一步:首先会在浏览器缓存里面检测有没有自己查找的资源,如果有,直接从缓存里面取;
​
      如果缓存里面没有这个资源,会通过DNS域名解析服务器寻找url域名所对应的ip地址
​
第二步:建立TCP连接,经历了3次握手
​
第三步:连接成功之后向服务器发起http请求
​
第四步:服务器处理请求,作出响应
​
第五步:拿到响应结果之后,断开TCP连接(经历了四次挥手)
​
第六步:解析HTML生成DOM树,解析CSS生成规则树
​
第七步: DOM树和规则树完成了最终的页面渲染

36.Tcp三次握手

tcp的握手其实就是客户端与服务器端建立可靠连接的过程,首先客户端向服务器发送一段tcp报文,服务器端接收并返回一短报文告诉客户端服务器已经收到,随后客户端再发送一段报文表示连接已经建立,三次发送报文的过程就是三次握手,四次挥手是断开连接的过程,原理大同小异.

37.为什么避免v-if 和 v-for ⽤在⼀起?如何解决?

当 Vue 处理指令时,v-for ⽐ v-if 具有更⾼的优先级,通过 v-if 移动到容器元素,不会再 重复遍历列表中的每个值。取⽽代之的是,我们只检查它⼀次,且不会在 v-if 为否的时候运 算 v-for。如果真的需要⼀起使⽤,可以先写if,再使⽤标签包裹需要循环的内容,讲循环写 在template标签上。

38.v-if和v-for的优先级

在vue2中,v-for的优先级是⾼于v-if,在vue3中则完全相反,v-if的优先级⾼于v-for,所 以v-if执⾏时,它调⽤的变量还不存在,就会导致异常

39.pc端图片上传功能:

1.封装一个图片上传的组件,利用el-upload组件
2.选择完要上传的图片之后,会触发组件的on-change钩子函数,这个函数可以获取选择文件的图片信息
3.获取图片信息之后,赋值给upload组件的filelist属性所绑定的数组,待触发上传动作之后,本地图片   就可以 展示在展示区,此时的图片的地址还是本地图片地址,
4.通过http-request触发上传,在这里获取文件的信息,调用后台接口,将图片信息作为参数,传给后     台,存放到后台服务器
​
5.加了一些图片上传的补充功能:图片的预览,调用on-preview钩子函数,实现了图片的删除,调用了
   on-remove钩子函数,还做了图片上传之间的检查功能,调用了before- upload钩子函数
 备注: 由于人资项目是上传到腾讯云服务器,所以在http- request钩子函数中利用插件的方法和腾讯云       服务器进行了交互,上传成功之后,腾讯云服务器返回了一个图片的线上地址

40.为什么要使用组件缓存?

在动态组件进行频繁切换的时候,会频繁的创建和销毁组件,影响性能

41.cookie、sessionStorage和localStorage的区别?

  • - cookie是网站为了标示用户身份而储存在用户本地终端上的数据(通常经过加密)
    ​
    - cookie数据始终在同源的http请求中携带
    ​
    - 存储大小:
      cookie数据大小不能4K
    ​
      sessionStorage和LocalStorage虽然也有存储大小的限制,但是比cookie大得多,可以达到5M或更大
    ​
    - 有期时间:
    ​
      LocalStorage存储持久数据,浏览器关闭后数据不丢失除非主动删除数据
    ​
      sessionStorage数据在当前浏览器窗口关闭后自动删除
    ​
      cookie设置的cookie过期时间之前一直有效,即使窗口或者浏览器关闭

42.如何实例化一个echars(在vue中使用echars步骤)

1.安装echars    yarn install ecahrts --save
2.导入ecahrs插件,在main.js文件下配置(挂载到vue原型上): 
      import ecahrs from 'ecahrs'
      Vue.prototype.$echars = echars
3.在组件页面中,建立一个容器,放入echars,并引入 
      import echarts from 'echarts'
4.初始化eachrs,建立mounted生命周期钩子函数
      初始化: var myChart = echars.init(document.querySelector('#list'))
      拿到echars图表需要的数据库:
        var option = option: {
            图表数据
        }
5.最后优化代码格式
​

43.computed和watch有什么区别?

computed:计算属性

支持缓存,计算属性对应的函数执行后,会把返回值缓存起来 当依赖项不变时 多次调用函数都是从缓存里取值,赖项变化时 函数会自动重新执行并缓存新的值

watch:侦听属性

不支持缓存,数据变,直接会触发相应的操作,监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值

44.js 防抖和节流

防抖

当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时 

节流 

 当持续触发事件时,保证一定时间段内只调用一次事件处理函数  

 区别: 

 节流   不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,防抖   只是在最后一次事件后才触发一次函数。

45.=== 和 ==的区别?

===:等同符,等号两边值与类型都相等时,才会返回true

==:等值符,等号两边的值为相同类型时比较值是否相同,类型不同时转换为相同的类型后再作比较。也就是说两个等号只要值相等就可以

46.获取对象中的属性

for in

object.keys

object.value 获取对象属性的值

47.文件上传是如何实现的?(即项目中的文件上传步骤)

1、使用 input 标签<input type="file">拾取本地要上传文件

文件上传按钮绑定点击事件

选择文件信息 files的判断 是否小于等于0

选择了发起接口请求,传递fromdata类型

new fromdata对象

2、前端使用http传送文件,文件以FormData为载体,Content-Type 选择为multipart/form-data

3、后端接收并解析FormData

48.什么是跨域?怎么解决跨域?

是由于浏览器的同源策略限制的,只要两个页面的协议、域名、端口号,其中一个不一致,就是非同源,就会产生跨域问题 

出现跨域的根本原因:浏览器的同源策略不允许非同源的URL之间进行资源的交互。

1.后端解决方案:

根本的解决方案

CORS:出现的较晚,它是W3C标准,属于跨域Ajax请求的根本解决方案。支持GET和POST请求。缺点是不兼容某些低版本的浏览器。

前端解决方案:

2.JSONP实现原理:主要就是利用了script 标签的src,不受跨域的限制

3.反向代理:
在vue中,脚手架在启动项目时,顺便启动了一个本地后台服务,这个本地后台服务地址和前端服务地址是一致的,在发起请求时,本地的前端服务先去请求本地的后台服务,本地的后台服务再去请求真实的服务,服务和服务之间不存在跨域问题,从而解决了跨域

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值