最近离职找工作,梳理了一下最近的面试问题,希望对大家找工作有帮助!有一些基础问题就没总结
- 响应式和双向绑定的区别
- 响应式是双向绑定的一环,响应式是数据影响视图,是单向的
- 双向绑定是双向的.数据影响视图,视图也会改变数据.
- Keep alive
- 是Vue 的一个组件,当他包裹动态组件时,会缓存不活动的组件实例.而不是销毁他们.他自身不会渲染成一个dom,也不会出现在父组链中
- 在组件切换过程中,将状态保留在内存中.防止重复渲染DOM,减少加载时间和性能消耗,提高用户体验
- 有两个对应的生命周期钩子,activate 在组件keep alive被激活时调用,在组件渲染期间不被调用.deactivated,在keep alive 被停用时调用
- Data为什么是函数
- 因为组件是用来复用的,js 中的对象都是引用关系.如果组件中data 是一个对象,那么这样没有作用域隔离.子组件中的data属性会互相影响.如果组件data是一个函数.每个实例可以维护一份返回对象的独立的拷贝.组件中的data值不会互相影响.而new Vue实例是不会被复用的,因此不存在应用对象的问题
- 动态组件和异步组件
- 动态组件其实就是component组件.组件身上可以绑定一个is属性,用来表示某一个组件.通过使用保留的元素,动态的去绑定他们的is特性,我们让多个组件可以用同一个挂载点,并动态切换.根据v-bind:is=”组件名” 中的组件名自动去匹配组件,如果不匹配则不显示.
- 异步组件在大型应用中,我们可能需要将一个应用分割成一些小的代码块.并且只在需要的时候才从服务器加载一个模块.Vue允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你定义的组件,Vue只有在需要被渲染的时候才回触发这个工厂函数.且会把结果缓存起来,供未来重渲染
- 动态组件使用异步加载的方式来加载异步组件
- Vuex
- Vuex是一个数据管理库
- 分别有state getters action mutation modules plugin 等配置项,他们之间有一个关系图.
- 解决了非关系组件之间数据传递和共享的问题
- 不过组件之间传值非常明确的时候.我会使用props ref event bus 等方法
- 能用mutation调用另一个mutation方法吗 可以 用this.commit(‘function’)
- 封装组件
- 我们封装组件是为了方便使用,简化操作,而不用写一大堆重复的代码
- Vue 组件通信 放到那个钩子里面
- 我们会放到mouth钩子里面
- 放到create里面,后端会请求一个,前端也会请求一次,不符合我们的预期
- 放到update里面,每一个数据更改都会请求一个,太频繁了
- 放到destroy里面,实例马上就要销毁了,也不行
- 怎么封装接口
- 首先会划分3个模块.api/* utils/request 组件.vue
- 封装axios的时候,会先创建一个axios实例baseURL和timeout,请求拦截和响应拦截.token过期的时候需要主动介入,登录成功后存一个时间戳,用当前的时间戳-登录成功时间戳,如果大于超时了,就直接拦截到登录页
- Cookie有那些属性
- Name和value 名称和值, name一旦被定义后,就不能修改了.
- Domain 决定cookie在那个域有效,也决定了发送请求的时候,带不带cookie
- Path 是cookie的路径
- Expire 和max age 都是设置有效期 他们的单位不一样,一个是时间戳,一个是秒.max age 为 0 则直接删除 为-1 则浏览器关闭时删除
- Size 是cookie 的大小
- Promise
- Promise本质是一个对象,是异步编程的一种方案,解决了回调地狱的问题
- 一般作为构造函数使用,需要new一下创建一个promise实例.Promise有三种状态 pending fulfilled 和reject
- Promise有两个过程 pending => fulfilled pending => reject 到reject后会触发.catch方法
- Promise 虽然解决了回调地狱问题 ,但是我更喜欢用async和await
- Async/await
- Async 会返回一个promise对象,并且promise状态是resolve的
- 如果async 中没有写return 则返回值是undefined
- 如果写了return,则return回的就是你成功时候返回的值
- Await 等到之后分两种情况
- 如果不是promise ,那么await会阻塞后面的代码.先执行async外面的同步代码.同步代码执行完,在回到async内部,把这个非promise的东西 作为await的表达式
- 如果是promise,await还是会暂停后面的代码,先执行async外面的同步代码,等promise对象fulfilled,然后把resolve参数作为await的表达式
- Async 会返回一个promise对象,并且promise状态是resolve的
- Promise和async/await的区别
- 都是解决回调地狱的问题,但是promise的.then 结构看起来还是比较混乱,所以我更喜欢用async和await
- Diff算法
- Diff算法的本质是找到两个对象之间的差异
- Diff算法的核心是 子节点数组的对比,思路是通过收尾两端对比
- Key 的作用是
- 决定子节点是否可以复用
- 简历key-index 的索引,主要是替代遍历,提升性能
- 什么是ajax
- 创建交互式网页应用的网页开发技术.可以在不刷新页面的情况下与服务器进行异步通讯
- 优点
- 最大的优点就是无刷新页面,用户体验非常好
- 可以使用异步的方式与服务器通信,具备更加迅速的能力
- 可以把服务器的压力转给客户端.节约空间和宽带租用成本
- 不需要下插件和小程序
- 缺点
- 不支持ajax 的back按钮
- 安全问题,暴露了与服务器交互的细节
- 对搜索引擎的支持较弱
- 破坏了程序的异常机制
- 常见的http状态码和意义
- 100 初始化 200 成功 300 重定向 400 请求格式错误 500 服务器遇到一个未曾预料的错误
- 101 正在切换协议 202 表示接收 301 永久重定向 302 临时重定向 304 本次获取的内容是读取缓存中的数据,每次都会去服务器校验 401 未认证 没有登录网站403 禁止访问,没有权限 404请求失败 502 充当网关或代理服务器 503 服务器超负荷
- 505 服务器不支持请求的http协议版本
- 上传图片怎么做的
- 创建input 设置type:file hidden隐藏 绑定change事件
- 创建一个button 创建点击事件 点击触发input change事件
- 监听input change 事件, 获取e.target.files属性
- 创建一个 new fromdata 对象,把文件信息放入axios 传入后端
- 图片预览:有两种方式
- URL.crateObjectURL(blob)
- FileReader(base64)
- 常见http请求(8种)
- Options 返回服务器正对特定资源所支持的http请求方法,也可以利用想web服务器发送 的请求测试服务器的功能性
- Head 想服务器 要get 请求相一致的响应 只不过响应体将不会返回 这一方法不必传输整个响应的情况下,可以获取包含在响应小消息头中的元信息
- Get 向特定的资源发出请求
- Post 向指定资源提交数据进行处理请求(例如提交表单或上传文件)
- Put 向指定资源位置上传最新内容
- Delete 请求服务器删除 requestURL所标识的资源
- Trace 回显服务器所有到的请求
- Connect http/1.1协议中预留给能够将链接改为管道方式的代理服务器
- 小程序和网页开发的差异
- 开发环境不同
- 宿主环境不同
- 上线流程不一样
- 开发项目的时候,有没有碰到过数据变了,但是视图没有变的情况
- 对象创建不存在的key赋值
- 因为vue是利用object.defindproperty 递归劫持里面的每一个属性,一上来就直接劫持了 所以后来添加的属性没有被劫持到
- 通过this.$set()解决
- 数组通过索引修改数组
- 性能问题
- 通过this.$set() 解决
- 还可以通过this.splice(1,2,1)解决
- Vue3 没有这个类问题 因为vue3是使用proxy proxy 劫持的就是对象 修改数据也不存在性能问题
- 对象创建不存在的key赋值
- 权限管理怎么做
- 用户登录后,后端获取到用户标识
- 前端获取到标识后,进行筛选 得到[有权限的路由/动态路由]
- 然后做了2件事
- 通过addrouters 把有权限的路由 添加到路由实例上.这样用户就具有访问某个路由的权限了
- 把动态路由添加到vuex一份,这样利用addrouters 后续添加路由的时候也会被追踪到,并且可以给侧边栏或其他地方使用
- 封装一个全局的指令或者方法,这个方法只绑定一个事件,内部进行一个判断,看一下这个标识在不在后端返回的功能列表里面,有就true 没有就false.需要对按钮进行权限判断的时候就调用这个指令或方法,根据返回的是true/false来判断显示或隐藏
- 组件传值
- 父传子
- 给父组件绑定自定义属性 子组件props接收来实现传值
- 父组件通过ref 来获取子组件的实例,调用子组件实例方法,子组件接收,来做出对应的修改
- 不常用:父组件通过$childer方法来修改
- 不常用:父组件通过$attr方法来自定义修改
- 子传父
- $emit(第一个传事件 第二个传值)
- $parent来修改父组件的值
- 不常用:$listevenrs来修改
- 不常用:直接this.props属性来修改
- 兄弟之间传值
- 状态提升 A-B B把要数据放到公共的父组件中,A通过子传父,然后父组件父传子 传给B来修改
- Event bus 已经废弃 原因是太快速了,无法追溯.可以用插件 meet插件能解决
- 父传子
- Router跳转的几种方式
- Router link to
- This.router.push 调到指定路由 会被history 记录 回退是退到上一个页面
- This.router.replace 调到指定路由 不会被history记录 回退是直接退到上上页面
- This.router.go 向前或向后跳N个页面,可以为证书也可以为负数
- Router传参
- Params 传参
- Query 传参
- Vue 怎么注册全局组件
- 在main.js中直接注册 里面import XX from ‘xxx’ 然后vue.component
- 在其他组件export default 导出,在main.js 中导入 然后 vue.use()使用
- 界面访问控制
- 在全局前置路由导航中做, 有token就next 放行 没有token 如果在白名单就放行,不然就拦截 跳转到登录页
- Token过期怎么办
- 一般在响应拦截器 根据后端返回数据401来进行清理用户信息并跳转路由
- 处于安全新考虑.token的有效期一般是后端定的2小时,但是这样会用户体验不好,这个时候可以用refresh_token当token触发401的时候,此时可以用refresh_token来覆盖旧的token然后再把失败的请求发出去
- 防抖和节流
- 防抖:持续触发不执行,不触发一段时间后执行
- 节流:持续触发也执行,但是触发的频率变低了
- 重绘和重排(回流)
- 重绘:元素样式改变,但是不影布局时,浏览器会使用重绘对元素进行更新,性能损耗较小 例子:改变背景颜色, 改变颜色等等
- 重排:当元素的尺寸,结构 触发某些属性时,浏览器会重新渲染页面,成为回流,浏览器要重新计算,计算后要重新布局 所以算比较重的操作 例子:页面第一次渲染,浏览器窗口大小发生改变.元素尺寸发生变化,元素字体大小发生改变,添加或修改dom元素
- 加入有100000个元素需要添加到页面上,怎么操作性能最好
- 利用文档碎片方法fargment 这个方法可以把所有要构造的节点放到文档片段中执行,这样可以不影响文档树,当节点构造完成后,再把文档碎片对象添加到文档中,这时所有的节点会一次渲染出来
- Vue 的性能优化
- v-for 循环的时候 带上key
- v-for 和v-if 不要放一起
- v-if 和 v-show区分使用场景
- 路由懒加载 组件动态加载
- Keep alive
- 怎么配置vue cli
- 在vue.config.js里面配置
- 深拷贝和浅拷贝
- 浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝.如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的是内存地址,所以如果其中一个对象改变了这个地址,就会影响另一个对象
- 深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存,当对象和他所引用的对象一起拷贝时即发生深拷贝.深拷贝相比于浅拷贝速度较慢并且开销花销较大,拷贝前后两个对象不影响
- 遇到的难点
- 路由缓存问题
- 点击用户1按钮和用户2按钮 共用了同一个路由组件USer,我在User里面根据userId发送请求的时候,发送永远是第一次发送的那个请求,很好奇,找不到原因
- Template里面获取数据是实时更新的,但是create拿不到最新的数据,后来发现原因是公用了同一个组件,二created这个钩子也会在组件创建完毕执行一次
- 第一个解决方法:<router-view :key="$route.fullPath"></router-view>
- 用watch监听router 然后
- 大数字问题
- 根据文章ID请求文章详情的时候,有的时候正常,有的时候出现404,找不到详情,反复检查了传参和接口都没有问题 百思不得其解..
- 愿意:后端给我的文章列表,当文章ID包含大数字的时候出事了
- 本质上说,后端返回的数据都是JSON格式的字符串, axios帮我们进行了内部处理,它为了方便我们前端使用,内部进行了JSON.parse操作转成了对象
- 但是 json格式的字符串内包含大数字的时候,JSON.parse就搞不定了,也就是后端返回JSON格式的字符串内包含大数字的时候,axios进行内部JSON.parse的时候,把大数字转换成了另一个结果,所以404
- 怎么解决
- 找后端, id 不用数字表示,用字符串表示文章id
- 自己搞定,用jsonbigint 插件包,一行代码搞定
- 路由缓存问题
- History和哈希的区别
- Hash 使用URL hash值作为路由,支持所有浏览器 带# 号 能兼容ie8 跳转的时候只能修改# 后面的内容
- History 依赖html5 history API 和服务器配置, 修改更自由
- Next tick的用处
- 因为vue采用的是异步更新的策略,通俗点说就是,同一事件循环内 多次修改,会统一进行刷新。所以也会造成一个问题,数据一更新,但是视图却还没有更新,所以拿到的是上一次的旧视图的数据 ,想到拿到最新的数据 ,就使用next tick。
- Vue 的ssr是什么,有什么好处
- Ssr就是服务端渲染
- 基于nodejs serve 服务环境开发,所有的html渲染在服务端
- 数据发送给前端,前端进行激活,即可成为浏览器识别的html代码