React是什么
? react是一个基于js的框架,简单来说就是用于构建用户界面的JavaScript框架,就是一个用于渲染ui的js库 它使用高效 减少dom交互具有独立的语言jsx 能解决js的很多缺陷 es6的所有特性都包含 组件复用单向数据流的响应, react就是一个框架,我认为它相对于mvc来说只是其中的V 它适用于开发数据不断变化的大型应用程序,它高性能高效率,实现了前端页面的高性能高效率开发,所以说react很擅长处理组件化页面
什么是JSX
? JSX是一种JavaScript的语法扩展,可以很好的描述ui的架构.是React.createElement的语法糖.浏览器不能直接解析jsx文件,需要用bable进行转义成js
类组件和函数式组件之间的区别是什么?
相同点:它们都可以接收属性并且返回React元素.
不同点:
? 1.类组件需要创建实例,是基于面向对象的方式编程; 函数组件不需要创建实例,接收输入,返回输出,是基于函数编程的思想.
? 2.类组件需要创建并且保存实例,会占用一定的内存; 函数组件不需要创建实例,可以节约内存占用。
? 3.类组件有完整的生命周期; 函数组件没有生命周期.
? 4.类组件通过 shouldComponent和pureComponent跳过更新; 而函数式组件可以通过 React.memo跳过更新
? 5.类组件复用逻辑一般用HOC 函数式组件用 自定义hook
React中受控组件和非受控组件的区别
非受控组件:即组件的状态不受react控制的组件,
受控组件: 受控组件就是组件的状态受react控制,通过设置input的value属性,并且结合onChange事件 实时更新value即可
React组件的渲染流程是什么?
使用React.createElement 或 JSX 编写 React组件 , 实际上所有的JSX代码最后都会转换成React.createElement(…) , Babel帮助我们完成了这个转换的过程。
createElement函数对key 和 ref 等特殊的props 进行处理,并获取defaultProps对默认props进行赋值,并且对传入的孩子节点进行处理,最终造成一个ReactElement对象 (所需的虚拟dom)
ReactDom.render 将生成的虚拟DOM渲染的指定容器,其中采用了批处理,事务等机制并且对特定浏览器进行性能优化,最终转换为真实DOM.
原型和原型链的理解
原型 : 每个函数都有prototype属性,该属性指向原型对象,使用原型对象的好处是所有对象实例共享它所包含的属性和方法.
原型链 : 主要解决了继承的问题, 每个对象都拥有一个原型对象,通过–proto–指针指向其显示原型,并从中继承方法和属性,同时原型对象也可能拥有原型,这样一层一层,最终指向object object的原型对象执行null
React合成事件
为了解决跨浏览器兼容问题,React中的事件处理程序将SyntheicEvent实例,它是跨浏览器本机事件的浏览器包装器,这些综合事件具有原生事件一样的东西,只是就浏览器的工作方式不同.
React未将事件附加到子节点本身,而是将单个事件监听器在顶层监听所有事件,这样对性能有好处,意味React在更新dom时不需要担心事件监听器
React事件和原生事件的执行顺序是什么? 可以混用么?
React的所有事件都通过document 进行统一分发.当真实dom触发事件后冒泡到domcument后才会对React事件进行处理.
? 所以原生事件会先执行,然后执行React合成事件,最后执行真正在document上挂载的事件.
? React事件和原生事件最好不要混用.原生事件中如果执行了stop方法,则会导致其它React事件失效.因为所以元素的事件将无法冒泡到document上,导致所有的React事件都将无法被触发
虚拟dom比普通dom更快么?
其实说虚拟dom可以提升性能,这一说法我感觉很片面.
直接操作dom是非常耗费性能的,这个一点不可置疑,但是react使用虚拟dom也是无法避免操作dom的。
如果是首次渲染,虚拟dom其实不具有任何优势,甚至它还要进行更多的计算,消耗更多的内存.
虚拟dom的优势在于react的diff算法和批处理策略,react在页面更新直接,提前计算好了如何更新和渲染dom,实际上,这个计算过程我们在直接操作dom时,也是可以自己判断和实现的,但是一定会耗费非常多的精力和时间,而且往往我们自己做的是不如react好的,所以,在这个过程中,react帮助我们提升了性能.
? 所以,我更认为虚拟dom帮助我们提高了开发效率,在重复渲染时它帮助我们计算如何更高效的更新,而不是它比dom操作更快
高阶组件(HOC)和Mixin的异同点是什么?
Mixin 和 Hoc 都可以用来解决React代码复用问题
Mixin可能会相互依赖,相互耦合,不利于代码维护,
不同的Mixin 中的方法可能会相互冲突,
Mixin非常多时,组件是可以感知到的,甚至还要为其做相关处理,这样会给代码造成滚雪球式的复杂性.
而HOC的出现可以解决这些问题:
高阶组件就是一个没有副作用的纯函数,各个高阶组件不会互相依赖耦合,
高阶组件也有可能造成冲突,但我们可以在遵守约定的情况下避免这些行为
高阶组件并不关心,数据使用的方式和原因,而被包裹的组件也不关心数据来自何处.高阶组件的增加不会为原组件增加负担
react的生命周期执行顺序是什么?
实例期
constructor() 实例化
componentWillMount 组件将要被挂载
render 生产虚拟dom
componentDidMount 组件挂载完成
存在期
状态改变分为两种 state 和props
state改变时
shouldComponentUpdate 返回true 或 false 决定组件是否更新
componentWillUpdate 组件将要更新
render
componentDidUpdate 组件更新完成
props改变时 第一次不生效
componentWilReceiveProps 子组件接受父组件传递过来的属性
shouldComponentUpdate 返回true 或 false 决定组件是否更新
componentWillUpdate 组件将要更新
render
componentDidUpdate 组件更新完成
销毁期
compoentWillUnmount 组件卸载完成
redux是什么,怎么使用它?
? redux 是 react的一个状态管理库 将状态管理从react抽象出来了 ? 组件触发事件 ? dispatch发送一个actions ? 通过store 把当前状态的state和action 传给reducer ? reducer 返回一个新的state ? store 把新的state 传递给组件 触发更新
redux遵循的三个原则是什么
1.单一事实来源, 整个应用的状态存储在单个store中的对象/状态树中,单一状态树可以更容易地跟踪随时间的变化,并调试或检查应用程序.
2.状态是只读的:改变状态的唯一方法就是去触发一个动作,通过该动作去触发更改.
3.使用纯函数进行更改,为了指定状态树如果通过操作进行转换,就需要纯函数,c纯函数如何改变取决于传递的参数。
setstate是异步还是同步?
? setstate 在合成事件和生命周期中是异步的 在原生事件和 settimeout中是同步的
this.setstate什么时候同步?
? 在原生事件和 settimeout中是同步的, 只在合成事件和钩子函数是异步的
react的合成事件带来什么优势?
? 实现了一套高效的事件注册,存储,分发 和逻辑重用 在dom事件上有很大的改进, ? 减少了内存消耗,简化了逻辑,解决了浏览器的兼容问题 ? 合成事件就是react对js原生事件进行了封装 并挂载到了虚拟dom节点上 js原生事件挂载到真实dom节点上 在操作合成事件时 并不会对真实dom节点进行改变 也不会对整个系统造成影响
react里面是怎么进行通信的?
? 父子,子父,跨组件通信 ? 父子:父组件通过向子组件传递props 子组件通过prosp 进行接收 ? 子父:父组件将一个函数作为props传递给子组件 子组件调用该回调 ? 跨组件通信:使用context对象进行传参
react的生命周期怎么去优化项目?
? shouldComponentUpdate 通过对比dom是否发生改变 改变返回true 为改变返回false
react和vue之间有什么差异?
? react整体是函数式的思想 为单项数据流 vue的思想是响应式的 数据是可变的 ? react使用jsx将 html,css,js 放在一起写 vue是组合 在一起写 ? react是类式和函数式写法 api很少 vue是声明式的 传入的参数很多 ? react大部分代码需要自己封装 自由度很高 vue各项都封装完成了 自由度很低
redux-sage有用过吗?
? saga 是一个用于管理副作用或异步获取数据的插件 作用是让副作用管理更容易 通过创建 saga将异步操作收集到一起处理
除了redux-sage之外还会用什么去处理异步操作?
? redux-thunk redux-saga react-persist
redux-thunk怎么处理异步?
thunk将dispatch的参数从对象升级的函数 如果传递的是一个函数是,它就会对其进行拦截,直接变成为一个对象 才会进行下一步操作
介绍一下hooks?
hooks是专门为react的函数式组件使用的 它使函数式组件拥有props,state,context ref,和生命周期 且只能在函数式组件中使用 useState useEffeft useLayoutEffect useReducer useRef useContext usemeno useCallback
useEffect : 不会在浏览器前渲染 而useLayoutEffect 会
useLayoutEffect: 会在浏览器渲染结束后执行,useLayoutEffect则是在dom更新完成后,浏览器绘制之前执行。
自定义hooks怎么实现的?
自定义hook相当于一个高阶函数 但是必须以use开头 可以在自定义hook里面使用任意 hooks方法
React事件池
? 虚拟事件对象已经被合并.这意味虚拟事件对象将被重新使用,而该事件回调被调用之后所有属性将无效,这是出于性能的考虑。所以不能以异步的方式访问事件
? 如果想以一个异步的方式来访问事件属性,应该对事件调用event.persist() , 这将从事件池中取出合成事件,并允许该事件的调用,使代码被保留.
移动端和pc端都用react有什么区别? !!
https://blog.csdn.net/liuyingv8/article/details/7898298520.
https://www.jianshu.com/p/94ca5d1493b3
移动端开发和pc端开发所需要注意的问题?
? 技术角度 产品角度 策划角度 市场角度 ? https://www.zhihu.com/question/46307591?sort=created
后端是如何提供接口给前端联调调用?
? 首先,要弄清楚前端提供一个接口或者调用后台接口,那么这个接口具体指什么?网上用户上传图片作为头像这个需求需要后台人员处理,当用户登录 修改自己个人信息的时候,上传了头像。此时,后台处理该用户update个人信息,将该图片存入数据库,一般存的都是图片地址,string形式的数据。然后,要返回到前台的时候,后台人员需要对这些用户的个人信息进行处理,不只是头像,还有一些别的信息。后台通过语言编译,生成json格式的键值对(一般是json 还有xml txt 等数据格式)。生成一个地址也就是url,前台人员利用ajax,将返回的data显示到页面就好了。大体上来讲,接口一般指的是HTTP接口,也可以说是HTTP API。接口由后端提供,前端调用后端接口以获取后端数据。而且接口由URL和HTTP方法构成,URL为接口的地址,HTTP方法指的是GET, PUT, DELETE等等。
es6的箭头函数?
? 箭头函数没有自己的this,他的this永远执行其定义的环境,任何方法都改变不了其指向,比如call bind,apply 它也不能当做构造函数 没有原型属性 不能使用arguments 对象
你觉得箭头函数有什么优缺点?
? 没有自己的this,不能当做构造函数 不能new命令,没有原型 不能使用yield命令 不能用作Generator函数 不能使用arguments
vue和react的优缺点?
? react的优点 ? 它的性能会比较更强大,可以通过虚拟dom进行局部更新 ? 兼容性更好 轻松解决跨域问题 ? 单向数据流 跟原生的js差不太多 也有助于搜索引擎的优化 ? 但是它不是一个完整的框架 如果是一个大型的项目的话,就需要一些router,redux一些库的支持 ? vue的优点 ? 简单快速,数据的双向绑定和指令的使用让项目搭建的更快 ? 通过使用单页面应用程序 实现局部刷新 不会对整个系统产生任何影响 ? 但是由于它的双向绑定使用就l了object.defineProperty 不支持ie8 当state较多时 监听的属性多了会导致性能下降 所以一些比较大的 项目就不太适合使用
在项目中遇到跨域问题是怎么解决?
跨域是指浏览器不能执行其他网站的脚本,是浏览器对js实施的安全限制 JSONP 但是它只能支持get请求 CORS 后台来进行设置 一般在线上环境解决跨域问题 在vue和react中通过配置proxy来处理 Nginx反向代理 解决线上的跨域问题
react你的redux还是hooks?
? 具体用redux还是hooks还是要看项目的安排 有的时候比如在一个项目比较大的时候,数据操控比较多这时候就需要redux的使用,以保持数据在各个组件直接的连贯 ? hooks函数式组件比类组件项目搭建的时候更容易操作
redux是怎么使用的?
组件触发事件,事件通过dispatch发送一个actions 通过stote会把当前的state和actions发送给reducer reducer通过一系列的操作之后返回一个新的state store通知组件 触发更新
异步处理是在reducer里面操作吗?
不是 reducer是纯函数 是不能用来异步处理的
thunk和sage的原理?
thunk其实并不能解决异步 它只是赋予了它人解决异步的方法 sage是通过es6中新增的Generator函数 把一个异步的方法变成了同步去执行 把所有的异步操作放到一起去执行
除了redux-thunk和redux-sage有想过用其他的中间件?
redux-thunk redux-saga redux-proime
react里面的高阶组件是什么?
我认为高阶组件就跟高阶函数一样 高阶函数接受一个函数作为参数 返回一个新的函数 而高阶组件接受一个组件作为参数 返回一个新的组件 代表作品 拖拽
你觉得为什么react要使用hooks?
hooks就是让你不必写class组件就可以使用state和react特性,并且可以在自己编写的hooks不同组件复用 它可以让你的函数具有react的一些特定的功能 重写时不需要添加或删除state 使用useEffect代替生命周期 代码会更比较干净 在修改代码是 没有什么大的变化
你们之前会用immutable属性去管理仓库里的状态吗?
? immutable 可以将store中的数据封装成一个immutable对象 , 这个对象拥有get,set等方法 这样就可以通过这些方法对store中的数据进行管理 ? 使用时 就是使用其中的get方法将其获取出来 在使用其中的set方法 结合其中的对象值和设置之前的值,返回一个新的对象
如果让你自己实现一个发布者订阅者的方式,怎么去实现?
首先 何为发布-订阅模式 其定义对象间一种一对多的依赖对象,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知 https://www.jianshu.com/p/2ec316ca0f8b
localStorage模拟一个定时器?
? 正常情况下 它存入的值是永久使用的 前提是在不清除的情况下 所以我们需要在存取方面进行重新处理
let 和 var有什么区别吗?
? let定义的变量 只能在块级作用域访问,不能跨块访问 也不能跨函数访问、 ? vat 定义的变量,没有块的概念,可以跨块访问 不能跨函数访问 ? let 的用法类似于var 但是let只在所在的代码块内有效 所以我们一般使用let代替var
let 没有声明变量前 console.log 会报错,你知道是为什么吗?
? let声明的变量不存在变量提升
你知道箭头函数和普通函数有什么区别吗?
? 普通函数 中的this总是指向调用它的那个对象 箭头函数没有自己的this 它的this永远之前其定义的环境 ? 它不能当做构造函数 没有原型属性 不能用作Generater函数 没有arguments对象
flex 和 position 都有什么属性?
flex-direction 绝对主轴的方向 flex-wrap 是否换行 如何换行 flex-start起始位置对齐 flex-end结束位置对齐 flex-shrink 按照比例收缩 flex-grow 按照比例扩展 position absolute 绝对定位 相对于 父级定位 fixed 固定定位 相对于浏览器窗口定位 relative 相对定位 相对于其正常位置定位 static 默认值 没有定位
怎么去实现瀑布流儿布局?
? 什么是瀑布流布局 就是图片的宽度固定 长度不一样 当页面滚动时 会再次加载数据 动态渲染在页面上 ? 利用css3的属性来设置 column来设置行
移动端和pc端有什么复用的部分?
? 按照项目来区分吧 比如是轮播图,或者 图片的渲染 这些都可以通过复用来实现
如何去分装一个公共组件?
? 判断项目中那些东西需要复用 在components中新建一个文件 传递相对应的参数 进行封装
移动端的宽高单位怎么去做适配?
? 通过rem 进行适配 rem是相对长度的单位 可以做到一样的取值 在不同尺寸的屏幕 按照比例缩放 ? rem是相对于 根元素 font-size 计算的倍数 ? 适配的原理是 根据不同的屏幕宽度 以相同的比例动态修改html的大小适配 并将px换成rem 从而达到各种屏幕基本一样的效果体验
怎么自己去写一个适配效果?
? 首先需要先选定一个单位进行适配 然后需要根据根元素计算大小的倍数 同时要做到在不同尺寸的屏幕 按照比例缩放 从而达到每个屏幕大小基本一致
在项目里遇到的比较难的,计较有挑战的技术栈是什么?
? 我认为目前在我遇到的最有挑战的技术栈是react 因为react适用于做一些大型的项目 ,但是呢 react在做一些大型的项目的时候需要配置一些很重要的插件 但是我认为react的写项目时跟原生js相差不是很多 所以一些插件除了自行下载意外 还可以自行封装 做到在所有的组件中都可以使用 在react中 我认为有着很多的选择性 它的组件有类组件 有函数式组件 这些都可自行选择 在数据非常多的时候 可以选择redux 在解决异步时可以选择saga 而es6中新增的一些 函数 大多数都适用于react 所以在用react写项目时 不仅仅写出了项目 也提升了自己对新知识的增长
有没有做过给字体放大缩小的功能?
? 通过按钮 控制字体的大小 font-size
分段下载文件如何实现?
? http 实现文件分段下载 ? 整个过程分3步来完成 ? 1、uploadVedioMetaDataInfo ? 功能描述:上传视频metadata信息,metadata信息包括:md5、文件容量大小、文件名称。 ? 返回视频的上传信息: 如果正在上传,返回当前文件的进度;如果上传成功,返回文件的保存 url ,视频截图的尺寸、视频时长
? 2、getUploadVedioInfo ? 功能描述:获取文件的上传信息,如果正在上传返回当前文件的进度; 如果上传成功返回文件的 保存url,如果是视频返回视频时长,和截屏.
? 3、uploadFileByBlock ? 功能描述:分块顺序上传文件,最终返回视频时长、视频缩略图等信息(由于用户录制视频较 大,客户端播放很慢、卡,最终通过服务器异步压缩处理的方式解决体验)
有没有参与过项目的搭建?
? 搭配项目环境 ? 搭建项目目录 ? build 构建脚本目录 config 项目配置 node_modules 加载项目依赖模块 src开发的目录 ? index.html 入口文件 package.json配置文件 .md项目说明文档
如何选型技术栈?
? 可以根据技术选型,如果一个项目较大 数据流向和组件依赖数据较多 那么就建议使用 react ? 如果项目不是很大 项目也需要加急 数据虽然多但是 可以依靠组件解决 那么就可以使用vue来进行搭建
除了react mvvm 你还知道其他的框架吗?
vue mvc , angular mvp
分装aixos的目的是什么?
? api的统一管理 这样不管接口有多少,所有的接口都会非常清晰 容易维护 ? 在响应时统一处理状态码 也可以做一些权限的判断
webpack有哪些配置项?
? mode : 选择什么环境 ? entry:打包文件入口 ? output:指定打包后的资源位置 ? module: 配置各种loader ? plugins :[] ? devserve ? optimization 代码的分割配置
你是通过什么去学习一些前端的知识?
? 慕课网 早读课 哔哩哔哩web视频
举例说明块级元素和行内元素?
? 块级元素会独自占据一行 或者多行 ,可以任意设置其大小尺寸 是用于搭建网页布局的必须部分 ? 块级元素 li p div h1 table ? 行内元素 行内元素一般不能随意设置其宽高,对齐属性 常用于控制页面中文本的样式 ? 行内元素 a span sub sup i b
有哪些方法去实现居中?
? 弹性盒子 ? 定位 absolute + 负的margin ? 定位 absolute + transform
做过动画相关的样式吗?
? transition : translate 动画位置,duration 持续时间,delay:延迟多久,name:动画名称
animation 帧动画 : name:名称,duration 持续时间,delay:延迟多久
promise是干什么的?
主要用于解决异步,可以将异步操作队列化,按照期望的顺序执行返回符合预期的结果
promise内部有几个状态?
? 三个状态 pending resolve reject
? pending 实例创建时候的初始状态等待
? resolve 成功的状态 reject失败的状态
创建promise的时候,它的默认状态是什么?
? 默认状态是 pending 是为决定的状态 同一时间只能存在一种状态 且状态一旦改变就不能在变了
现在有十个任务,分别输出1-10,只能同时运行五个任务,按顺序执行,用promise怎么做?
可以使用 promise的then 一个一个链式执行
也可以将结果放到一个数组中 一个一个输出
原型链是什么?
原型链是原型对象创建过程的历史记录 当访问一个对象的某个属性时,会在这个对象本身属性上查找 ,如果没有找到,则会去他的__proto__原型上查找 ,即它的构造函数的prototpye ,如果还没有找到就会在构造函数的prototype的__proto__中查找如果还没有找到就会在构造函数的prototype的__proto__中查找 ,这样一层一层向上查找就会形成一个链式结构
假如给你一个对象,你用for in循环,它会把原型链给枚举出来吗?
首先要分清什么是可枚举属性,什么是不可枚举属性 他如何判断呢 由enumerable值决定了这个属性能否被for in 查找到
for in的键值会遍历原型链上的值吗?
使用for in 循环遍历对象的属性时 , 原型链上的所有属性都将被访问
移动端和pc端是怎么重构的?
pc端的重构要考虑的远远没有移动端那么多 最多有一些逻辑复用,公共组件的封装上面
移动端的重构要考虑的东西缺很多很多 比如 信息架构的重构 移动端不能像pc端那样将所有的功能都展示给用户 它只能展示一些主要的功能,一些次要的功能就需要放在下一层级,移动端的使用环境复杂多变,更容易受到干扰,所以必须保证界面信息的简单直观
媒体查询你分了几种适配?
@media 实现自适应的关键分辨率 768 992 120
typescript有使用过吗?它和javascript有什么区别?
首先呢 ts是js的一个超集
js是一种轻量型的脚本语言 可放在html页面中 也能在浏览器中运行 能在浏览器中交互 js是基于对象和事件驱动的 它的语法简单使用的变量为弱类型的
ts是一种面向对象的编程语言,是js的超集 包含了js的所有元素 可载入js之后运行 并扩展了js的语法 它添加了静态类型类 模块 接口 类型注解 可用于大型开发
https://www.jianshu.com/p/0dfbcd4a0757
typescript给你的项目带来了什么好处和便利?
静态类型的注入 渐进的类型系统 所有的类型注解都是可选的 比如说即是天使又是恶魔的any (被称为ts类型的漏洞) 支持结构子类型
也添加了代码的可读性和可维护性 ts非常的包容
typescript还会给你的项目增加工作量?主要体现在那个部分?
在定义接口、泛型、类,枚举类型 这几个方面 会多一些开发成本 毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,它们确能减少维护成本
https://www.jianshu.com/p/2116e39dd2ef
在你开发移动端和pc端的时候有遇到什么难解决的问题吗?
? 移动端
? new Date 在ios上值为nan的问题
? 安卓的部分机型在使用高度和行高来设置垂直居中中 会显示偏高的问题
? ios在h5页面会把数字 识别为电话
? iPhone的h5页面点击事件不生效
? 适配用rem十分的麻烦
pc端
? 高度塌陷问题 父元素的高度会被子元素撑开
? img底部的空隙问题 把img标签变成块元素
? 垂直居中问题 三个方法
? 文本溢出需要显示省略号
? margin的重合 累加 溢出问题
? 重合:上方元素margin-bottom:50px,下方元素margin-top:50px,间隙还是50px
? 累加 :左右盒子中间的margin值会累加,不会重合
? 溢出 :正常文档下 父元素没有边框没有定位没有浮动 子元素的margin-top会加到父元素上
你项目中的用户权限是如何做的?
通过登录是后端根据前端传递的参数生成token 前端把token进行存入 请求时携带 判断请求时是否携带token
token是从那个地方带入到接口里面的?
? 在请求时将token挂载到请求头上
你对webpack配置项有了解那些?
mode 开发环境 entry 打包入口文件 output 指定打包后自由位置
? module 配置各种loader plugins 一些额外的配置项
devServer 启动一个服务
es6的语法有了解吗?
let 声明变量 const 声明常量 解构赋值 数组,字符串扩展方法
箭头函数 类 模块化 import export rest promise async await
generator proxy
项目里面使用了那些ui框架?
iviw antd vant element
vue-router的动态路由?
在一个路由中设置路径参数 输入对应的值 就会到达对应的路由界面
rem的作用是什么?怎么使用?
根据不同屏幕的宽度,以相同的比例动态修改html的font-size 适配,并将px替换成rem,它可以很好的根据根元素的字体大小来进行变化,从而达到各种屏幕基本一致的效果体验
rem怎么做到适配的?
将手机屏幕 分成16份 每份设置 font-siez每份代表1rem
比如图是 750 750/16 = 46.875 1rem就是46.875
rem就是根据根元素的长度进行计算 得到屏幕适应的宽或高度
echarts怎么使用的?
? echarts 是一个纯js图表库依赖于轻量级的canvas 是一款优秀的可视化前端框架
? 引入echarts 根据数据绘制一个简单的图表
原生js获取dom元素有哪些?
通过id获取(getElementByid)
通过标签名(getElementByTagName)
通过类名(getElementByClassName)
通过name属性(getElementByName)
如何修改ui组件的样式?
就比如是element ui 样式
一种是通过添加 自定义样式
第二个是通过在选择器样式上加 /deep/ 实现 深度修改样式 适用于sass
另一个就是 选择器样式后 >>> 也可以实现深度修改样式 不适用于sass
路由传参params和query区别?
query传参类似于 axios的get 传参 params类似于 post传参
简单来说 前者浏览器地址栏显示参数 后者不显示
什么是单向数据流?
父级prop 的更新向下流动到子组件中 每次父组件更新时,子组件中所有的prop都将刷新为最新值
路由拦截是怎么做的?
比如说登录吧 没有登录或token失效 路由就不能跳转
在定义路由时多添加一个自定义字段 用于判断是否该路由的访问需要登录,如果已登录则进入路由否则就进入登录页面 在路由管理页面添加meta字段
然后通过beforeEach 进行拦截 在它里面进行判断是否需要登录
to是跳往哪一个路由 form是从哪一个路由来 new是执行函数
如何防抖和节流?
防抖是将多次高频操作优化为只在最后一次执行 一般在输入场景实现 封装一个函数 一直输入时,不执行此函数 停止输入多少秒后执行
节流:每隔一段时间后执行一次,也就是降低评率 一般在滚动时 或resize事件使用
? 定义一个时间 第一次请求后开始计算 直到时间流完 才能继续下一次请求 时间没有流完,则不能下一次请求
有遇到什么兼容问题吗?
浏览器的兼容问题 浏览器的种类不同 内核也不同 要想所有浏览器都能使用 就要解决浏览器兼容
获取滚动条距离 也有两个方法也要处理兼容
var sTop=document.documentElement.scrollTop || document.body.scrollTop;
网页可视区兼容
window.innerHeight || document.documentElement.clientHeight
window.innerWidth || document.documentElement.clientWidth
事件对象 var e = event || window.event
获取事件源/事件目标对象 e.target || e.srcElement;
6.获取键盘信息 e.keyCode || e.which
react里的defaultProps是干什么的?
给组件props设置默认状态 只能被调用一次
defaultProps和getlnitialState执行的先后顺序?
defaultProps 设置props的默认值值 对每一个实例化组件只执行一次
getlnitialState设置state值 每一个组件只有一个state 只会被调用一次
什么是闭包
闭包是指有权访问另一个函数作用域中的变量的函数
作用:使用闭包可以访问函数中的变量,可以使变量长期保持在内存中,生命周期比较长
缺点:闭包不能滥用,否则会导致内存泄露,从而影响网页性能
一般用在函数作为参数传递,函数作为返回值
为什么要使用虚拟dom
? 因为如果每次都操作真是dom的话,真实dom的体积非常大 从而导致页面重绘,当然使用虚拟dom也是为了对比虚拟dom和真实dom的区别
在浏览器地址栏输入url,按下回车之后会经历以下哪些流程
DNS 解析 (浏览器向DNS服务器请求解析该url中的域名所对应的ip地址)
建立TCP连接 (握手)
发送请求 分析url 设置请求报文
服务器返回请求的文件
释放tcp链接
浏览器渲染html
vue数据驱动的原理
vue的数据驱动的是视图也就是dom元素让dom的内容随着数据改变而改变
我的理解就是通过控制数据的变化来改变某物或某事
mvvm和mvc的区别
mvc的全名是 Model View Controller
m是模型 model v 是view视图 c是controller 控制器
是一种设计规范 一种业务逻辑,数据,界面显示分离的组织代码
mvvm是 Model-View-ViewModel的简写
m 模型 代表真实状态内容的模型
v 视图 用户在屏幕上看到的结构 布局
v 视图模型
m 绑定器
优点 :低耦合,可重用性 独立开发 可测试
区别 mvvm 采用双向绑定控制 view的更新 让开发者不用在处理接收事件和view更新
mvc view访问数据需要在model 访问 但是不建议在view依赖model
如何创建自定义指令,自定义指令的目的是为了什么,写一个自定义指令
vue中内置了许多指令,当这些指令无法满足我们的需求的时候,或我们想加一些特别的功能的时候,就需要写一个自定义指令了
自定义指令分为 全局的和局部的 directive 和 directives
Vue 中的 key 有什么作用,key的原理是什么?
key是唯一标识 依靠key能够在diff算法执行时更快的找到对应的标识,提高diff算法
key具有唯一性 它的作用就是更新组件时判断两个节点是否相同,相同就复用,不相同就删除旧的
vue首页白屏是什么问题引起的?如何解决呢?
vue首页加载过慢,其原因是因为它是一个单页面应用,需要将所有需要的资源都下载都浏览器端并解析
解决方法 : 按需加载 加载时添加一个loading提高用户体验
页面刷新后vuex的state数据丢失怎么解决
将vuex里面的数据同步到本地存储中
vue中data的属性可以和methods中的方法同名吗?为什么?
不可以 vue会把method和data的东西,全部代理到vue生成对象中
会产生覆盖 所有最好不要同名
受控组件和非受控组件
每当表单的状态发生变化时,都会被写入组件的state中,每当表单的值发生改变时,调用onChange
非受控组件就是 没有value 它的值不受state和props的控制
什么dns,它是如何缓存的
dns 是域名系统 是internet上解决网上机器命名的一种系统 就比如说当拜访朋友时首先要知道朋友家怎么走一样,interner上当一台主机要访问另外一台主机的时候,必须要知道其地址,但是它的地址是由很多段数字组成的,记起来总是不如名字那么方便,所以就采用了域名系统来管理名字和ip的关系
js数据类型及如何判断
typeof 判断数据类型
instanceof 判断对象类型
object.prototype.toString.call() 是最准确最常用的方法
如何实现浅拷贝与深拷贝
浅拷贝:它只是复制指向某个对象的指针,而不复制其对象本身,新旧对象还是同一个对象 修改新对象 原对象也更改
方法:直接赋值,concat object.assign 扩展
深拷贝:在拷贝数据时,将所有的引用类型都拷贝一份,简单来说就是目前内存中存在两个数据结构完全相同又完全独立的数据,修改新对象 原对象不会在受任何影响
方法:json - parse stringify 利用递归实现
箭头函数设计时为什么不能使用 arguments
箭头函数没有自己的this 其this来源于它的上文执行环境,当使用arguments时就会把arguments当做一个普通的变量
怎么实现双飞翼布局和圣杯布局
这两个布局都是针对 三栏布局 左右栏固定 中间栏自适应的网页布局
左右侧 固定高度 中间的元素自适应
css3的动画、过渡
过渡 :transition 是元素从一种样式逐渐改变为另一种的效果
动画:animation 指定一个css样式 和动画 将逐步从目前的样式更改为新的样式
DOM 事件流和事件委托
dom事件就是:程序各个组成部分之间的一种通信方式,也就是js和html的交互基础,任何事件或于浏览器发生交互都要统过绑定事件进行交互
dom的事件流就是描述从页面接收事件的顺序,也可以理解为事件在页面中传播的顺序,它分为捕获和冒泡
事件捕获阶段:事件从最上面一级一级往下找,直到找到事件目标
事件冒泡阶段:事件从事件目标开始自下而上的冒泡到最上一级的标签
事件委托:也可以叫做事件代理 事件会在冒泡阶段向上传递到父节点,因此可以把子节点的监听函数定义到父节点上,由父节点的监听函数统一处理多个子元素的事件
解释下BFC
BFC 是页面中的一块渲染区域,并且它还有自己的渲染规则,它能决定其子元素的如何定位,也能决定其他元素的关系
它就可以看做隔离了的独立容器,容器里面的元素不会影响外面布局的元素,它还具有普通容器没有的特性 , 简单理解就是bfc就是一个封闭的大箱子,无论箱子里的元素
怎么翻江倒海都不会影响到外部
单页面应用和多页面应用
单页面应用技术说:只有一个主页面的应用,浏览器最开始就需要加载所有的HTML,css,js,所有的内容都包含在这个主页面里面,只是写的时候是分开写而已,
单页面应用用户体验好,内容的改变不需要加载整个页面,对服务器的压力较小,前后端分离,可以设置一下比较炫酷的切换动画
缺点就是,初次加载时,耗时比较多,但是可以用一些数据加载方式解决,页面的复杂度也提高了很多
多页面应用:就是指一个应用中有多个应用,页面跳转时整页刷新
nodejs跨域在哪里设置
两种跨域方式 (jsonsp,cors)
jsonp 但是它只能使用get 请求 post请求则会报错
cors 实现跨域 在头信息之中,添加一个 值 服务器根据这个值决定是否同意这次请求,cors 跨域,前端不需要任何改变,就是普通的请求,只是后台每次返回信息的时候,添加一个header即可
怎么防止接口数据泄露
可以在请求接口时携带一个token ,没有token自然就无法请求接口,数据就不会随意泄露, 也可以对所以的请求和响应都进行加解密操作
重绘和回流
回流:当dom树中的一部分或全部,因为元素的规模尺寸,布局,隐藏,而改变时需要重新构建,这就叫回流,每个页面在第一次加载时都需要
重绘:当dom树中的一些元素需要更新属性时,这个属性只影响外观,风格,而不影响布局,这就叫重绘
回流必将引起重绘,重绘不一定引起回流
h5有哪些新特性
可以用来画图的canvas , 多媒体元素 audio video 语义化标签 headr,nav,section,footer,main , 本地存储 应用程序的缓存 离线浏览,速度,减少了服务器负荷
盒模型
盒模型的组成 , 由内向外 content , padding , border,margin
ie盒模型中 content , padding , border,
w3c是 content , padding , border,margin
css的margin塌陷问题
塌陷是由两盒子的最大外边距为准
嵌套关系
解决方法:
1.为父盒子设置border,为外层添加border
2.给父盒子添加一个overflow:hidden;
3.为父盒子添加position:fixed;
4.为父盒子添加 display:table
css的预处理器
sass,scss,less,stylus
预处理的常用功能,变量、代码混合,嵌套,并且有利于模块化开发
js的事件模型
1.dom0级事件模型 是最早的事件模型 所有的浏览器都支持,这种事件模型容易理解,是唯一的,但是后面的事件会覆盖前面的事件
2.dom2事件模型 这种事件模型是捕获和冒泡模型,一个事件要先捕获到,在执行冒泡
作用域
在js中分为全局作用域和函数作用域
全局:在任何地方都是被访问,window对象的内置属性都拥有全局作用域
函数:在固定的代码片段才能被访问,它有上下级关系,就看是在哪个作用域下创建,它最大的好处是隔离变量,不同的作用域 同名变量不会起冲突
import和require的区别
他们两个都是模块化使用
require是amd规范化引入方式
import是es6的一个语法标准 如果要兼容浏览器的话必须转换成es5语法
require是运行时调用 可以运用在任何地方,import是编译时调用,必须放在文件开头
require 赋值过程 就是把require的结果赋值给某个变量,import是结构过程
模版字符串
模版字符串是增强版的字符串,用反引号标识,它可以当做普通字符串使用,也可以定义多行字符串,或者在字符串中嵌入变量
对象的解构赋值
解构赋值时允许交换值,可以在函数中返回多个值
事件的绑定方式
1.在构造函数中使用bind绑定this
2.在调用的时候使用bind绑定this
3.在调用是使用箭头函数绑定this
display:none 和 visibility:hidden的区别
display:none隐藏后元素不占据任何空间,
visibility:hidden 隐藏后元素的空间依旧保留,并且它具有继承,父元素设置属性子元素会继承 而display:none 时直接携带所以元素统一隐藏,并且它还支持transition,display就不支持 所以visibility就可以配合 transition使用纯css实现hover延迟显示效果,提高用户体验
vue的路由懒加载
1.vue异步组件技术 异步加载
vue-router 配置路由 使用vue的异步组件技术 可以实现按需加载
通过require的方式、但是会生成一个js组件
2.路由懒加载 (import)
const 组件名 =()=>import (组件路径)将每个组件打包成一个js文件
3.vue-router配置路由 使用webpack的require.ensure技术也没实现按需加载 这样会将所有路由打包成一个js文件
r
o
u
t
e
r
和
router和
router和route的区别
r
o
u
t
e
r
为
v
u
e
?
r
o
u
t
e
r
实
例
,
想
要
导
航
到
不
同
的
u
r
l
则
使
用
router为 vue-router实例,想要导航到不同的url 则使用
router为vue?router实例,想要导航到不同的url则使用router.push方法
$route 为当前router跳转对象里面可以获取name,path,query,params
vue发送请求的方式
1.vue-resource(官方提供的一个插件)
? 在main.js引入并挂载到use上 页面上直接this.$http使用即可
2.axios 引用+使用 (在哪文件用就在哪引入即可)
3.fetch.jsonp(引用:同axios一样在哪文件用就在哪引入)
fetch是干什么的
fetch被称为上一代ajax的技术,采用promise 方式来处理数据,比XMLHttpRequest更加简单易用
页面中需要向服务器请求数据,基本上都会使用ajax来实现,ajax的本质是使用XMLHttpRequest对象来请求数据,而XMLHttpRequest对象是通过事件的模式来实现返回数据的处理
与XMLHttpRequest类似,fetch允许你发出请求
区别在于fetch API 使用promise方式 是已经正式发布的es6的内容之一,因此是一种简洁明了的api,比XMLHttpRequest更加简单易用
阻止冒泡
e.stop() event.stopPropagation()
vue与react虚拟dom对比
vue和react都采用了虚拟dom算法,以最小化更新真是dom ,从而减少不必要的消耗,
区别就在与 dom的更新策略不同吧,
react 会自顶向下的全部diff
vue会跟踪每一个组件的依赖关系,从而不在需要重新去渲染整个dom树
1.在react中,当状态发生改变的时候,组件数就会自顶向下的获取所有diff,重新render页面,重新生成新的虚拟dom树, 然后新旧dom树进行对比, 从而局部更新dom。当react为了避免父组件更新从而引起不必要的子组件更新,可以在shouldComponentUpdate 做逻辑判断,减少没必要的render,以及重新生成虚拟dom,做对比过程
2.在vue中,通过Object.defineProperty 把这些data属性 全部转为getter/setter.同时实例对象会在组件渲染时,将属性记录为dep,当dep项中的setter被调用时,通知watch重新计算,使得关联组件更新,
diff算法 借助元素的Key 判断元素是新增,删除,修改, 从而减少不必要的元素渲染
Vue中常用的插件或组件
ui插件 element iview 滚动插件 mescroll 图表插件 vue-table
播放器插件 vue-video-player vue的一个视频及直播播放器
vue的百度地图插件 vue-baidu-map
谈谈对sync的理解
假如父组件传给子组件的的值,子组件接收之后,想要改变父组件传过来的值,就可以使用sync .sync是vue中用于实现简单的’'双向绑定"的语法糖,在平时的开发中是可以经常使用的
vue的prop是单向下行绑定:父级的props的更新会向下流动到子组件,但是反过去不行,可是有些情况,我们需要对props进行’双向绑定’,这个时候,就可以使用sync解决
cookie,sessionStorage和localStorage的区别
cookie 是网站为了标识用户身份而存储在用户本地存储上的数据,cookie还可以设置有效时间.
cookie始终在同源的http请求中携带 可以在浏览器和服务器间来回传递
sessionStorage和localStorage 不会自动把数据发给服务器 仅在本地保存
区别存储大小:
? cookie 数据大小 不能超过4k
? sessionStorage和localStorage 虽然也有存储大小的限制 但是比cookie大得多 可以达到5m 或更大
有效时间 :
? localStorage 存储持久数据 浏览器关闭后数据不丢失 除非数据主动删除
? sessionStorage 数据在当前浏览器窗口关闭后自动删除
? cookie 设置的cookie 过期时间之前一直有效 即使窗口或浏览器关闭
迭代器和生成器的区别
1.生成器本质是一个函数,它记住了上一次返回时在函数体中的位置,对生成器函数的第二次调用,跳转到函数上一次挂起的位置,而且记录了程序执行的上下文,生成器不仅记住了它的数据状态,也记住了它执行的位置
2.迭代器是一种支持next()操作的对象 ,它包含了一组元素,执行next()操作时,返回其中一个元素.当所有元素都返回时 在执行报异常
生成器一定是可迭代的,也一定是迭代器对象
3.区别:
生成器是生成元素的,迭代器是访问集合元素的一中方式
迭代输出生成器的内容,迭代器是一种支持next操作的对象
css3里面的内置函数
rgb() rgba() rotate() rotate3d() scale() translate()
前端页面代码层面的优化
1.合理使用v-if和v-show
2.合理使用watch和computed
3.使用v-for 必须添加key,最好为唯一id,避免使用index , 且在同一个标签,v-for不要和
v-if同时使用
4.定时器的销毁,可以在beforeDestroy()生命周期内执行销毁事件,也可以使用$once这个事件监听器,在定义定时器事件的位置来清除定时器
diff算法
1.虚拟dom中采用的算法
2.把树形结构按照层级分解,只比较同级元素,不同层级的节点只有创建和删除操作
3.给列表结构的每个单元添加唯一的key属性,方便比较
4.react只会匹配相同class名的component (这里的class指的是组件的名字)
5.合并操作,调用component的setState方法的时候,React将其标记为dirty 到每一个事件循环结束,react检查所有标记 dirty 的 component重新绘制
6.选择性子树渲染,开发人员可以重写 shouldComponentUddate 提高diff的性能
RBAC是什么
RBA是基于角色的访问控制,在RBAC中,权限与角色相关联,用户通过成为适当角色的成员得到这些角色的权限。这就极大地简化了权限的管理,这样管理都是层级相互依赖的,权限赋予给角色,而把角色有赋予用户,这样的权限设计很清楚,管理起来很方便
transition 和 animation 的区别
? 他们大部分属性都是相同的,都是随着时间改变元素的属性值,主要的区别是transition需要触发一个事件,而animation不需要触发任何时间的情况随着时间改变属性值 , 并且transition 为2帧 从from…to 而animation 可以是一帧一帧的
visibility:hidden和display:none和opacity:0和z-index:-1的区别
opacity:0 该元素隐藏起来了,但是不会改变布局,并且如果该元素绑定了一些事件 那么点击该区域,也能触发该事件
visibility:hidden 该元素隐藏起来了,不会改变布局,但是也不会触发已经绑定的事件,
display:none: 把元素隐藏起来了,并且改变页面布局,就可以理解为在页面中把元素删除了一样
z-index:-1 ; 将元素覆盖在下面
Real DOM 和 Virtual DOM 的区别(真实dom和虚拟dom的缺点)
Real DOM:1.更新慢、2.可以直接更新html 、3.如果元素更新,则直接创建新的dom、4.dom操作代价很高 、5.消耗的内存较多
Virtual DOM:1.更新更快 、2.无法直接更新HTML、3.如果元素更新,则更新jsx、4.DOM操作非常简单 5.很少的内存消耗
getters和methods,computod的区别
? 调用方式不同,computod和getters都是计算属性,有缓存 他们是以对象属性方式直接调用,而methods必须要函数执行才能得到结果,却它没有缓存
AB两个dom元素,怎么找到他们最近的父节点
parentNode
for in 和 for of 的区别
for in 遍历的是数组的索引 (即键名) for of遍历的数组元素值
通常for in 遍历对象 for of 遍历数组
将vue和react做对比,怎么看待这两个框架
从设计方法上来说: 存在一些区别
vue直接改变状态,这样有一些好处,我们可以随心所欲的想写代码就写代码,很多人都喜欢这样的方式,但对于我们来说,我们会做一些transition,vue和react就有很大的差异,是两种完全不同的方向。 vue可能是基于50年的编程沉淀,对于我们来说基于我们自己的做法,当然他们的做法在技术上来说也是很棒的,vue更多会用一些实用的技术解决实用的问题,比如提供更加便利的动画的解决方案,更便利的模版,但是对于react来说,我们不想去做一些我们没有办法充分相信的解决方案,所以我们给出的东西可能没有那么直接便利,比如我们想做动画功能,我们并不会去标准化一些存在的东西,我们会有自己对动画的想法,这跟很多框架都是不一样的,vue可以更快的拿到你所想要的,react我们有更丰富的库,我们就可以学会怎么去做这些事,这就像安卓和ios一样,ios其实很多功能都不包括,但是他可以帮助你更好的完成一些事情.
new操作符都做了些什么
创建了一个空对象
将空对象的proto属性指向它的原型
改变this指向
检查返回值
常见的状态码
200 :成功 、300:重定向 304 资源为资源未修改 305 需代理访问
400: 请求错误 401 要求身份验证 403 拒绝请求 404 资源不存在 500 服务器错误
1** 服务器收到请求 需要请求者继续执行操作
2** 操作成功
3** 重定向 需要进一步的操作已完成请求
4** 客户端错误 , 请求包含语法或无法完成请求
5** 服务器错误 , 服务器在处理请求的过程发生了错误
PureComponent
shouldComponentUpdate可以控制render函数是否调用 它返回false不调用render 假如state和props并没有改变,那么调用render,执行diff运算就没有任何意义,所以当state和props没有改变时返回false,就不用render调用了, 如果 在react中引用了PureComponent概念 它会在render之前对state和props进行比较,若state和props都相同,则不会render 这个浅比较是在shouldComponentUpdate中进行的,所以使用了PureComponent就不需要在使用shouldComponentUpdate,因为会覆盖默认的钩子函数
PureComponent不能使用shouldComponentUpdate周期,会报错。
数据双向绑定的原理
? 数据双向绑定是用数据劫持和发布-订阅模式来实现双向绑定的方式,通过object.defineProprety 这个方法来劫持各个属性的setter和getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图
? 第一步:需要(observer)观察者对数据对象进行遍历,包括子属性对象的属性,都加上setter和getter。 这样的话在给这个对象的某个值赋值,就会触发setter,就能监听数据的变化
? 第二步:(compile)解析指令,将模版中的变量替换成数据,然后初始化渲染视图,根据指定节点更新函数,添加用来监听的订阅者,这样一旦数据变动,就会收到通知,更新视图
? 第三步:watcher作为通信的桥梁 先在实例化时往上添加属性订阅器,调用update的方法触发绑定的回调
? 第四步:mvvm作为数据绑定入口 , 整合observer和compile和watcher 首先通过objserver监听自己的数据变化,在通过compile 解析模版命令 然后通过watcher搭建起observer和Compile之间的通信 这样来达到数据的双向绑定
js 执行机制-eventloop
? 想到eventtloop 就想到了异步 为了避免dom的渲染冲突 ,js是单线程的,也就是同一时间只能做一件事,异步就解决js单线程,让同步先执行,等一段时间在执行异步
? eventloop就是js异步的体现,同步进入主线程,异步进入eventloop中等待
? 主线程的任务执行完毕,异步在进入主线程进行执行,先执行微任务,在执行宏任务,
? 微任务有:promise,nexttick 宏任务有 :settimeout setinterval
? 这些就是eventloop
$nextTick
? 在dom更新循环结束之后执行延迟回调,在修改数据之后使用$nextTick,则可以在回调中获取更新后的dom, 简单理解:当数据更新了,在dom中渲染后,自动执行该函数
使用场景:
? 当项目中你想在改变dom元素的数据之后基于新的dom做点什么,对新dom的操作都需要放到nexttick中, 通俗理解:更改数据之后当你想立即使用js操作新的视图的时候就需要使用它.
项目优化的方式
分为三种 代码层面 webpack配置层面 技术层面
代码层面 :
区分v-if和v-show使用场景 、合理使用 computed 和 watch 、v-for时遍历时添加key值 同时避免v-if 、长列表优化 object.freeze冻结一个对象 这样就不会在修改了、事件销毁、图片懒加载,路由懒加载、第三方插件的按需引入、优化无限列表性能 当应用中存在无限滚动的列表时使用上拉加载
webpack:
? 对图片进行压缩、减少es6转为es5的沉余代码、提取公共代码、模版预编译
技术层面:
? 浏览器缓存 、cdn的使用 :浏览器从服务器上下载css,js, 图片 要与服务器连接,服务器的宽度有限,如果超过了限制,网页就半天反应不过来。csdn可以通过不同的域名来加载文件,从而使下载文件的的连接大大增加,cdn有更好的可用性和更低的网络延迟和丢包率
Vue的响应式系统
? Vue为MVVM框架,当数据模型data变化时,页面视图会得到响应更新,其原理对data的getter/setter方法进行拦截(Object.defineProperty或者Proxy),利用发布订阅的设计模式,在getter方法进行订阅,在setter方法中通知,让所有订阅者完成响应
? 在响应式系统中,Vue会为数据模式data的每一个属性新建一个订阅中心作为发布者,而监听器watch、计算属性computed、视图渲染template/render三个角色同时作为订阅者,对于监听器watch,会直接订阅观察监听的属性,对于计算属性computed和视图渲染template/render,如果内部执行获取了data的某个属性,就会执行该属性的getter方法,然后自动完成对该属性的订阅,当属性被修改时, 就会执行该属性的setter方法,从而完成该属性的发布通知,通知所有订阅者进行更新.
Computed与watch的区别
? 计算属性computed和监听器watch都可以观察属性的变化从而做出响应.不同的是:
? 计算属性computed更多是作为缓存功能的观察者,它可以将一个或者多个data的属性进行复杂的计算生成一个新的值,提供给渲染函数使用,当依赖的属性变化时,computed不会立即重新计算生成新的值,而是先标记为脏数据,当下次computed被获取的时候,才会进行重新计算并返回.
? 而监听器watch并不具备缓存性,监听器watch提供一个监听函数,当监听的属性发生变化时,会立即执行该函数.
为什么data必须是一个函数
? 一个组件可能在很多地方使用,也就是会创建很多个实例,如果data是一个对象的话,对象是引用类型,一个实例修改了data会影响到其他实例,所以data必须使用函数,为每一个实例创建一个属于自己的data,使其同一个组件的不同实例的不同实例互不影响
vue组件之间的传值?
父传子: 父组件向子组件传递参数 子组件通过props接受
子传父: 父组件
o
n
子
组
件
on 子组件
on子组件emit接收
兄弟组件: Event Bus: $on 推送事件 $emit接收事件
? Vuex:将状态和方法提取到vuex 完成共享
跨组件传参: 使用provide/inject provide 提供参数 inject接收参数
? Vuex:将状态和方法提取到vuex 完成共享
Vue事件绑定原理
? 每一个Vue实例都是一个Event Bus, 当子组件被创建的时候,父组件将事件传递给子组件,子组件初始化的时候是有
o
n
方
法
将
事
件
注
册
到
内
部
,
在
需
要
的
时
候
使
用
on方法将事件注册到内部,在需要的时候使用
on方法将事件注册到内部,在需要的时候使用emit触发函数,而对原生native事件,使用addEventListener绑定到真实dom元素上.
slot是什么? 有什么作用? 原理是什么?
? slot又名插槽 , 是Vue的内容分发机制,组件内部的模版引擎使用slot元素作为承载分发内容的出口.插槽slot是子组件的一个模版标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决定的.
? slot又分三类, 默认插槽,具名插槽和作用域插槽.
? 默认插槽: 又名匿名插槽,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有一个匿名插槽
? 具名插槽: 带有具体名字的插槽,也就是带有name属性的slot,一个组件可以出现多个具名插槽.
? 作用域插槽: 子组件在渲染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件传递过来的数据决定如何渲染该插槽
? 实现原理: 当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm.
s
l
o
t
中
,
默
认
插
槽
为
v
m
.
slot中,默认插槽为vm.
slot中,默认插槽为vm.emit.default , 具名插槽为vm.
s
l
o
t
.
插
槽
名
,
当
组
件
执
行
渲
染
函
数
时
候
,
遇
到
s
l
o
t
标
签
,
使
用
slot.插槽名, 当组件执行渲染函数时候,遇到slot标签,使用
slot.插槽名,当组件执行渲染函数时候,遇到slot标签,使用slot中的内容进行替换,此时可以为插槽传递数据,若存在数据,则可称该插槽为作用域插槽.
Vue模版渲染的原理是什么?
? vue中的模版template无法被浏览器解析并渲染,因为这不属于浏览器的标准,不是正确的html语法,所有需要template转化成一个JavaScript函数,这样浏览器就可以执行这一个函数并渲染对应的html元素,就可以让视图跑起来,这一个转化过程,就称为模版编译.
? 模版编译有分为三个阶段,解析(parse),优化(optimize),生成(generate),最终生成可执行函数render.
? parse阶段:使用大量的正则表达式对template字符串进行解析,将标签,指令,属性等转化为抽象语法书AST
? optimize阶段:遍历AST,找到其中的一些静态节点并进行标记,方便在页面重渲染的时候进行diff比较时,直接跳过这一些静态节点,优化runtime的性能
? generate阶段: 将最终的AST转化为render函数字符串
template预编译是什么?
对于Vue组件来说,模版编辑只会在组件实例化的时候编译一次,生成渲染函数之后在也不会进行编译.因此,编译对组件的runtime是一种性能损耗
而模版编译的目的仅仅是将template转化为render function , 这个过程,正好可以在项目构建的过程中完成,这样可以让实际组件在runtime时直接跳过模版渲染,进而提升性能,这个项目构建的编译template的过程,就是预编译.
template和jsx有什么区别
? 对于runtime来说,只需要保证组件存在render函数即可,而我们有了预编译之后,我们只需要保证构建过程中生成render函数就可以.
? 在webpack中,我们使用vue-loader 编译.vue文件,内部依赖的vue-template-compiler模块,在webpack构建过程中,将template预编译成render函数
? 与react类似,在添加了jsx的语法糖解析器babel-plugin-transform-vue-jsx之后,就可以直接手写render函数.
? jsx相对于template而言,具有更高的灵活性,在复杂的组件中,更具有优势,而template虽然显得有些呆滞.但是template在代码结构上更符合视图与逻辑分离的习惯,更简单,更直观,更好维护.
说一下Virtual DOM
? Virtual DOM 是dom节点在JavaScript中的一种抽象数据结构,之所以需要虚拟dom,是因为浏览器中操作DOM的代价比较昂贵,频繁操作dom会产生性能问题。虚拟dom的作用是在每一次响应式数据发生变化引起页面重新渲染时,对比更新后的虚拟dom,匹配找出尽可能少的需要更新的真实dom,从而达到提升性能的目的.
介绍一下Vue中的Diff算法
在新老虚拟dom对比时:
? 首先,对比节点本身,判断是否为同一节点,如果不为相同节点,则删除该节点重新创建节点进行交换.
? 如果为相同节点,进行patchVnode,判断如何对该节点的子节点进行处理,先判断一方有子节点一方没有子节点的情况(如果新的children没有子节点,将旧的子节点移除),比较如果都有子节点,则进行updateChildren , 判断如何对这些新老节点的子节点进行操作(diff核心) 匹配时,找到相同的子节点,递归比较子节点
? 在diff中,只对同层的子节点进行比较,放弃跨级的节点比较,使得时间复杂度降低了很多,也就是说,只有新旧children都为多个子节点时才需要用核心的Diff算法进行同层级比较
key属性的作用是什么
? 在对节点进行diff的过程中,判断是否为相同节点的一个很重要的条件是key是否相等,如果是相同节点,则会尽可能的复用原有的dom节点.所以key属性是提供给框架在diff的时候使用的,而非开发者.
Vue2.0和Vue3.0有什么区别
1.重构响应式系统,使用proxy替换object.defineProperty,使用Proxy优势.
? 可直接监听数组类型的数据变化,
? 监听的目标为对象本身,不需要像object.defineProperty一样遍历每个属性,有一定的性能提升.
? 可拦截apply,ownKeys,has等13种方法,而object.defineProperty不行
? 直接实现对象属性的新增/删除
2.新增Composition API 更好的逻辑复用和代码组织
3.重构了Virtual DOM
? 模版编译时的优化,将一些静态节点编译成常量
? slot优化,将slot编译为lazy函数,将slot渲染的决定权交给子组件
? 模版中内联事件的提取并重用(原本每次渲染都重新生成内联函数)
? 4.代码结构调整,更便于 Tree shaking,它的体积更小
? 5.使用Typescript代替flow(静态类型检查工具)
为什么要新增Composition API , 它能解决什么问题
? Vue2.0中,随着功能的增加,组件变的越来越复杂,越来越难维护,而难以维护的根本原因是Vue的API设计使得开发者使用watch,computed,methods选项组织代码,而不是实际的业务逻辑.
? 另外Vue2.0缺少一种较为简洁的低成本的机制来完成逻辑复用,虽然可以使用minxis完成逻辑复用,但是当mixin变多,会使得难以找到对应的data,computed或者method来源于那个mixin,使得类型推断难以进行.
? 所以Composition API 的出现,主要是解决option api 带来的问题,第一个是代码组织问题,Composition API 可以让开发者根据业务逻辑组织自己的代码,让代码具备更好的可读性,可扩展性,也就是说当下一个开发者接触这一段不是他自己写的代码时,他可以更好的利用代码的组织反推出实际的业务逻辑,或者根据业务逻辑更好的理解代码.
第二个是实现代码逻辑提取与复用,当mixin也可以实现逻辑提取与复用,但是像前面所说的,多个mixin作用在同一个组件时,很难看出property是来源于哪个mixin,来源不清楚,另外,多个mixin的property存在变量命名冲突的风险.而Composition API 刚好解决这两个问题.
都说Composition API 与 React Hook 很像 , 说说区别
? 从React Hook的实现角度来看, Reack Hook是根据useState调用的顺序来确定下一次重渲染的state是来源于哪个useState,所以出现一些限制.
? 1.不能在循环,条件,嵌套函数中调用Hook
? 2.必须确保总是在你的React函数的顶层调用Hook
? 3.useEffect,useMemo 等函数必须手动确定依赖关系
而Composition API 是基于Vue的响应式系统实现的,与React Hook 的相比
? 1.声明在setup函数内,一次组件实例只调用了一次setup,而React Hook 每次重渲染都需要调用Hook , 使得React的GC (组件)比Vue更有压力, 性能也相对Vue来说也较慢
? 2.Composition API的调用不需要顾虑调用顺序,也可以在循环,条件,嵌套函数中使用
? 3.响应式系统自动实现了依赖收集,进而组件的部分性能优化由Vue内部自己完成,而React Hook 需要手动传入依赖,而且必须保证依赖的顺序,让useEffect,useMemo等函数正确的捕获依赖变量,否则会由于依赖不正确使得组件的性能下降.
虽然Composition API 看起来比React Hook 好用,但是其设计思想也是借鉴React Hook 的。
SSR有了解吗? 原理是什么?
? 在客户端请求服务器的时候,服务器到数据库中获取到相关的数据,并且在服务器内部将Vue组件渲染成HTML,并且将数据,html,一并返回给客户端,这个在服务器将数据和组件转化为HTML的过程,叫做服务端渲染SSR.
? 而当客户端拿到服务器渲染的HTML和数据之后,由于数据已经有了,客户端不需要再一次请求数据,而只需要将数据同步到组件或者Vuex内部即可.除了数据以外,HTML结构也有了,客户端在渲染组件的时候,也只需要将HTML的DOM节点映射到Virtual DOM 即可,不需要重新创建DOM节点
使用SSR的好处:
? 有利于SEO:其实 就是有利于爬虫来爬你的页面,因为部分页面爬虫是不支持JavaScript的,这种不支持执行JavaScript的爬虫抓取到的非SSR的页面会是一个空的HTML页面,而有了SSR以后,这些爬虫就可以获取到完整的HTML结构的数据,进而收录到搜索引擎中.
? 白屏时间更短: 相对于客户端渲染,服务端渲染在浏览器请求url之后已经得到了一个带有数据的html文本,浏览器只需要解析HTML,直接构建DOM树就可以。而客户端渲染,需要先得到一个空的HTML,这个时候页面已经进入白屏了,之后还需要经过加载并执行JavaScript,请求后的服务器获取数据,JavaScript渲染页面几个过程才可能看到最后的页面.特别是在复杂应用中,由于需要加载JavaScript脚本,越是复杂的应用,需要加载的JavaScript脚本就越多,越大,这会导致应用的首屏加载时间非常长,进而降低就体验感.
vue的生命周期有哪些?
挂载阶段
? beforeCreate 实例创建之前 data,methods,computed,watch都不能使用
? created 实例创建之后 data和methosd已经开始创建 但是还没有开始编译模版
? beforeMount 实例挂载前 data和methosd还没有挂载到页面上
? mounted实例挂载之后 data和methosd已经挂载到指定的容器上了
更新阶段
? beforeUpdate 更新之前 当前的值已经是新的了 但是页面还没渲染新值
? updated 更新之后 data的值和页面显示的都是新的都完成了渲染
卸载阶段
? beforeDestory 实例销毁之前,在当前阶段实例完全可以被使用,可以在这时做一些收尾工作比如清除定时器
? destroyed 实例销毁后 vue实例绑定的东西全部解绑 实例也销毁了
? keep-alice : activated ,激活正在显示 deactivated keep-alice 被停用
Vue.$set() 是干什么的
? 在开发过程中,时常遇到这样一种情况,当vue的data里边声明或者已经赋值过的对象或者数组时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的.
? 原因:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新
? 解决方法:Vue.set(object,key,value)将响应属性添加到嵌套的对象上
? object是你要添加到哪个对象上,key是添加的键名,value是键值
v-if和v-show的区别?
v-if是对dom节点的卸载和加载
v-show 是控制css样式dispaly来进行显示隐藏
在对一个节点需要频繁切换操作的时候,就建议使用v-show
当只需要首次加载的时候隐藏或显示的时候就可以使用v-if
缓存组件 keep - ailve 使用场景
参数: include : 只有名称匹配的组件会被缓存
? exclude : 名称匹配的组件不会被缓存
? max : 最多可缓存多少组件实例
activated 和 deactivate 生命周期钩子函数
使用场景: 列表页面=>点击进入详情页 => 后退到列表页 要缓存列表原来的数据 重新进入列表页面 => 获取最新的数据
? 使用keep-alive 会将数据保留在内存中,如果每次进入页面的时候要获取最新的数据,需要在activated 生命周期中重新获取数据,承担原来 created 钩子中获取的任务
? 第一次进入: beforRouteEnter => created => … => actived => deactived
? 后续进入: beforRouteEnter => actived => deacvtived
? 只有第一次进入该组件时,才会走created钩子,需要换成的组件中每次都走actived钩子函数
如何在vue中做一个自定义插件?
创建组件构造器 创建一个组件对象
将组件对象挂载到一个元素上 通过vue原型注册
介绍一下vuex?
? vuex是一个专门为vue开发的状态管理库,集中管理所有组件的状态 ? state:状态管理 ? getter: 计算属性 当其依赖值发生改变时才会发生改变 有缓存 ? mutation: 更改state 的唯一方法 是同步函数 ? avtion:执行任意的异步操作 ? module:分割模块
vue是什么
? vue是一个框架 就是一套用于构建用户界面的渐进式框架 它能构建用户界面 只需要关系view层 简单易学 ,轻量快速 是一个渐进式框架 它有两大核心 响应式的双向绑定和可组合的视图组件
虚拟dom和真实dom的区别
? 真实dom:更新缓慢,可以直接更新视图,如果元素更新,则直接创建dom,dom操作代价很高,消耗内存较多
? 虚拟dom:更新更快,无法直接更新视图,如果元素更新,则更新jsx,dom操作非常简单,很少的内存消耗
为什么选Vite
到现在我们见证了许多打包工具的诞生,webpack,Rollup,和Parcel,这些工具极大地改善了前端开发者的开发体验,
但是,当我们开始构建的项目越来越大时,需要处理的js代码量也呈指数级增长,大型项目包含数千个模块的情况并不少见。这时就遇到了性能瓶颈—使用js开发工具通常需要很长时间(甚至几分钟),才能启动开发服务器,即使使用SSR进行服务端渲染, 修改后的效果也需要几秒钟才能在浏览器中反应出来,如此循环往复,会极大的影响开发者的开发效率.
? vite在生态系统中解决了这些问题, 当使用vite启动项目时会将应用中的模块分为依赖和源码两类,改进了服务器的启动时间.
vite在编译一个文件时,会精准地使以编译的模块与模块本身失效,使模块快速更新,无论应用大小.
WebSocket
? 它是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议.
? 它使得客户端和服务器之间的数据交换变得更加简单,允许服务器主动向客户端推送数据.在websocket api中 浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输.
? 在WebSocket api中,浏览器和服务器只需要做一个握手动作,然后,浏览器和服务器之间就形成了一条快速的通道.两者之间就直接可以数据互相传送
React生命周期
挂载时 :
? 1.constructor :用于初始化
? 2.getDerivedStateFromProps: 当state,props,变化时触发, 在这个静态方法中nextProps和currentState以外都无法访问
? 3.render : 返回生成的虚拟dom
? 4.componentDidMount : 用于组件加载完成时做某些操作.比如请求或绑定事件
更新时 :
? 1.shouldComponentUpdate: 该方法返回 true 或 false 来确定是否需要触发新的渲染。是性能优化的必争之地.
? 2.getSnapshotBrforeUpdate: 在dom更新前调用,返回值作为componentDidUpdate的第三个参数
? 3.componentDidUpdate :首次渲染不会执行此方法,可以使用setState,触发重渲染。
卸载时 : 1. componentWillUnmount : 主要用于一些事件的解绑,资源清理,取消定时器,取消订阅
浏览器缓存
? 强缓存:强缓存如果命中,浏览器直接从直接的缓存中读取资源,不会发请求到服务器.
? 协商缓存 : 当强缓存没有命中的时候,浏览器一定会发送一个请求到服务器,通过服务器端依据资源的另外一些http header验证这个资源是否命中协商缓存,如果协商缓存命中,服务器会将这个请求返回,若未命中请求,则将资源返回客户端,并更新本地缓存数据。
get和post的区别
get请求参数的大小存在限制,post请求的参数大小无限制
实际上HTTP协议从未规定 GET/POST的请求长度限制是多少。对get请求参数的限制是来源于浏览器或web服务器的,浏览器或者web服务器限制了url的长度。不同的浏览器和web服务器限制的最多长度不一样, IE最大长度为2083byte 谷歌最大长度8182byte
get和post在缓存方面的区别:
get请求类型查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存
post不同 post做的一般是修改和删除的工作, 所以必须与数据库交互 所以不能使用缓存。因此get请求适合于请求缓存。
get和post安全性更高:
其实这里的安全并不是真正意义上的安全,通过get提交的数据提交的数据将显示到url上,页面会被浏览器缓存,其他人查看历史记录会看到提交的数据,而post不会。另外get提交的数据还可能会造成csrf攻击,所以不能用get传递一些敏感信息。
get发送请求会产生一个TCP包 post会产生两个TCP包
http和https的区别
http : 用于web浏览器与网站服务端之间传递信息,http协议以明文方式发送内容,不提供任何方式的加密,容易被攻击者截取传输的信息。不适合传输一下:银行卡号和密码支付信息
https : 解决了http协议的缺陷,为了保证数据传输的安全,https在http的基础上加入了ssl协议,用来验证服务器的身份,并为浏览器和服务器之间的通信加密。 https协议主要分为两种 :一种是建议一个信息安全通道,另一个是确认网站的真实性
区别:
? http协议传输的数据是未加密的,如果用http协议传输隐私信息非常不安全。
? https协议是由ssl+http协议构建的可进行加密传输,身份认证的网络协议,要比http协议安全。
http端口 80 https端口 443
https的工作原理:
https的缺点:
https协议握手阶段比较费时,会使页面的加载时间长50%左右
https连接缓存不如http高效,会增加数据开销和功耗
ssl证书要钱,越强大的证书越贵
https协议的加密范围比较有限,在一些黑客攻击或服务器攻击,服务器劫持方面几乎起不到什么作用
web前端优化策略
1.减少HTTP请求数:浏览器进行并发请求的请求数是有上限的,因此请求数多了以后,浏览器需要分批请求,因此会增加用户的等待时间,所以需要减少HTTP请求数
2.从设计实现层面简化页面:保持页面简洁,减少资源的使用时最直接的
3.合理设置HTTP缓存:缓存的力量是强大的,恰当的缓存可以大大的减少HTTP请求
4.资源合并与压缩:将外部的脚本,样式进行合并多个合并为一个,另外css,js,image都可以用对应的
5.css sprites : 合并css图片 减少请求的方法
6.Lazy Load images
PNG,GIF,JPG 的区别及如何选
GIF : 8位像素,256色 无损压缩 支持简单动画 直接透明 适合简单动画
JPG:颜色限于256 有损压缩 可控制压缩质量 不支持透明 适合照片
PNG: 类似 GIF 文件小 支持透明 无动画 适合图标 背景 按钮,
|