【无标题】

面试题-1_2022/2/16

vue

1.r-v区别

数据驱动试图,props父子传递参数,虚拟dom,组件化开发,支持webcomponent,都支持native方案,react-native,vue的weex
v:mvvm模式,r:针对mvc的view层,vue会跟踪每个组件之间的依赖关系,不会整个渲染dom树,对于react,每次数据跟新都需要重新渲染整个dom数,需要依赖showComponentUpdate实现
vue中可以直接修改data中的数据,react需要借助setState方法,
组件写法:r采用all in js的概念,也就是把html css js都写在js中;v的话采用的是webpack和vue-loader的单文件格式,就是把html css js都写在vue文件中在哪个
vue数据流动是双向的,react数据流动是单向的

token失效

1.后端记录,前端每次操作都延后,session就是利用这种策略保持token有效期,前后分离后每次操作都需要刷新一下,消耗性能,
2.使用refresh token,后端在token过期的时候通知前端,前端重新使用refresh token更新token,避免重复刷新
tokne

2/9

虚拟dom和key

直接操作dom元素开销很大,耗费性能,因此使用原生对象对真实dom进行模拟,是对真实dom的一层抽象
1,使用js对象对真实dom树的模拟,对真实dom的一种抽象
2,使用diff算法对比差异
3.使用pach算法,将对比两个虚拟dom对象的差异渲染到真正的dom树
key作为vnode的唯一标识,可以使diff算法更快更准确的找到需要更新的dom
在sameNode中将a.key和b.key进行对比,避免就地复用
根据key的唯一性生成map对象比用循环获取对应节点更快速

vuex中mutation为什么是同步

vuex中修改数据的唯一途径就是mutation,action本质上也是用mutation进行提交的,mutation是同步的方便我们跟踪没一个状态的变化,
每个mutation执行都会有一个对应的状态变更,这样devtools就可以打个快照保存下来,从而实现time-travel,如果是异步的,就无法知道状态什么时候变更,增加调试难度

vuex和全局对象差别

vuex的store是响应式的,数据发生变化响应的依赖会重新渲染更新,vuex的数据不允许随意修改必须通过mutation进行更新,全局对象可以随意更改,而且容易导致命名污染,vuex可以解决跨组件通信问题

vue中组件通信:

$emit和props传递
vuex/Even事件总线
a t t r 和 attr和attrlistren
provide/inject
p a r e n t / parent/parent/children和ref

路由钩子(路由守卫):

全局:beforeEach,afterEach,beforeResolve
路由独享:beforeEnter
组件路:beforeRouterEnter,beforeRouterUpdate,beforeRouterLeave

diff算法:

先比较有无子节点(无子节点则直接将旧的子节点删除)
比较都有子节点的情况
递归比较子节点

vue响应式原理

1.一个vue实例创建的时候,会遍历data属性,利用obj.defineproperty转为get和set并在内部追踪他们的依赖.属性被访问和修改的时候通知变化
2.每组组件实例都有一个watcher程序实例,会在组件渲染时将属性记录为依赖,之后当依赖的setter被调用的时候,会通知watcher重新计算,关联的组件得以更新

vue实现按需加载

1.()=>import引入
2.require.ensure()

vuex五个核心属性

1.state-数据存储
2.getter-state的派生,相当于计算属性
3.mutation:修改state中的数据必须是同步的,每个mutation都有一个字符串类型的type和一个回调函数handler
4.action:提供异步修改mutation的方法,本质是提交mutation
5.modules:模块化vuex

vue优化

1.gzip压缩
2.骨架屏
3.图片压缩,icon图标,尺寸限制
4.ui库按需加载
5.不打包框架库,cdn引入
6.用optimization抽离公共js
7.抽离css
8.配置路由懒加载

MVVM模式

1.m-数据层,用于存储数据
2.v-view视图层,负责数据的渲染
3.viewModel-负责监听model数据的变化控制view视图的更新,处理用户交互操作
model和view无直接关联,通过viewModel实现联系,model数据更新触发view的更新,页面用户交互操作导致的数据变化也会更新到model

vue2收集依赖的过程:

vue2的分成挂载前,挂载时,挂载后 挂载前:对data对象的一个遍历,要进行对应的下载getter,setter,getter里面维护了一个收集依赖的对象 挂载时:1将template转成render函数, 2创建一个updateComponent函数,在updateComponent中会调用上一个render函数, 3给每个组件或者是vue实例new一个Watcher,这个Watcher里面会传入上一个步骤的updateComponent, 在new Watcher的时候会先调用一次upDateComponent 挂载后:我们的用户去更新数据的时候就会触发对应的Watcher,这样能更新视图, 在new Watcher的时候,在构造器的内部会调用一次render,render函数是有template编译过来的,在这个里面会访问data的属性,进而触发getter,在getter中触发了依赖的收集

vue首页优化

1.骨架屏
2.减少请求,异步路由
3.按需引入,延迟加载图片,cdn引入,分屏

vue拓展组件

1.hoc高阶组件
2.solt
3.mixin
4.vue.extends

2/10

keep-alive

用于缓存被keep-alive包裹的组件
有两个参数include exinclude in-对名称匹配的组件进行缓存,ex-对名称匹配的组件不缓存,有两个钩子,activated和deactivated,组件激活触发activated,组件移除触发deactivated

vue2-3有什么区别

1.vue3监测机制改变,只能监测属性不能监测对象,
2.对象式的组件声明方式,
3.监控数据的改变,vue3没继续沿用obj.defineProperty的方式,改用proxy和reflect的方式,obj.dp会改变原始数据,而proxy是创建对象的虚拟表示,并提供set.get和deleteProperty等处理器,这些处理器可在访问或修改原始对象的属性时进行拦截,
4.vue2是optionAPI,vue3是compositionAPI
5.vue2的组件 太过于依赖this上下文,开发方式不太灵活

vue模板编译的原理

将template转化成render函数
1.解析模板生成AST语法树,运用大量正则对模板进行解析,遇到标签文本都会用对应的钩子进行处理
2.vue的数据是响应式的,但是不是所有数据都需要,dom也是,有些数据在初次渲染之后就不会再改变,可以深度遍历AST数对相关节点进行标记,这样对比的时候可以跳过
3.最后再转成可执行的代码

vue使用$ _定义

1.可以不被vue实例代理,防止和内部api冲突
2.可以使用vm.$data._property获取

a t t r s 和 attrs和attrslisteners

attrs:获取父级以上的所有属性(非props)
listeners:获取父级以上所有的方法

assets和static

assets和static都是用来存放资源
assets会压缩打包,最后放到static中和index.html一起上传
static则是直接进行上传,一般用来存放已经打包好的第三方库,例如icon字体之类
assets会一定程度影响打包时间,但是如果直接将一些需要压缩的文件放到static中,会暂用服务器空间

vuex原理

1.一个应用可以看成三部分组成,view,action.state,数据的流动也是view-action-state-action,组件嵌套太深,多组件共享一个state就会出现很多问题
2.vuex可以看做是所有组件的数据中心,将所有组件的共享state抽离出来.所有组件都可以访问数据中心
3.vuex的组成是一个实力化的vuex,store通过state,mutation.action组成

vue销毁定时器

1.使用$once监听定时器
2.将定时器赋值给this,最后根据this清楚

vue访问组件实例或者元素

使用$ref获取

watch使用箭头函数

this收到当前上下文影响,不会指向当前实例,this获取undefined

vue部署404

1.检查nginx是否正确映射
2.检查vue.config.js中publicPath是否正确

React

react如果进行组件/逻辑复用:

高阶组件,属性dialing,反向继承,渲染属性,react-hooks

redux如何进行异步操作

1.可以使用componentDidMount中直接请求无需借助redux,在一定规模项目中,比较难进行异步流管理
2.使用redux中间件,主流是redux-thunk和redux-saga

react组件通信:

1.父组件可以通过props给子组件进行传参
2.子组件类似vue一样,用父组件传递一个方法,子组件通过props触发这个方法携带上参数
3.跨层级可以使用context或者使用redux或者Mobx进行通信
4.发布订阅模式,发布者发布事件,订阅者监听事件并作出反应,通过引入event模块进行通信

如何避免react中重新绑定实例(this指向)

1.使用箭头函数来定义方法
2.使用带有hook的函数组件
3.将事件处理程序需定义为内联箭头函数

如何避免React组件重新渲染

使用memo组件
使用pureComponent
都依赖props的浅比较,如果props没有改变组件就不会重新渲染,但是浅比较如果使用不当依旧会对性能产生负面影响,通过使用React Profilter确保方法使用前后对比有实际改进性能

受控组件和非受控组件的区别

受控组件是react控制中的组件,带有change时间,每次表单发生变更都会写入组件的state,
非受控组件是只需要用refs获取值,使用defaultvalue和defaultChecked来展示默认值
建议还是用受控组件,可以支持即时字段验证,条件禁用启用,强制输入格式

为什么类方法需要绑定到类实例

this根据当前上下文变化,在react类组件方法中,开发一般希望this引用当前的组件实例(call,bind,箭头函数)

react中strictMode

辅助组件,可以帮助我们编写更好的组件,使用strictMode包裹需要检查的组件,可以检查
1,是否遵循某些推荐语法,如果没有会在控制台报警告
2,.是否用废弃了的方法,
3识别潜在的风险预防一些副作用

useState ?

useState是内置的react hook, useHook(0)返回一个元组,其中一个参数count是计数器的当前状态,setCounter提供更新计数器状态的方法,可以在任何地方是用setCounter更新技术状态,并且可以在setCount函数内部做更多操作,使用hooks可以让代码保持更多功能避免使用太多基于类的组件

什么是hooks

1.16.8提出的,可以提取跨组件的有状态逻辑
2.可以在不编写类组件的情况下使用state和其他react特性
3.可以在不影响当前组件层级情况下重用有状态逻辑
好处:
1.可以提取和重用跨多组件的通用的有状态逻辑,不用承担高阶组件和渲染Props的负担
2.可以随意操作函数组件的状态,不需要更改为类组件
3.对类组件不起作用,可以避免使用生命周期componentUpdata,componentDidMount,可以使用内置钩子useEffect

React生命周期

componentWillMount 渲染前执行
componentDidMount 首次渲染后执行,一般用于请求ajax,更新dom,设置事件监听器
componentWillReceiveProps:首次render不执行,在组件接受到新props后触发,主要用于父组件更新子组件
componentWillUpdata:在shouldComponentUpdata返回true之后更新前执行
componentDidUpdata:主要用于更新dom以相应props和state更新
componentWillUnMount:用于取消ajax请求,删除与组件相关的事件监听器

为什么不直接更新state

setState建议传入一个新的值而不是直接修改原来的数据
如果直接使用this.state.xxx的方式去更改数据,并不会触发重新渲染
使用setState方法可以重新调度渲染方法
另外setState更新是异步的,react会将要修改的状态放到一个更新队列,并考虑到render次数,会考虑到render次数,会将多个值一起改变一次render
还有就是改变state的时候如果有其他地方也在改state,尤其是异步,可能会出现状态不同步

什么是高阶组件

高阶组件是接受一个组件并返回一个新组建的方法,是一种模式,也可以成为纯组件,可以接受任何动态提供的组件,不修改或复制输入组件中的任何行为

如何创建refs

refs是使用reat.creactRef()创建的,并通过ref属性附加到react元素,在构造组件时,通过将refs分配给实例属性,以便可以在整个组件中引用他们

什么是jsx

是js的一种拓展,跟模板语法类似,可以将html写在js中,但是jsx 不能给浏览器直接读取,必须使用babel和webpack进行编译转成js
通过createElement生成ReactElement对象,通过ReactElement构成对象树, 这个对象树就是虚拟Dom
jsx=>createElement函数=>ReactElement(对象数/虚拟dom)=>ReactDom.render=>真实dom

react怎么处理事件:

1.使用原生的onclick
2.addEventListener
3.bind,call更改onclick的绑定
4.箭头函数

函数式组件和类组件的区别

1.写法区别
2.类组件可以使用其他特性,如state和生命周期钩子
3.函数组件没有this可以访问props.只能通过形参props接收
4.类组件使用的时候要实例化,函数式组件直接执行函数取返回的结果就行,性能比类组件高

react中的事件是什么

在react中,事件是对鼠标点击,悬停,按钮等特定操作的触发反映.处理这些事件类似于处理Dom元素中的事件,但有语法差异:
1.用驼峰命名而不是单独的小写字母
2.使用函数传递而不是字符串
事件参数中包含一组特定事件的属性,每个事件类型都包含自己的属性和行为,只能通过其事件处理程序访问

何为state

和props类似,都是私有的由组件单独控制的,本质是一个持有数据,并决定组件如何渲染的对象

有状态组件和无状态组件

1.无状态组件主要用于定义模板,接受来自父组件props的数据,并将数据塞到模板里
2.有状态组件用来定义交互逻辑和业务数据,使用this.state把业务数据塞到组件实例上,然后传递props到展示组件,

render的目的
每个react组件都强制要求必须有一个render,.他返回一个react元素,是原生dom组件的标识

react中一切皆组件
React采用组件化的思想,最小的组件单位就是原生HTML元素,采用JSX的语法声明组件的调用
React的虚拟DOM,就是一个大的组件树,从父组件层到子组件,在render函数中层层堆叠
从react-router v4开始,路由本身也是组件
各个库提供的hoc返回的也是组件,如withRouter、connect
React中的基础数据state props的传递也是以组件为基础

Flux

是强制单向数据流的体系结构模式.
它控制派生的数据,并使用具有对所有数据的权限的中央存储实现多个组件之间的通信
整个应用程序中的任何数据更新都只能在此处进行
flux为应用程序提供稳定性并减少运行是错误

js面试题

原型链:

1.每个对象都有proto,这就是原型
2.另一个内部属性prototype,当对象被当成构造函数创建实例的时候,prototype就是这个实例的proto
3.当在对象找一个属性或者方法找不到的时候,就会往prototype上去找,如果也找不到,就会往proto关联的前辈protype上去找

作用域链

1.js中作用域只函数作用域,
2.全局的作用域无法访问内部的作用域,内部的可以访问全局的
3.当当前作用域找不到属性或方法时会向上一级找知道找到或者返回undefined

继承

1.构造函数继承:call,bind
2.拷贝继承
3.extend-class
4.将子类的prototype指向父的prototype
5.将子类的prototype指向父创建的实例

this

1.this总是指向函数的调用者
2.this收到当前上下文的影响
3.事件中this总是指向当前事件的触发者
4.如果有new,则指向new出来的实例

事件三阶段:捕获 目标 冒泡

事件委托就是将事件绑定到父类上,利用冒泡触发该事件

函数节流:

阻止一个函数在很短时间间隔内连续调用,只有当上个函数执行后达到一段时间才可以再次执行(重复请求,button多次点击)

防抖:

多次触发一个函数,只会执行一次.触发之后如果在一定时间有重新触发,那就重新计时(search)

js异步编程

async/await
回调函数
promise
事件监听

js创建对象

function
new
原型创建(prototype)

闭包

a函数包裹b函数,b函数中访问a函数的属性和方法.闭包可以突破作用域链,参数和变量不会被垃圾回收机制回收.使用不当会造成内存泄露

new

1.创建了一个空对象,this引用了该对象,继承了该函数的原型
2.属性和方法会被添加到该对象
3.隐式的返回this

同源

域名端口协议
跨域解决:proxy代理,后端处理

存储:

sessionStoragelocalStorage

sessionStorage是临时的,当会话关闭的话会被清楚
localStorage是永久的除非主动清楚否则会被保存

cookie和session

1.cookie有字段大小限制
2.没有封装好的remove和get,set方法
3.cooke存在客户端,seeison存在客户端
4.cookie不是很安全,cookie是在用户本地,可以分析进行cookie欺骗
5.seeison是存在服务器上,会暂用服务器性能

cookie和local
1.cookie有大小限制,本地更大
2.cookie每次请求都会带在请求头local不会
3.cookie设置有效时间一直有效,跟浏览器关闭无关
4.sessionStorage会话关闭会删除

渲染过程

1.解析html形成dom数,并下载css/js
2.解析css,构建css树
3.生成renden树
4.计算位置,绘制

js数据类型

基础类型:number.string,undefined,null.boolean
引用数据类型:array,object,function

js内置对象

数据封装类:Object,Array,Number,String,Boolean
内置:Math.Date,function,Argument,error
新增:set get proxy,symbol,map.promise,reflect

重绘回流

重绘,颜色之类的
回流:修改了宽度,排列,隐藏

简述bfc

1.bfc是一种环境,只包含其子元素,不包含其子元素的子元素
2.bfc可以用;来解决边距塌陷,浮动覆盖的问题,可以用来清除浮动的影响
3.满足条件:1.设置overflow,2.flex,3.table-cell4.body根元素5.设置浮动不包括none.6.行内块.7.定位:absolute或者fixed

缓存:

1.强缓存:用户发送的请求,直接从客户端缓存中获取,不发送请求到服务器,不与服务器发生交互行为。
2.协商缓存:用户发送请求,发送到服务器之后,由服务器判定是否从缓存中获取资源。

项目问题

1.element校验表单数组解决
在是数组的地方再套一个

<el-form :model="item" v-for="(item,index) in dataFields.list :key="index">
   <el-form-item label="name" prop="name" :rules="{ required: true, message: 'Required', trigger: 'blur' }">
      <el-input placeholder="name" v-model="item.name"></el-input>
   </el-form-item>
</el-form>

2.直接给list数组对象的字段名称绑定数组下的名称(修改prop绑定)

<div v-for="(item,index) in dataFields.list :key="index">
    <el-form-item label="name" :prop="`list[${index}].name`" :rules="{ required: true, message: 'Required', trigger: 'blur' }">
       <el-input placeholder="name" v-model="item.name"></el-input>
   </el-form-item>
</div>

3.不做element默认的表单校验,使用单独的校验


版权声明:本文为weixin_48601618原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。