赞
踩
目录
3、 说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?
10、说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
11、说说AMD、CMD、commonJS模块化规范的区别?
14、说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?
15、 React render方法的原理,在什么时候会触发?
21、bind、call、apply 区别?如何实现一个bind?
27、什么是响应式设计?响应式设计的基本原理是什么?如何做?
36、 说说webpack中常见的Loader?解决了什么问题?
45、说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
51、Js数据类型判断都有哪几种方式?至少说出5种?它们的区别是什么?
52、说说你对Object.defineProperty()的理解?
57、说说设备像素、css像素、设备独立像素、dpr、ppi之间的区别?
64、说说你对git rebase 和git merge的理解?区别?
68、props和state相同点和不同点?render方法在哪些情况下会执行?
69、react新出来两个钩子函数是什么?和删掉的will系列有什么区别?
74、 如果需要手动写动画,你认为最小时间间隔是多久,为什么?
75、说说Real DOM和Virtual DOM的区别?优缺点?
80、shouldComponentUpdate有什么作用?
81、说说你对git rebase 和git merge的理解?区别?
82、在使用redux过程中,如何防止定义的action-type的常量重复?
83、说说React中的虚拟dom?在虚拟dom计算的时候diff和key之间有什么关系?
84、React的props.children使用map函数来遍历会收到异常显示,为什么?应该 如何遍历?
86、redux本来是同步的,为什么它能执行异步代码?实现原理是什么?中间件的 实现原理是什么?
87、redux中同步action与异步action最大的区别是什么?
88、redux-saga和redux-thunk的区别与使用场景?
96、说说你对useEffect的理解,可以模拟哪些生命周期?
97、说说React中setState和replaceState的区别?
101、知道react里面的createPortal么,说说其使用场景?
9、说说css中元素脱离文档流的方式有哪些?定位的方式有哪些以及区别?
11、伪类和伪元素的区别有哪些? Css3新增了哪些选择器?
16、如何快速的让一个打乱一个数组的顺序,比如 var arr = [1,2,3,4,5,6,7,8,9,10]?
17、Vue的自定义指令钩子函数有哪些?你用自定义指令做过什么?
18、从A页面跳转到B页面,缓存A组件,从A组件跳转到C组件,取消缓存,如何实现?
20、Vue是如何实现实现权限管理的,按钮级别权限如何实现?
30、Methods watch computed区别是什么?
35、说说HTTP和HTTPS的区别,HTTPS加密原理是?
41、说说webpack中常见的Loader?解决了什么问题?
42、你对SPA单页面的理解,它的优缺点分别是什么?如何实现SPA应用呢?
47、Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
49、说说对React中类组件和函数组件的理解?有什么区别?
51、UseMemo和useCallback如何提升了性能,应用场景有哪些?
60、什么是响应式设计?响应式设计的基本原理是什么?如何做?
67、Bind 、Call 、Apply有什么区别?如何实现一个bind方法?
76、说说你对递归的理解?封装一个方法用递归实现树形结构封装?
87、说一下DOM0、DOM2、DOM3事件处理的区别是什么?
88、如何判断页面滚动到底部,如何判断页面中元素是否进入可视化区域?
89、说一下浏览器Event Loop和nodejs中Event Loop的区别?
91、说一下vuex的实现原理?commit和dispatch方法是如何实现的?
92、有A,B,C 三个组件,A组件跳转到B组件缓存,A组件跳转到C组件不缓存,如何实现?
96、vue的路由实现:hash模式和history模式原理?
105、Proxy相比于definedProperty的优势?
110、举一些ES6对于String字符串做的常用升级优化?
111、举一些ES6对于Array数组类型做的常用升级优化?
1、React是用于构建用户界面的JavaScript库,只提供了UI层面的解决方案,遵循组件设计模式、声明式编程范式和函数式编程概念,使得前端应用程序更加高效。 2、使用虚拟DOM来有效地操作DOM,遵循从高阶组件到低阶组件的单向数据流,帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面。 3、特性:JSX语法、单项数据绑定、虚拟DOM、声明式编程、Component
1、diff算法是为了节省性能而设计的,通过同层级进行比较,不跨层级使得性能更加高效 2、运作流程主要分为三层:tree层、component层、element层 1、tree层:tree层对于DOM节点的跨层级移动的操作忽略,只对相同层级的DOM节点进行比较,一旦发现节点不存在,直接删除该节点以及以下的所有子节点 2、component层:遇到同一个类型的组件遵循tree diff,进行层级对比,遇到不同类型的组件,直接将这个不同的组件判断为脏组件,并且替换该组件之下的所有的子节点,当知道这个组件的虚拟DOM没有任何变化,就可以手动使用,shouldComponentUpdate来判断是否需要进行diff,进一步提升了diff效率和性能 3、element层:低于同一层级,面对全新节点,可以实现插入的操作;面对多余的节点,执行删除操作;面对换位的节点,执行移动的操作
1、React生命周期主要分为三个阶段:创建阶段、更新阶段和卸载阶段 2、创建阶段: 1、constructor:用来定义状态,或者是用来存放一些this的方法; 2、getDerivedStateFromProps():将来会使用的,需要返回一个新的对象作为新的state或者返回null表示state状态不需要更新 3、render():类组件必须实现的方法,用于渲染DOM结构,可以访问组件state与prop属性 4、componentDidMount():用于执行一些数据获取,事件监听等操作 3、更新阶段: 1、getDerivedStateFromProps():将来会使用的,需要返回一个新的对象作为新的state或者返回null表示state状态不需要更新 2、shouldComponentUpdate:用于告知组件本身基于当前的props和state是否需要重新渲染组件,默认情况返回true 3、render:类组件必须实现的方法,用于渲染DOM结构,可以访问组件state与prop属性 4、getSnapshotBeforeUpdate:该周期函数在render后执行,执行之时DOM元素还没有被更新,目的在于获取组件更新前的一些信息,比如组件的滚动位置之类的,在组件更新后可以根据这些信息恢复一些UI视觉上的状态 5、componentDidUpdate:可以根据前后的props和state的变化做相应的操作,如获取数据,修改DOM样式等 4、卸载阶段: componentWillUnmount:此方法用于组件卸载前,清理一些注册是监听事件,或者取消订阅的网络请求等,一旦一个组件实例被卸载,其不会被再次挂载,而只可能是被重新创建
1、虚拟DOM用js对象的形式,来模拟页面dom的嵌套关系; 2、虚拟DOM是一棵虚拟的JavaScript对象树,画重点,”虚拟的“、”JS对象“,指的是它把真实的网页文档节点,虚拟成一个个的js对象,并以树型结构,保存在内存中。 3、实现原理:通过JS模拟网页文档节点,生成JS对象树(虚拟DOM),然后再进一步生成真实的DOM树,再绘制到屏幕。如果后面有内容发生改变,React会重新生成一棵全新的虚拟DOM树,再与前面的虚拟DOM树进行比对diff,把差异的部分打包成patch,再应用到真实DOM,然后渲染到屏幕浏览器。
1、Hook是React 16.8.0版本增加的新特性/新语法,可以让你在函数组件中使用 state 以及其他的 React 特性 常见的Hook: 2、useState:跟类组件中state类似,方便我们定义初始化的数据,接收两个参数,一个是初始化数据,另一个是修改数据的方法 3、useEffect:副作用函数,只有使用之后,才会产生副作用,他接受两个参数,一个是函数,另一个是要监听的数据,可以是[],表示只执行一次,也可以传参,传参之后只要当我们的数据发生变化时才会触发,如果不写,那么发生一次变化就会执行一次 4、useMemo:数据缓存,当我们进行组件通信时,如果我们父组件中的数据发生变化,那么我们的子组件也会随着进行更新,不管我们更新的数据是否跟我们的子组件的数据有关系,他都会进行更新操作,这时候,就会存在更新性能的浪费,我们可以使用ysememo来进行缓存,减少不必要的更新操作,他的缓存的参数是一个字符串,如果是一个函数的话,那么我们的usememo就会失效,这时候就需要使用useCallback进行数据的缓存操作 5、useRef:可以监听我们的输入框数据的变化,获取输入框中的值
React组件通信就是值组件通过某种方式来传递信息以达到某个目的 方式: 1、父组件向子组件传递信息:由于react数据流动是单向的,父组件在调用子组件时,只需要在子组件标签内传递参数,子组件通过props属性接收 2、子组件向父组件传递信息;父组件向子组件传递一个函数,然后通过这个函数的回调,拿到子组件传过来的值 3、兄弟组件之间的传递:父组件作为中间层来实现数据的互通,通过使用父组件传递 4、父组件向后代组件传值:使用context提供的组件通信的一种方式,可以实现数据的共享,Provider组件通过value属性传递给后代组件 5、非关系组件传递数据:将数据进行一个全局的资源管理,从而实现组件间的通信功能,例如redux
1、受控组件:在React中,可变状态通常保存在组件的状态属性中,并且只能使用 setState() 更新,而呈现表单的React组件也控制着在后续用户输入时该表单中发生的情况,以这种由React控制的输入表单元素而改变其值的方式,称受控组件。简单说就是收到setState的控制,组件的状态全程响应外部数据 2、非受控组件:表单数据由DOM本身处理。即不受setState()的控制,与传统的HTML表单输入相似,input输入值即显示最新值(使用 ref从DOM获取表单值),不受setState的控制,一般在初始化的时候接收外部的数据,然后自己在内部存储其自身的状态 应用场景: 1、受控组件:强制输入格式、一个数据的多个输入、动态输入、提交时的验证问题 2、非受控组件:一次性取值(提交时)、提交时的验证
1、Connect连接redux和react,包裹在我们容器组件外层,接收上边的Provider提供的store里state和dispatch,传给一个构造函数,返回一个对象,以属性的形式传递给我们的容器组件 2、Connect是一个高阶函数,首先传入mapStateToProps、mapDispatchToProps,然后返回Component函数,然后将真正的Component作为参数传入,从而返回一个新的组件
1、Jsx的本质就是函数React.createElement的语法糖,所有的jsx语法都会最终经过babel.js转化为React.createElement这个函数调用 2、三个参数:type是指的当前的元素类型,config是jsx属性,以对象的属性和值的形式存储,children是存放在标签中的内容 3、jsx写法:必须引入babel并且设置script标签的type为text/bable babel:将jsx转化为React.createElement()这种函数的调用
1、Redux中间件就是介于应用系统和系统软件之间的一类软件,使用系统软件提供的基础服务,衔接网络上应用系统的各个部分或者是不同的应用,达到资源共享,功能共享的目的 2、常用的中间件:redux-thunk用于异步操作、redux-logger用于日志的记录 实现原理:所有中间件被放进一个数组中嵌套执行,判断传递过来的数据类型,最后执行store.dispatch,中间件内部middleware API可以拿到getstate和dispatch方法。
1、AMD:这种规范就是异步的加载模块,先定义所有依赖,然后加载完成后的回调函数中执行require([‘xxx’],function(){}) 2、CMD:依赖就近原则,用的时候在写 function(require,exports,module){require(‘xxx’)} 3、commonJS:加载模块使用require(‘xxx’) 区别: 1、AMD和CMD最大的区别就是对依赖模块的执行时机处理不同,二者均为异步加载模块 2、AMD依赖前置,js可以方便的知道依赖模块是谁,立即加载,CMD就近依赖,需要把模块变为字符串解析 3、commonJS是所有代码都运行在模块作用域,不会污染全局作用域,模块加载是同步的,只有加载完成后才可以执行后边的操作,requeire的值是被输出的值的拷贝,模块内容变化也不会影响这个值
^:只会执行不更改左边非零数字的更新 ~:如果写入的是~0.13.0,则当运行npm update时i,会更新到补丁版本 >:接收高于指定版本的任何版本 >=:接受等于或者高于指定版本的任何版本 <=:接受等于或者低于指定版本的任何版本 <:接受低于指定版本的任何版本 =:接收确切的版本 -:接受一定范围的版本 ||:组合集合 无符号:接收指定的特定版本 Latest:使用可以用的最高版本
1、使用React.createElement或jsx编写react组件,实际上所有的jsx代码最后都会转换成React.ccreateElement(...),babel帮助我们完成转换的过程 2、createElement函数对于key和ref等特殊的props进行处理,并获取defaultProps对默认的props进行赋值,并且对传入的子节点进行处理,最终构成一个虚拟DOM对象 3、ReactDOM.render将生成好的虚拟DOM渲染到指定的容器上,其中采用了批处理,事务等机制并且对特定的浏览器进行了性能优化,最终转换为真实DOM
1、React-redux是官方react UI绑定层,允许React组件从redux存储中读取数据,并将操作分派到存储以更新的状态。提供了connect,Provider等API,帮助我们连接react和redux,实现的逻辑会更加的严谨高效 2、@reduxjs/tookit是对Redux的二次封装,开箱即用的一个高效的Redux开发工具,使得创建store,更新store 区别: 1、reduxjs/tookit相对于react-redux来说比较方便,集成了redux-devtools-extension,不需要额外的配置,非常方便 2、reduxjs/tookit集成immutable-js的功能,不需要安装配置使用,提升了开发效率 3、reduxjs/tookit集成了redux-thunk的功能 4、reduxjs/tookit将types、actions、reducers放在一起组成了全新的slices,简化了我们的使用
Render函数在react中有两种形式,在类组件中指的是render方法,在函数组件中,指的是函数组件本身,在render中我们会编写jsx,jsx通过babel编译后就会转化为我们熟悉的js格式,在render过程中,React将新调用的render函数返回的树与旧版本的树进行比较,决定如何更新DOM,然后进行diff比较,更新DOM树 触发时机: 1、类组件调用setState修改状态时; 2、函数组件通过useState Hook修改状态时; 3、类组件重新渲染时; 4、函数组件重新渲染时;
1、通过shouldComponentUpdate:对比state和props,确定是否重新渲染,默认返回true,不希望渲染返回false 2、PureComponent:通过对比state和props间比较结果来实现 3、React.memo:缓存组件的渲染,避免不必要的更新(只能用于函数组件) 4、避免使用内联函数:每次调用render时就会重新渲染一个新的函数,在组件内部创建一个函数,将事件绑定到该函数本身 5、使用React Fragments避免额外标记 6、使用Immutable:减少渲染的次数 7、懒加载组件:使用suspense和lazy组件实现代码拆分功能 8、事件绑定方式 9、服务端渲染
1、函数节流: 频繁触发,但只在特定的时间内才执行一次代码 2、函数防抖: 频繁触发,但只在特定的时间内没有触发执行条件才执行一次代码 3、区别:两者区别在于函数节流是固定时间做某一件事,比如每隔1秒发一次请求。而函数防抖是在频繁触发后,只执行一次(两者的前提都是频繁触发) 4、节流应用场景:函数节流的应用场景一般是onrize,onscroll等这些频繁触发的函数,比如你想获取滚动条的位置,然后执行下一步动作 5、防抖应用场景:输入框搜索自动补全事件,频繁操作点赞和取消点赞等等,这些应用场景,也可以通过函数节流来实现,频繁操作点赞和取消点赞,因此需要获取最后一次操作结果并发送给服务器
1、在koa中,中间件被next()方法分成两部分,next方法上面会先执行,下边部门会在后续中间件执行全部结束后再执行, 2、在洋葱模型中,每一层相当于一个中间件,用来处理特定的功能,比如错误处理,session处理等,其处理顺序先是next()请求,然后执行next()函数,最后是next()响应,也就是说每一个中间件都有两次处理时机。 3、洋葱模型的核心原理是借助componse方法
1、压缩代码:删除多余的代码、注释、简化代码的写法等等⽅式。可以利⽤webpack的 UglifyJsPlugin 和 ParallelUglifyPlugin 来压缩JS⽂件 2、利⽤ cssnano (css-loader?minimize)来压缩css 3、利⽤CDN加速: 在构建过程中,将引⽤的静态资源路径修改为CDN上对应的路径。可以利⽤webpack对于 output 参数和各loader的 publicPath 参数来修改资源路径 4、Tree Shaking: 将代码中永远不会⾛到的⽚段删除掉。可以通过在启动webpack时追加参数 --optimize-minimize 来实现 5、Code Splitting: 将代码按路由维度或者组件分块(chunk),这样做到按需加载,同时可以充分利⽤浏览器缓存 6、提取公共第三⽅库: SplitChunksPlugin插件来进⾏公共模块抽取, 7、利⽤浏览器缓存可以⻓期缓存这些⽆需频繁变动的公共代码
1、理解:webSocket是一种网络传输协议,位于OSI模型的应用层,可在单个TCP连接上进行双工通信,能够更好的节省服务器资源和带宽并达到实时通讯。客户端和服务器只需要完成一次握手,两者之间就可以创建出持久性的连接,并进行双向数据传输 2、特点: 1、全双工(通信允许数据在两个方向上同时传输) 2、二进制帧(采用二进制帧的结构,语法语义与HTTP完全不兼容,更侧重与实时通信) 3、协议名(引入ws和wss分别代表明文和密文的websoket协议,且默认端口使用80或者443,几乎与http完全一致) 4、握手(有一个握手过程然后正式收发数据)
Call、bind、apply作用都是改变函数执行时的this指向 区别: 1、apply接收两个参数,第一个参数是this指向,第二个参数是函数接收的参数,以数组的形式传入 2、Call方法的第一个参数也是this指向,后面传入的是一个参数列表 3、Bind方法和call相似,第一个参数也是this指向,后边传入的也是一个参数列表(这个列表可以分多次传入),bind是返回绑定this之后的函数,apply和call是立即执行 如何实现一个bind:修改this指向,动态的传递参数,兼容new关键字 使用function.prototype.mybind = function(context){ 判断调用对象是否为函数 If(typeof this !== ‘function’){throw new TypeError(“error”)} 获取参数 Const args = [...arguments].slice(1) Fn = this Return function Fn(){ 根据调用方式,传入不同的绑定值 Return fn.apply(this instanceof Fn ? new fn(...arguments):context,args.concat(...arguments)) } }
节流:n秒内只允许一次,如果在n秒内重复触发,只有一次生效 防抖:n秒后在执行该事件,如果在n秒内被重复触发,则重新计时 区别: 1、函数防抖在一段连续操作结束以后,处理回调,利用clearTimeout和setTimeout实现;函数的节流,在一段连续操作中,每一段事件只执行一次,频率较高的事件中使用来提高性能 2、函数防抖关注一定时间连续触发的时间,只在最后执行一次,而函数节流一段时间内只执行一次
回流:布局引擎会根据各种样式计算每个盒子在页面上的位置和大小 重绘:当计算好盒模型的位置、大小以及其他属性后,浏览器根据每个盒子的特性进行重新绘制 触发时机: 回流:添加或删除可见的DOM元素;元素位置发生变化、元素的尺寸发生变化、内容发生变化,比如文本变化或者图片被代替;页面一开始渲染的时候、浏览器的窗口尺寸变化 重绘:触发回流时一定触发重绘,另外还有颜色的修改、文本方向的修改、阴影的修改等
路由分为两种模式:hash模式和history模式 原理: Hash:url中的hash值是客户端的一种状态,当向服务器端发送请求时,hash部分不会被发送,hash的改变,都会在浏览器的访问历史中增加一个记录,因此我们可以通过浏览器的回退,前进按钮控制hash的切换,通过改变hash值来进行页面的跳转 History:在history的模式下,前端的url必须和实际向后端发起请求的url一致,pushState和replaceState两个API来操作实现url的变化,可以在页面不刷新的情况下,操作浏览器的历史记录,也可以使用popstate来监听url的变化,从而实现页面的跳转功能
Diff算法是一种通过同层的树节点进行比较的高效算法,有两个特点:比较只会在同层级中进行比较,变化跨层级进行比较;在diff的比较过程中,循环从两边向中间进行比较 原理: 1、当数据发生变化时,set方法会调用Dep.notify通知所有订阅者watcher,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图 2、每次diff都会调用updateChildren方法来比较,然后层层递归下去,直到将旧Vnode和新Vnode中的所有子节点对比完。domDiff的过程更像是两个树的比较,每找到相同节点时,都会一层层的往下比较它们的子节点,是一个深度递归遍历比较的过程
1、Keep-alive是vue中的内置组件,能在组件切换的过程中将状态保留在内存中,防止重复渲染DOM,也就是所谓的组件缓存 2、Keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁他们 3、Keep-alive可以设置props属性:include字符串或正则表达式,只有当名称匹配时才会被缓存; 4、exclude:字符串或者正则表达式,任何名称匹配的组件都不会被缓存,max数字,最多可以缓存多少组件实例
响应式网站设计:是一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整 响应式设计的基本原理:是通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有meta声明viewport 实现方式: 1、媒体查询:设置不同类型的媒体条件,并根据对应的条件,给相应符合条件的媒体调用相对应的样式表 2、百分比:当浏览器的宽度或者高度发生变化时,通过百分比单位,可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果 3、vw/vh:vw表示相对于视图窗口的宽度,vh表示相对于视图窗口高度。任意层级元素,在使用vw单位的情况下,1vw都等于视图宽度的百分之一 4、rem:rem是相对于根元素html的font-size属性,默认情况下浏览器字体大小为16px,此时1rem = 16px
出于浏览器的同源策略限制产生的跨域问题,浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域 解决: 1、jsonp跨域 2、Nginx反向代理 3、Php端修改header 4、Document.domain实现不同window之间的相互访问和操作 5、Cors解决跨域 6、Window.name利用了浏览器的特性来做到不同域之间的数据传递;
1、尽可能的减少模板上使用loader,减少loader被频繁执行的频率 2、跟上开发技术的迭代:node,yarn,npm,webpack保持最新最稳定的版本 3、Plugin尽量少并可靠,选择性能好,官方推荐的插件 4、Resolve参数的合理配置 5、使用DllPlugin提升webpack的打包速度 6、控制包文件的大小 7、Thread-loader、parallel-webpack、happypack多进程打包
首屏加载:浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容 1、减小入口文件体积:,把不同路由对应的组件分割成不同的代码块,待路由被请求的时候会单独打包路由,使得入口文件变小,加载速度大大增加 2、静态资源本地缓存:采用http缓存设置响应头,采用service worker离线缓存,合理利用localstroage 3、UI框架按需加载 4、组件重复打包 5、图片资源的压缩 6、开启GZip压缩 7、使用SSR:服务端渲染,组件或页面通过服务器生成html字符串,再次发送到浏览器
两种模式:hash模式和history模式 Hash原理:hash 值改变,触发全局 window 对象上的 hashchange 事件。所以 hash 模式路由就是利用 hashchange 事件监听 URL 的变化,从而进行 DOM 操作来模拟页面跳转 History原理:利用了 HTML5 History Interface 中新增的 pushState () 和 replaceState () 方法。
1、浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP,向服务器发起请求; 2、服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图像等) 3、浏览器对加载到的资源(HTML、JS、CSS 等)进行语法解析,建立相对应的内部数据结构(如 HTML 的 DOM); 4、载入解析到的资源文件,渲染页面,完成。
基本类型:number、string、Boolean、undefined、null、symbol 复杂类型:object、array、function 存储的区别: 1、位置不同:基本数据类型存储在栈中,引用类型的对象存储与堆中 2、声明变量时内存地址分配:简单类型的值栈中存放的是对应的值,引用数据类型栈中存放的是指向堆的内存地址 3、简单基本类型赋值是生成相同的值,两个对象对应不同的地址,复杂类型赋值将保存对象的内存地址赋值给另一个变量,两个变量指向堆内存中的同一个对象
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性 解决问题: 1、难以重用和共享组件中与状态相关的逻辑 2、由于业务变动,函数组件不得不改为类组件 3、逻辑复杂的组件难以开发和维护,当组件需要处理多个不相关的local state时,每个生命周期函数中肯能会包含各种互不相关的逻辑 4、类组件在基于现有工具的优化上存在的些许问题 5、hooks的出现,使函数组件的功能得到了扩充,拥有了类组件相似的功能,在我们日常使用中,使用hooks能够解决大多数问题,并且还拥有代码复用机制,因此优先考虑hooks
1、Promise是最早由社区提出和实现的一种解决异步编程的方案,比其他传统的解决方案(回调函数和事件)更合理和更强大。 2、promise是为解决异步处理回调金字塔问题而产生的 3、Promise对象的状态不受外界影响,Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,只能由 pending变成fulfilled或者由pending变成rejected 4、Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。 5、Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
1、loader 用于对模块的源代码进行转换,在import或加载模块时预处理文件 2、Style-loader:将css添加到DOM的内联样式标签style中 3、Caa-loader:将css文件通过require的方式引入,并且返回css代码 4、Less-loader:处理less 5、Sass-loader:处理sass 6、Postcss-loader:处理postcss来处理css 7、File-loader:分发文件到output目录并返回相对路径 8、Html-minify-loader:压缩html
1、通过shouldComponentUpdate:对比state和props,确定是否重新渲染,默认返回true,不希望渲染返回false 2、PureComponent:通过对比state和props间比较结果来实现 3、React.memo:缓存组件的渲染,避免不必要的更新(只能用于函数组件) 4、避免使用内联函数:每次调用render时就会重新渲染一个新的函数,在组件内部创建一个函数,将事件绑定到该函数本身 5、使用React Fragments避免额外标记 6、使用Immutable:减少渲染的次数 7、懒加载组件:使用suspense和lazy组件实现代码拆分功能 8、事件绑定方式 9、服务端渲染
一个组件显示形态就可以由数据状态和外部参数决定,而数据状态就是state,当需要修改值的状态就通过seState来改变,从而达到更新组件内部数据的作用 SetState更新数据时就可以分为同步和异步更新,在组件生命周期或react合成事件中,setState就是异步的,在setTimeout或原生的dom事件中,setState就是同步的
这类问题 首先分类 表明了解的比较多 具体就没说完 或者漏了 面试官也不会计较很多 组件通信的四大类 父与子 子与父 子与子 跨层级 在细说各种方式 加入自己的理解 1、props和$emit父组件向子组件传递数据是通过prop传递的,子组件传递数据给父组件是通过$emit触发事件 2、$attrs和$listeners 3、中央事件总线 bus上面两种方式处理的都是父子组件之间的数据传递,而如果两个组件不是父子关系呢?这种情况下可使用中央事件总线的方式。新建一个Vue事件bus对象,然后通过bus.$emit触发事件,bus.$on监听触发的事件。 4、provide和inject父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深只要调用了 inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。 5、v-model:父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input’,val)自动修改v-model绑定的值 6、$parent和$children 说说vue中Key值的作用 说说vue中的虚拟dom和diff算法 7、boradcast和dispatch 8、vuex处理组件之间的数据交互 如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。
1、 getDerivedStateFromProps 容易编写反模式代码,使受控组件和非受控组件区分模糊 2、 componentWillMount 在 React 中已被标记弃用,不推荐使用,主要的原因是因为新的异步架构会导致它被多次调用,所以网络请求以及事件绑定应该放到 componentDidMount 中 3、 componentWillReceiveProps 同样也被标记弃用,被 getDerivedStateFromProps 所取代,主要原因是性能问题。 4、 shouldComponentUpdate 通过返回 true 或者 false 来确定是否需要触发新的渲染。主要用于性能优化。 5、 componentWillUpdate 同样是由于新的异步渲染机制,而被标记废弃,不推荐使用,原先的逻辑可结合 getSnapshotBeforeUpdate 与 componentDidUpdate 改造使用。 6、如果在 componentWillUnmount 函数中忘记解除事件绑定,取消定时器等清理操作,容易引发 bug。如果没有添加错误边界处理,当渲染发生异常时,用户将会看到一个无法操作的白屏,所以一定要添加
1、 代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。 2、 经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面; 3、 在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染; 4、 在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。
1. 将应用的状态统一放到state中,由store来管理state。 2. reducer的作用是返回一个新的state去更新store中对用的state 3. 按redux的原则,UI层每一次状态的改变都应通过action去触发,action传入对应的reducer 中,reducer返回一个新的state更新store中存放的state,这样就完成了一次状态的更新 4. subscribe是为store订阅监听函数,这些订阅后的监听函数是在每一次dipatch发起后依次执行 5. 可以添加中间件对提交的dispatch进行重写
react中的事件都是合成事件,不是把每一个dom的事件绑定在dom上,而是把事件统一绑定到document中,触发时通过事件冒泡到document进行触发合成事件,因为是合成事件,所以我们无法去使用e.stopPropagation去阻止,而是使用e.preventDefault去阻止。 合成事件:循环所有类型的eventPlugin,对应每个事件类型,生成不同的事件池,如果是空,则生成新的,有则用之前的,根据唯一key获取到指定的回调函数,再返回带有参数的回调函数。
目的是为了防止 XSS 攻击。 因为 Synbol 无法被序列化,所以 React 可以通过有没有 $$typeof 属性来断出当前的 element 对象是从数据库来的还是自己生成的。 如果没有 $$typeof 这个属性,react 会拒绝处理该元素。
Redux中间件就是介于应用系统和系统软件之间的一类软件,使用系统软件提供的基础服务,衔接网络上应用系统的各个部分或者是不同的应用,达到资源共享,功能共享的目的 常用的中间件:redux-thunk用于异步操作、redux-logger用于日志的记录 实现原理:所有中间件被放进一个数组中嵌套执行,判断传递过来的数据类型,最后执行store.dispatch,中间件内部middleware API可以拿到getstate和dispatch方法。
JavaScript是一门单线程的语言,意味着同一时间内只能做一件事情,但是并不意味着单线程就是阻塞,而实现单线程非阻塞的方法就是事件循环 所有的任务都分为同步任务、异步任务。 同步任务:立即执行的任务,同步任务一般会直接进入到主线程中执行 异步任务:ajax网络请求、setTimeout定时器函数 同步任务进⼊主线程,即主执⾏栈,异步任务进⼊任务队列,主线程内的任务执 ⾏完毕为空,会去任务队列读取对应的任务,推⼊主线程执⾏。那么上述过程的不断重复就称为事件循环。
1、 Jsonp跨域:利用script标签没有跨域限制,src属性发送带有callback参数的get请求,服务端接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从前端拿到数据 2、 跨域资源共享:允许浏览器向跨源服务器发出XMLhttpRequest请求,克服了ajax只能同源使用的限制 3、 Nginx代理跨域 4、 Node.js中间件代理跨域 5、 Localtion.hash+iframe跨域
1、 Array.join():将数组中的元素连接成一个字符串 2、 Array.push(): 将新元素追加到数组的最后一个位置中 3、 Array.splice(): 根据数组的下标在数组中的任意位置添加或者删除元素 形参1代表根据数组的下标,从第几个元素开始添加或删除。 4、 Array.slice(): 根据数组下标裁切出一个新的数组 5、 Array.forEach(): 该数组方法接收三个形参,第一个形参为数组中的每一项; 第二个形参为数组中每一项的索引下标; 第三个形参为数组本身。 6、 Array.map():循环,分配内存空间存储新数组并返回 7、 Array.filter(): 创建一个新的数组,新数组中的元素是通过filter方法检查后再指定数组中符合条件的所有元素并且它不会改变原始数组。 8、 Array.reduce(): 接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减(递增),最终为一个值。 9、 Array.every(): 检查所有数组值是否通过测试。 10、 Array.some():检查某些数组值是否通过测试 11、 Array.indexOf():在数组中搜索元素值并返回其位置 12、 Array.find():通过测试函数的第一个数组元素的值 13、 Array.pop():从数组中删除最后一个元素 14、 Array.shift():删除首个数组元素,并把所有的其他元素位移到哦更低的索引 15、 Array.unshift():在开头向数组添加新元素,并反向位移旧元素
1、 Mixin是面向对象程序设计语言中的类,提供了方法的实现,其他类可以访问mixin的方法而不必成为其子类 2、 Vue中的mixin是一种非常灵活的方式,用来分发vue组件的可复用功能 3、 本质上就是一个js对象,可以包含组件中的任意功能选项,比如说data、components、methods、created等 4、 将共用的功能以对象的方式传入 mixins选项中,当组件使用 mixins对象时所有mixins对象的选项都将被混入该组件本身的选项中来
1、 For in 和 for of 都是可以用于遍历 2、 For in 遍历的是数组的索引index;for of 遍历的是数组的元素值 3、 For in 更适合遍历对象,当然也可以遍历数组,但是会存在一些问题;for of 可以遍历数、数组对象、字符串等拥有迭代器对象的集合 4、 For in 会遍历数组的所有可枚举属性,包括原型;For of 遍历的只是数组内的元素,不包括原型属性和索引 5、 For in 总是得到对象的key或数组、字符串的下标;for of得到的对象的value或数组、字符串的值
1、 Typeof方法:返回表示数据类型的字符串,无论引用对象是什么类型,都返回Object 2、 Instanceof方法:由构造类型判断出数据类型 3、 Constructor方法:是prototype对象上的属性,指向构造函数 4、 Object.prototype.toString方法:object对象返回的是[Object object],其他类型需要call,apply来调用 5、 Jquery.type()方法
1、Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。IE8不兼容。 2、对象中目前存在的属性描述符有两种形式:数据描述符和存取描述符 3、数据描述符就是一个具有值的属性,该值可写也不可写;存取描述符是由get和set函数所描述的属性 4、数据描述符有value和writeable,存取描述符是由一堆getter和setter函数功能来描述的属性,get返回值被用作属性值,set方法接受唯一参数,并将该参数的新值分配给该属性 5、当使用get或者set方法时,不能使用writable和value两个属性,反之也一样
1、 指令系统也是计算机硬件的语言系统,也叫机器语言,是系统程序员看到的计算机主要属性 2、 自定义指令也像组件那样存在的钩子函数,bind、inserted、update、componentUpdated、unbind 3、 场景:表单防止重复提交、图片的懒加载、一键copy的功能
1、 意外的全局变量 2、 忘记释放的计时器 3、 多处引用,当多个变量引用同一个对象时,有引用没有被清除 4、 闭包的不合理使用 5、 Console.log打印信息内存不被释放
由于大文件上传时,像服务器处理数据的能力、请求超时、网络波动等变量会影响我们的用户体验,那么我们就会需要对大文件上传做单独的处理 1、分片上传:就是将所需要上传的文件,按照一定的大小,将整个文件分割成多个数据块来进行分片上传,在上传完成以后再由服务器对上传的文件进行汇总整合成原始的文件 2、断点续传:断点续传指的是再下载或者上传时,将下载或者上传的任务认为的划分为几个部分,每一个部分采用一个线程进行上传或者是下载,如果碰到网络故障问题,用户可以从已经上传或者下载的部分开始继续上传或者下载未完成的部分,而没有必要从头开始上传下载,用户可以节省时间,提高速度。 3、断点续传一般实现方式有两种,服务器端返回,告知从哪开始;浏览器端自行处理。
上拉加载及下拉刷新都依赖于用户交互 1、上拉加载: 1、scrollTop:滚动视窗的高度距离window顶部的距离,它会随着往上滚动而不断增加,初始值是0,它是一个变化的值 2、clientHeight:它是一个定值,表示屏幕可视区域的高度; 3、scrollHeight:页面不能滚动时也是存在的,此时scrollHeight等于clientHeight。 4、scrollHeight表示body所有元素的总长度(包括body元素自身的padding) 一个触底公式:scrollTop + clientHeight >= scrollHeight 2、下拉刷新: 下拉刷新的本质是页面本身置于顶部时,用户下拉时需要触发的动作 1、监听原生touchstart事件,记录其初始位置的值,e.touches[0].pageY; 2、监听原生touchmove事件,记录并计算当前滑动的位置值与初始位置值的差值,大于0表示向下拉动,并借助CSS3的translateY属性使元素跟随手势向下滑动对应的差值,同时也应设置一个允许滑动的最大值; 3、监听原生touchend事件,若此时元素滑动达到最大值,则触发callback,同时将translateY重设为0,元素回到初始位置
1、无缩放情况下,1个CSS像素等于1个设备独立像素 2、 设备像素由屏幕生产之后就不发生改变,而设备独立像素是一个虚拟单位会发生改变 3、 PC端中,1个设备独立像素 = 1个设备像素 (在100%,未缩放的情况下) 4、 在移动端中,标准屏幕(160ppi)下 1个设备独立像素 = 1个设备像素 5、 设备像素比(dpr) = 设备像素 / 设备独立像素 6、 每英寸像素(ppi),值越大,图像越清晰
1、 Bfc就是块级格式化上下文,它是页面中一块渲染区域,并且有一套属于自己的渲染规则 2、 Bfc的目的就是形成一个相对于外界的完全独立的空间,让内部的子元素不会影响到外部的元素 3、 Bfc就是页面上一个隔离的独立容器,容器里边的子元素不会影响外部的元素,反之也是 4、 Bfc的区域不会和浮动的元素区域重叠
三次握手是为了建立可靠的数据传输通道,四次挥手则是为了保证等数据完成的被接收完再关闭连接。 1、 三次握手就是指建立一个TCP连接时,需要客户端和服务器总共发送三个包,主要作用就是为了确认双方的接受能力和发送能力是否正常,指定自己的初始化序列为后边的可靠性传送做准备 2、 四次挥手就是指tcp终止一个连接,需要四次挥手,当服务器在收到客户端断开连接的报文后,并不会立即关闭连接,而是先发送一个ACK包告诉客户端收到关闭连接的请求,只有当服务器的所有报文发送完毕以后,才断开连接
1、 资源压缩合并,减少http请求 2、 图片优化,使用png体积小 3、 非核心代码异步加载 4、 利用浏览器缓存,资源文件存在本地,下次调用直接从缓存中取出 5、 使用CDN可以分配负载,提高性能 6、 DNS预解析 7、 开启Gzip代码压缩 8、 减少不必要的cookie
1、 额外标签法:在需要清除浮动的元素前面放一个空的div,并给这个空div设置属性 clear:both 2、 给父元素设置 overflow 属性 为 hidden 或者 auto 3、 :after利用伪元素清除有浮动的标签->在有浮动的标签前面添加一个块级元素
浏览器首次请求资源后,需要再次请求时,浏览器会首先获取该资源缓存的header信息,然后根据Cache-Control和expires来判断该资源在本地缓存否过期。若没过期则直接从本地缓存中获取资源信息,浏览器就不再向服务器重新请求资源,如过期则需重新发送请求,重新缓存资源,更新缓存时间。 1、强缓存是利用http请求头中的Expires和Cache-Control两个字段来进行控制,用来表示资源的缓存时间。Expires是http1.0的规范,它的值是一个GMT格式的绝对时间字符串。 2、协商缓存是服务器用来确定缓存资源是否可用过期。因为服务器需要向浏览器确认缓存资源是否可用,二者要进行通信,而通信的过程就是发送请求,所以在header中就需要有专门的标识来让服务器确认请求资源是否可以缓存访问
1、 栈(stack)又名堆栈,它是一种运算受限的线性表,限定仅在表尾进行插入和删除操作的线性表 2、 栈按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据,具有记忆作用 3、 队列时跟栈十分相似,队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作 4、 队列因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出 5、 场景:栈可以使用在函数调用和递归时,还有编译器在对输入的语法进行分析时;队列可以使用遍历一个二叉树时
1、 在使用 git 进行版本管理的项目中,当完成一个特性的开发并将其合并到 master 分支时,会有两种方式是git merge和git rebase 2、 git rebase 与 git merge都有相同的作用,都是将一个分支的提交合并到另一分支上,但是在原理上却不相同 3、 git merge将当前分支合并到指定分支:git merge xxx;git rebase合并分支或合并到指定的commit上:git rebase -I <commit> 4、 通过merge合并分支会新增一个merge commit,然后将两个分支的历史联系起来; rebase会将整个分支移动到另一个分支上,有效地整合了所有分支上的提交
1、 git status :时刻掌握仓库当前的状态,是否进行了修改变化 2、 git diff 小说.txt :查看修改的内容操作 3、 git reflog :查看版本号 4、 git log :查看提交历史 5、 git reset --hard 版本号 :穿梭到那个版本号 6、 git checkout -- 小说.txt:可以丢弃工作区的修改 7、 rm 文件名:删除文件(没有提交至工作区的文件) 8、 git rm 文件名:删除版本库中的文件 9、 git branch dev :创建dev分支 10、 git branch -a :查看分支以及当前处于哪个分支 11、 git checkout dev :切换到dev分支 12、 git merge dev:将当前分支与dev分支进行合并
组件通信指的是发送者通过某种媒体以某种格式来传递信息到收信者以达到某个目的 分类:父子组件之间的通信、兄弟组件之间的通信、祖孙与后代组件之间的通信、非关系组件间之间的通信 vue中8种常规的通信方案: 1、通过 props 传递:子组件设置props属性,定义接收父组件传递过来的参数,父组件在使用子组件标签中通过字面量来传递值 2、通过 $emit 触发自定义事件:子组件通过$emit触发自定义事件,$emit第二个参数为传递的数值,父组件绑定监听器获取到子组件传递过来的参数 3、使用 ref:父组件在使用子组件的时候设置ref,父组件通过设置子组件ref来获取数据 4、EventBus:创建一个中央事件总线EventBus,兄弟组件通过$emit触发自定义事件,$emit第二个参数为传递的数值 另一个兄弟组件通过$on监听自定义事件 5、$parent 或$root:通过共同祖辈$parent或者$root搭建通信桥连 6、attrs 与 listeners:设置批量向下传属性$attrs和 $listeners,包含了父级作用域中不作为 prop 被识别 (且获取) 的特性绑定 ( class 和 style 除外)。可以通过 v-bind="$attrs" 传⼊内部组件 7、Provide 与 Inject:在祖先组件定义provide属性,返回传递的值,在后代组件通过inject接收组件传递过来的值 8、Vuex:作用相当于一个用来存储共享变量的容器
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 vuex五大核心属性:state,getter,mutation,action,module 1、state:存储数据,存储状态;在根实例中注册了store 后,用this.$store.state来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。 2、getter:可以认为是 store 的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。 3、mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。 4、action:包含任意异步操作,通过提交 mutation 间接更变状态。 5、module:将 store 分割成模块,每个模块都具有state、mutation、action、getter、甚至是嵌套子模块。
不同点: 1.props不可以在组件内部修改,但state可以在组件内部修改 2.可以从父组件修改自组件的props,而不能从父组件修改自组件的state 相同点: 1.props和state都是导出HTML的原始数据。 2.props和state都是确定性的,如果我们写的组件为同一props和state的组合3.生成了不同的输出,那木我们肯定在哪里做错了 4.props和state都会触发渲染更新 5.props和state都是纯JS对象(用typeof来判断,结果都是object) 6.可以从父组件得到初始值props和state的初始值 render在哪些情况下执行? 1、类组件调用setState修改状态时 2、函数组件通过useState Hook修改状态时 3、类组件重新渲染时 4、函数组件重新渲染时
React新增的两个生命周期钩子函数? 1、getDerviedStateFromProps 作用:从props中获取衍生的state 2、getSnapshotBeforeUpdate 作用:在组件更新前获取快照,一般结合componentDidUpdate使用,getSnapBeforeUpdate中返回值将作为第三参数传递给componentDidUpdate 它和componentDidUpdate将render夹在中间,其实它的核心作用就是在render改变dom之前,记录更新前的dom信息传递给componentDidUpdate。 二、React新的生命周期去除的钩子函数? 1、componentWillMount 2、componentWillReceiveProps 3、componentWillUpdate 总结 1、componentWillMount中可能需要做的事(一些数据初始化的操作就应该放在这个钩子中处理),constructor与componentDidMount也能做,甚至做的更好,此方法被废弃。 2、componentWillReceiveProps实际行为与命名并不相符,由于不稳定性已由getDerivedStateFromProps代替; 3、而componentWillUpdate同等理由被getSnapshotBeforeUpdate代替
1、CDN 意为内容分发网络,是基于现有网络的智能虚拟网络,分布在世界各地的边缘服务器上。基本思路是避免互联网上可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输更快更稳定。 2、CDN 表示将数据从原始服务器复制到其他服务器。当用户访问时,他们可以在复制了数据内容的服务器上进行访问。其目的是使用户能够更快更好地获取所需内容,解决网络拥塞情况,提高用户访问网站的响应速度。CDN 加速成本低,速度快,适合访问量比较大的网站。 特点: 1.本地缓存加速:提高了企业网站(尤其是包含大量图片和静态页面的网站)的访问速度,大大提高了上述网站的稳定性。 2.镜像服务:消除了不同运营商之间互联瓶颈带来的影响,实现了跨运营商的网络加速,保证了不同网络的用户都能获得良好的接入质量。 3.远程加速:远程访问用户根据DNS负载均衡技术智能自动选择缓存服务器,选择最快的缓存服务器加速远程访问。 4.带宽优化:自动生成服务器的远程镜像缓存服务器。远程用户访问时,可以从缓存服务器读取数据,减少远程访问的带宽,分担网络流量,减轻原WEB服务器的负载。 5.集群抗攻击:广泛分布的CDN 节点加上节点间的智能冗余机制,可以有效防止黑客入侵,降低各种D.D.o.S攻击对网站的影响,同时保证更好的服务质量。
1、闭包就是能够读取其他函数内部变量的函数,说白了闭包就是个函数,只不过是处于其他函数内部而已。 2、由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数“ 应用场景: 1、模仿块级作用域:计时器的应用、打印一组li标签的下标 2、埋点计数器:产品做一些常用的数据采集方法 3、柯里化:将一个多参数的函数转换为单参数函数的办法
内核主要分为渲染引擎和js引擎 1、渲染引擎:负责取得网页的内容(HTML,XML和图像等),整理讯息(例如css),以及计算网页的显示方式,然后输出到显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不同。所有网页浏览器、电子邮件客户端以及它需要编辑、显示网络内容的应用程序都需要内核 2、JS引擎:解析和执行JavaScript来实现网页的动态效果 最开始渲染引擎和js引擎并没有区分很明确,后来js引擎越来越独立,内核就倾向与只指渲染引擎
清除浮动:为了解决父元素因为子级元素浮动引起的内部高度塌陷的问题 方式: 1、额外标签法(在最后一个浮动标签后,新添加一个标签,给它设置clear:both;)优点:通俗易懂更加方便;缺点:添加无意义标签,语义化差 2、父级添加overflow属性(父元素添加overflow:hidden) 优点:代码简洁;缺点:内容增多时容易造成不会自动换行导致内容被隐藏掉,无法显示要溢出的元素 3、使用after伪元素清除浮动 优点:符合闭合浮动思想,结构语义化正确;缺点:IE6-7不支持伪元素 4、使用before和after双伪元素清除浮动 优点:代码更加简洁;缺点:用zoom:1触发haslayout
多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7ms。为了浏览器的渲染和用户体验的话,最小设置0.1-0.3s最佳
1、Real DOM,真实DOM, 意思为文档对象模型,是一个结构化文本的抽象,在页面渲染出的每一个结点都是一个真实DOM结构 2、Virtual Dom,本质上是以 JavaScript 对象形式存在的对 DOM 的描述 3、创建虚拟DOM目的就是为了更好将虚拟的节点渲染到页面视图中,虚拟DOM对象的节点与真实DOM的属性一一照应 4、两者的区别如下: 虚拟DOM不会进行排版与重绘操作,而真实DOM会频繁重排与重绘 虚拟DOM的总损耗是“虚拟DOM增删改+真实DOM差异增删改+排版与重绘”,真实DOM的总损耗是“真实DOM完全增删改+排版与重绘” 优缺点? 真实DOM的优势:易用 缺点: 1、效率低,解析速度慢,内存占用量过高 2、性能差:频繁操作真实DOM,易于导致重绘与回流 使用虚拟DOM的优势如下: 1、简单方便:如果使用手动操作真实DOM来完成页面,繁琐又容易出错,在大规模应用下维护起来也很困难 2、性能方面:使用Virtual DOM,能够有效避免真实DOM数频繁更新,减少多次引起重绘与回流,提高性能 3、跨平台:React借助虚拟DOM, 带来了跨平台的能力,一套代码多端运行 缺点: 1、在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化 2、首次渲染大量DOM时,由于多了一层虚拟DOM的计算,速度比正常稍慢
1、react自身实现了一套自己的事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等,虽然和原生的是两码事,但也是基于浏览器的事件机制下完成的。 2、React 上注册的事件最终会绑定在document这个 DOM 上,而不是 React 组件对应的 DOM(减少内存开销就是因为所有的事件都绑定在 document 上,其他节点没有绑定事件) 3、React 自身实现了一套事件冒泡机制,所以这也就是为什么我们 event.stopPropagation()无效的原因。 4、React 通过队列的形式,从触发的组件向父组件回溯,然后调用他们 JSX 中定义的 callback 5、React 有一套自己的合成事件 SyntheticEvent
React Fiber 是 Facebook 花费两年余时间对 React 做出的一个重大改变与优化,是对 React 核心算法的一次重新实现。 在react中,主要做了以下的操作: 1、为每个增加了优先级,优先级高的任务可以中断低优先级的任务。然后再重新,注意是重新执行优先级低的任务 2、增加了异步任务,调用requestIdleCallback api,浏览器空闲的时候执行 dom diff树变成了链表,一个dom对应两个fiber(一个链表),对应两个队列,这都是为找到被中断的任务,重新执行 3、从架构角度来看,Fiber 是对 React核心算法(即调和过程)的重写 4、从编码角度来看,Fiber是 React内部所定义的一种数据结构,它是 Fiber树结构的节点单位,也就是 React 16 新架构下的虚拟DOM
1、跟Vue一致,React通过引入Virtual DOM的概念,极大地避免无效的Dom操作,使我们的页面的构建效率提到了极大的提升而diff算法就是更高效地通过对比新旧Virtual DOM来找出真正的Dom变化之处 运作流程主要分为三层:tree层、component层、element层 1、tree层:tree层对于DOM节点的跨层级移动的操作忽略,只对相同层级的DOM节点进行比较,一旦发现节点不存在,直接删除该节点以及以下的所有子节点 2、component层:遇到同一个类型的组件遵循tree diff,进行层级对比,遇到不同类型的组件,直接将这个不同的组件判断为脏组件,并且替换该组件之下的所有的子节点,当知道这个组件的虚拟DOM没有任何变化,就可以手动使用,shouldComponentUpdate来判断是否需要进行diff,进一步提升了diff效率和性能 3、element层:低于同一层级,面对全新节点,可以实现插入的操作;面对多余的节点,执行删除操作;面对换位的节点,执行移动的操作
1、border:给定一个宽度和高度都为 0 的元素,其 border 的任何值都会直接相交,我们可以利用这个交点来创建三角形。也就是说,border属性是三角形组成的,如果想要一个指向右面的三角形,可以让 border 的左边可见,其他边都设置为透明: 2、linear-gradient:linear-gradient 需要结合 background-image 来实现三角形,下面就来逐步使用渐变实现一个三角形。 3、clip-path:clip-path 就是使用它来绘制多边形(或圆形、椭圆形等)并将其定位在元素内。实际上,浏览器不会绘制 clip-path 之外的任何区域,因此我们看到的是 clip-path 的边界。 4transform: rotate 配合 overflow: hidden 绘制三角形
1、根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。 2、eact中props,state值的变化,会导致组件重新渲染。使用shouldComponentUpdate就是为了减少render不必要的渲染。 返回布尔值,然后做 Virtual DOM 比较,并得出是否需要做真实 DOM 更新
1、在使用git管理版本的项目中,当完成一个特性的开发,并将其合并到master分支,就会使用到git rebase 和git merge 2、两个都有相同的作用:将一个分支的提交合并到另一个分支上,但是原理不一样 3、Git merge将当前分支合并到指定分支:git merge xxx;git rebase合并到指定的commit上:git rebase -I <commit > 4、通过merge合并的分支会新增一个merge commit,,然后将两个分支的历史联系起来;rebase会将整个分支移动到另一个分支上,有效的整合了所有分支上的提交
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。 Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
1、实际上它只是一层对真实DOM的抽象,以JavaScript对象(VNode节点)作为基础的树,用对象的属性来描述节点,最终可以通过一系列操作时这棵树映射到真实环境上,创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应 2、通过JS模拟网页文档节点,生成JS对象树(虚拟DOM),然后再进行一步生成真实的DOM树,再绘制到屏幕。如果后面有内容发生改变,React会重新生成一棵全新的虚拟DOM树,再与前面的虚拟DOM树进行比对diff,把差异的部分打包成patch,再应用到真实DOM,然后渲染到屏幕浏览器。 在虚拟dom计算的时候diff和key之间有什么关系: 1、React需要同时维护两棵虚拟DOM树:一棵表示当前的DOM结构,另一棵在React状态变更将要重新渲染时生成。React通过比较这两棵树的差异,决定是否需要修改DOM结构,以及如何修改。这种算法称作Diff算法。 2、key 当同一层级的某个节点添加了对于其他同级节点唯一的key属性,当它在当前层级的位置发生了变化后。react diff算法通过新旧节点比较后,如果发现了key值相同的新旧节点,就会执行移动操作(然后依然按原策略深入节点内部的差异对比更新),而不会执行原策略的删除旧节点,创建新节点的操作。这无疑大大提高了React性能和渲染效率。
1、当前组件没有子节点数据类型就是undefined, 2、有一个子节点数据类型就是object 。 3、有多个子节点的时候才会是array ,只有在多个节点的时候才可以直接调用map方法,react资深提供了一个react.children.map()方法,可以安全遍历子节点对象。
1、Immutable.js就是react中用来做性能优化的 2、在react中使用immutable可以减少页面的一些不必要的渲染,不需要像react中进行深度对比而进行渲染 3、immutable可以直接快速的进行对比,完成渲染,提升了渲染的效率,降低了性能的消耗 4、Immutable不可改变的,在计算机中,即指一旦创建,就不能再被更改的数据 对 Immutable对象的任何修改或添加删除操作都会返回一个新的 Immutable对象 Immutable 实现的原理是 Persistent Data Structure(持久化数据结构): 1、用一种数据结构来保存数据 2、当数据被修改时,会返回一个对象,但是新的对象会尽可能的利用之前的数据结构而不会对内存造成浪费
1、Redux-thunk这个中间件支持异步操作 2、执行异步的操作首先需要下载一个thunk,通过thunk来进行异步的一个操作,支持异步操作,可以使用dispatch和getState来进行数据的获取或状态 3、Redux是一个状态管理库,redux的核心是store,actions,reducers三个部分 4、通过dispatch发放到任务的actions中,在actions中返回一个promise对象,再通过dispatch派发到reducers中 5、在reducers中通过传递type和data来进行判读
1、同步action:执行了dispatch函数之后,对应的reducer纯函数立即得到执行,reducer执行完了之后,state立即就改变了,此时用store.getState函数,取到的是最新的state值; 2、异步action:原则上redux并没有提供异步action的处理方案,异步的action需要依赖第三方的中间件解决(如redux-thunk),dispatch了一个异步action(本质上是dispatch的一个函数)之后,目标state并不会立即响应,而是要看异步函数内部的逻辑,来决定state什么时候响应。 3、区别: 首先区别redux和react-redux,redux是一个单独的模块,在其他框架中也能使用,而react-redux是为react管理数据而生。 redux的设计思想:web应用是一个状态机,视图与状态是一一对应的,所有的状态,保存在一个对象里面
1、使用redux-thunk的代码,当我们返回的是函数时,store会帮我们调用这个返回的函数,并且把dispatch暴露出来供我们使用。对于redux-thunk的整个流程来说,它是等异步任务执行完成之后,我们再去调用dispatch,然后去store去调用reduces 2、使用了redux-saga的代码,当我们dispatch的action类型不在reducer中时,redux-saga的监听函数takeEvery就会监听到,等异步任务有结果就执行put方法,相当于dispatch,再一次触发dispatch。对于redux-saga的整个流程来说,它是等执行完action和reducer之后,判断reducer中有没有这个action 区别: 1、redux-thunk和redux-saga处理异步任务的时机不一样。对于redux-saga,相对于在 2、redux的action基础上,重新开辟了一个 async action的分支,单独处理异步任务 3、saga 自己基本上完全弄了一套 asyc 的事件监听机制,代码量大大增加,从我自己的使用体验来看 redux-thunk 更简单,和 redux 本身联系地更紧密。
1、for循环就是通过下标,对循环中的代码反复执行,功能强大,可以通过index取得元素。处理比较复杂的处理的时候比较方便 2、forEach()循环方法用于调用数组的每个元素,并将元素传递给回调函数。foreach有的也叫做增强for循环,forEach其实是for循环的一个特殊简化版。forEach循环对于空的数组是不会执行回调函数的。 区别: 1、遍历:for循环按照顺序进行遍历,forEach使用iterator迭代器遍历 2、数据结构:for循环是随机访问元素,foreach是顺序链表访问元素 3. 性能上:对于数组arraylist来说,是顺序表,使用for循环可以进行顺序访问,速度比较快;使用foreach循环会比for循环稍微慢一点。对于linedlist来说,是单链表,使用for循环每次都要从第一个元素读取next域来读取,速度非常慢;使用foreach可以直接读取当前的节点,数据较快。
在移动端web开发中,UI设计稿中设置边框为1像素,前端在开发过程中如果出现border:1px,测试会发现在某些机型上,1px会比较粗,即是较经典的移动端1px像素问题 方案: 1、小数:0.5px,相信浏览器肯定是会慢慢支持的;目前而言,如果能用的话,可以hack一下; 2、阴影,border-img的方案不建议使用 3、背景图片和缩放可以在项目中配合使用,如单个线条使用缩放,四条框用背景图片模拟,额,如果要圆角的话,无能无力了 4、建议采用transform和伪类
1、弹性盒的项目设置flex-grow属性定义项目的放大比例,默认值为0,值越大,放大越厉害,且不支持负值; 2、而flex-shrink属性定义项目的缩小比列,默认值为1,数值越大,缩小越厉害,同样不支持负值; 3、flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间,浏览器根据这个属性,计算主轴是否有多余空间。他的默认值为auto,也就是项目的本来大小。
1、 Mixin是面向对象程序设计语言中的类,提供方法的实现,其他1的类可以访问mixin中的方法而不必称为其子类 2、 Vue中mixin是用来分发vue组件的可复用功能 3、 本质上就是一个js对象,可以包含组件中的任意功能选项,比如说data、component、methods、created等 4、 将公用的功能以对象的方式传入mixins选项中,当组件使用mixins对象时,所有的mixins对象的选项都被混入该组件本身的选项中
For in和for of都属于遍历 1、for in 遍历时数组的索引index,for of遍历的时数组的元素值 2、for in更适合遍历对象,也可以遍历数组,会存在一些问题;for of 数组,对象等一些拥有迭代器对象的集合 3、for in 总是得到对象的键或者数组、字符串的下标;for of得到的对象的值或者数组、字符串的值
1、发布订阅模式:订阅者(Subsciber)通过事件注册(Subscribe)将订阅事件提交到调度中心(Topic),调度中心保存好订阅者的注册信息(回调函数),每当发布者(Publisher)发布事件的时候,通过事件发布(Publish)将发布的消息提交到调度中心,然后调度中心统一处理订阅者注册该事件的消息(执行注册时的回调函数) 2、实现: //实例化一个发布订阅模式,多个new,可以做到事件隔离,正常一个项目一个就够了 const pub1 = new Pubsub() //调用 示例 pub1.topic("on-sleep) //创建一个睡觉的订阅主题 //同学1 订阅睡觉 pub1.subscribe("on-sleep",(a)=>{ console.log("sleep") console.log(a) }) //同学2 订阅睡觉 回调不同 pub1.subscribe("on-sleep",(a)=>{ console.log("sleep2”) console.log(a) }) setTimeout(()=>{ //时间差不多了,通知他们该睡觉了! pub1.publish("on-sleep",{info:"该睡觉啦!"}) },2000)
1、在一个浏览器中,看到的区域就是视口(viewport) 2、在PC端页面中,不需要对视口进行区分,因为布局视口和视觉视口是同一个 3、但在移动端,你布局的视口和可见的视口是不一样的因为移动端的网页窗口往往比较小,我们可能会希望一个大的网页在移动端可以完整的显示; 4、所以在默认情况下,移动端的布局视口是大于视觉视口的 5、所以在移动端,我们将视口分成三种情况 1、布局视口(layout viewport) 2、视觉视口(visual layout) 3、理想视口(ideal layout)
1、使用钩子函数useEffect可以实现组件的副作用。useEffect(希望执行的动作, [组件状态的列表]);第二个参数用来处理useEffect调用的时机,是一个数组,数组内是组件状态的列表。 2、useEffect模拟componentDidMount:当useEffect的第二个参数传入空列表时,相当于模拟生命周期函数componentDidMount。这个副作用仅在组件第一次挂载ui的时候调用一次。用它来模拟组件初次挂载时,访问api、获得数据: 3、useEffect模拟componentDidUpdate:如果在使用useEffect时不带上第二个参数,就相当于模拟了生命周期函数componentDidUpdate。每次渲染结束的时候都会被调用。 4、useEffect模拟componentWillUnmount,在useEffect中返回一个函数用于模拟component WillUnMount
1、setState用于设置状态对象 2、两个参数:nextState,将要设置的新状态,该状态会和当前的state合并;callback,可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用。 3、合并nextState和当前state,并重新渲染组件。setState是React事件处理函数中和请求回调函数中触发UI更新的主要方法。 4、replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除 5、两个参数:nextState,将要设置的新状态,该状态会替换当前的state。callback,可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。 ----------------------------------------------------------------------- 1. setState 是修改其中的部分状态,相当于 Object. assign,只是覆盖,不会减少原来的状态; 2. replaceState 是完全替换原来的状态,相当于赋值,将原来的 state 替换为另一个对象,如果新状态属性减少,那么 state 中就没有这个状态了。
当组件元素绑定onClick事件之后: 1、react会对事件先进行注册,将事件统一注册到document上 2、根据组件唯一的表示key来对事件函数进行存储 3、统一的指定,dispatchEvent回调函数 4、存储事件回调:react会将click这个事件统一存放在一个对象中,回调函数中存储采用键值对的方式存储在对象中,key是组件唯一标识id,value对应的事件就是回调函数,通过组件的key就能回到相对应的函数了。
1、垂直外边距合并:当两个存志外边距相遇时,将形成一个外边距,合并后的外边距高度等于两个发生合并的外边距的高度中的较大者 2、注意:只有普通的文档流中的块级元素的垂直外边距才会发生外边距合并,行内框,浮动框或者绝对定位之间的外边距不会合并 情况: 1、当相邻的元素垂直外边距合并时候:如果上边的元素有下外边距,下边的元素有上外边距,那么他们之间的垂直间距不是bottom和top之间的和,而是两者中较大者,这种现象被称为外边距塌陷 2、当嵌套块元素垂直外边距合并:如果父元素没有上内边距以及边框,那么父元素上外边距会与子元素的上外边距发生合并,合并后的外边距为两者中的较大者,就是父元素的上外边距为0,也会合并 解决方法:可以为父元素定义1像素的上边框或上内边距
1、使用 ‘use-deep-compare-effect’ :他可以进行深比较,使用方法也很简单, import useDeepCompareEffect from ‘use-deep-compare-effect’ 之后用useDeepCompareEffect 替换掉 原有的 useEffect 即可。 2、也可以使用 useRef这个钩子来解决上述问题,useRef的特性是跨渲染周期保存数据 3、用useRef保存了之前的数据, useEffect中的依赖以然为引用类型, 每次obj发生改变都会调用执行函数,但是执行函数中多了一个判断, prevObj是上一次渲染时obj的值, 用prevObj中的某个key与此次obj中的某个key做对比,满足条件后做其他操作
1、Event Loop是JavaScript中的一种机制,用于处理异步事件和回调函数,它是JavaScript运行时环境的一个循环,不断从任务队列中取出任务并执行,直到任务队列为空。 2、Event Loop工作原理: a、执行同步代码,将异步操作放入任务队列中 b、当主线任务空闲的时候,Event Loop会检查任务队列中是否有任务 c、如果有任务,则取出任务并且执行 d、执行完成任务以后,再次检查任务队列,重复b和c的操作 3、Event Loop是JavaScript中非常重要的一个概念,它使得JavaScript可以处理异步操作,提高了程序的性能和用户体验。
1、BOM就是指浏览器对象模型,提供了独立于内容与浏览器窗口进行交互的对象 2、它的作用就是跟浏览器做一些交互效果,比如如何进行页面的后退、前进、刷新、浏览器的窗口发生变化、滚动条的滚动,以及获取客户的一些信息,像浏览器品牌版本,屏幕分辨率 3、window:BOM的核心对象是window,它表示浏览器的一个实例,在浏览器中,window对象有双重角色,也就是浏览器窗口的一个接口,又是全局对象,因此,所有在全局作用域中声明的变量,函数都会编程window对象的属性和方法 4、local: 5、navigator:主要用来获取浏览器的属性,区分浏览器类型。属性较多,且兼容性比较复杂 6、screen:保存的纯粹是客户端能力信息,也就是浏览器窗口外面的客户端显示器的信息,比如像素宽度和像素高度 7、history:对象主要用来操作浏览器URL的历史记录,可以通过参数向前,向后,或者向指定URL跳转
常见的浏览器内核有以下几种:
Trident内核:是微软开发的浏览器内核,主要用于Internet Explorer浏览器。
Gecko内核:是Mozilla Firefox浏览器的内核,也被其他浏览器所采用。
WebKit内核:是苹果公司开发的浏览器内核,主要用于Safari浏览器和Chrome浏览器。
Blink内核:是Google公司基于WebKit内核开发的浏览器内核,主要用于Chrome浏览器和Opera浏览器。 5、区别: 1、主要在于其渲染引擎的不同,从而导致了浏览器的性能、兼容性、安全性等方面的差异。 2、Trident内核在处理CSS和JavaScript方面相对较慢 3、Gecko内核则更加注重安全性和隐私保护 4、WebKit内核则以其快速的渲染速度和良好的兼容性著称 5、Blink内核则在性能和稳定性方面有所提升。
1、浏览器的渐进增强和优雅降级都是为了解决不同的浏览器或者设备之间的兼容性问题 2、渐进增强就是指在设计和开发网站或应用程序的时候,首先考虑基本功能的实现,然后逐步添加更加高级的功能和交互的效果,以适应不同的浏览器和设备的能力 3、渐进增强更加注重于向前兼容性,就算在比较老的浏览器上也可以正常使用 4、优雅降级就是指在设计和开发网站或者应用程序的时候,首先考虑高级功能和交互效果的实现,然后逐步降低要求,用来适应较老或者不支持这些功能的浏览器和设备 5、优雅降级就是强调向后兼容性,也就是说在较新的浏览器上能够享受更好的用户体验
1、尽量减少HTTP的请求次数:合并js、css等 2、 压缩文件:压缩CSS、JavaScript、HTML等文件,减少文件大小,提高网页加载速度。 3、 图片优化:使用适当的图片格式,压缩图片大小,减少图片数量,提高网页加载速度。 4、CDN加速:使用CDN(内容分发网络)加速网站访问速度,将网站内容分发到全球各地的服务器上,使用户可以从最近的服务器获取内容。 5、缓存优化:使用浏览器缓存和服务器缓存,减少重复请求,提高网站访问速度。 6、前端优化:减少HTTP请求,使用CSS Sprites、合并JavaScript文件等技术,减少页面加载时间。 7、数据库优化:优化数据库查询语句,使用索引,减少数据库查询时间,提高网站访问速度。 8、服务器优化:使用高性能服务器,优化服务器配置,提高网站访问速度。 9、去除冗余代码:去除无用的代码,减少页面大小,提高网站访问速度。 10、响应式设计:使用响应式设计,使网站可以适应不同的设备和屏幕大小,提高用户体验。
1、Link和@import都是用于引入外部资源的方法 2、不同: 1、加载顺序的不同:Link标签在加载页面的时候就会同时加载外部的资源,而@import在页面加载完毕之后才会加载外部资源 2、兼容性的不同:Link标签在所有浏览器中都被支持,而@import在一些旧的版本浏览器中可能不被支持 3、作用范围不同:Link标签可以用于引入各种类型的资源,包括CSS、JavaScript、图像等,而@import只能用于引入css文件 4、优先级不同:Link标签的优先级高于@import,因此如果同一个样式表这两种方法都使用的话,那么Link就会覆盖@import的样式
1、BFC就是块级格式化上下文,是指的独立的渲染区域,其中的元素按照一定的规则进行布局和渲染 2、BFC特点: 1、内部元素在垂直方向上一个接一个的排列,形成一个垂直流 2、BFC区域不会与浮动元素重叠 3、BFC区域不会与外部元素的margin发生重叠 4、BFC区域可以包含浮动元素 5、BFC区域可以防止元素被父元素的边框所覆盖 3、触发条件: 1、根元素或者包含根元素的元素 2、浮动元素float不等于none 3、绝对定位position为absoulute或者fixed 4、display是inline-block、table-cell、table-caption、flex、inline-flex 5、overflow不为visible的块级元素
1、在js中,null和undefined都是表示没有值 2、区别: 1、undefined表示一个变量声明了但是没有被赋值,或者对象属性不存在 2、null表示一个变量已经被赋值为null,或者对象属性被赋值为null 3、在条件语句中,undefined和null都会被转换为false,但是在比较运算符中,行为不同,undefined与任何值包括本身比较都是false,但是null只在和undefined比较是为true
1、CSS中元素脱离文档流的方式有以下几种: 1. 浮动(float):将元素从文档流中移出来,使其能够与其他元素并排显示。 2. 绝对定位(position: absolute):将元素从文档流中移出来,并相对于其最近的已定位祖先元素进行定位。 3. 固定定位(position: fixed):将元素从文档流中移出来,并相对于浏览器窗口进行定位。 4. 弹性布局(display: flex):通过设置父元素为弹性容器,使其子元素能够脱离文档流,并按照一定的规则进行排列。 5. 网格布局(display: grid):通过设置父元素为网格容器,使其子元素能够脱离文档流,并按照一定的规则进行排列。 2、定位的方式有以下几种: 1. 相对定位(position: relative):相对于元素在文档流中的位置进行定位,不会影响其他元素的位置。 2. 绝对定位(position: absolute):相对于最近的已定位祖先元素进行定位,如果没有已定位的祖先元素,则相对于文档的 body 元素进行定位。 3. 固定定位(position: fixed):相对于浏览器窗口进行定位,不会随着页面滚动而移动。
3、区别: 相对定位和绝对定位的区别在于,相对定位不会脱离文档流,而绝对定位会脱离文档流。固定定位与绝对定位类似,但它相对于浏览器窗口进行定位,不会随着页面滚动而移动。
1、同步和异步是指在进行任务处理的时候,任务的执行方式不同 2、同步任务指的是任务按照顺序依次执行,每个任务必须等待前一个任务完成之后才能执行,在同步执行中,任务的执行是阻塞的,也就是说在执行任务的时候会一直等待任务完成后才会继续执行下一个任务 3、异步执行是指任务不按照顺序依次执行,每一个任务可以独立执行,不需要等待前一个任务完成。在异步任务的执行中,任务的执行是非阻塞的,也就是执行任务是不会等待任务完成,而是继续执行下一个任务 4、同步和异步的区别就在于任务的执行方式,同步执行就是按照顺序依次执行,而异步执行时独立执行,不需要等待前一个任务的完成,在实际中,异步执行通常能够提高程序的响应速度和效率
伪类和伪元素的区别: 1. 伪类用于描述元素的一些特殊状态,如:hover、:active、:focus等,而伪元素用于创建一些不在文档树中的元素,如::before、::after等。 2. 伪类在CSS2中以单冒号(:)表示,伪元素以双冒号(::)表示。 3. 伪类可以用于任何元素,而伪元素只能用于某些特定的元素。 4. 伪类可以用于选择器的任何位置,而伪元素只能用于选择器的最后一个位置。 CSS3新增的选择器包括: 1. 属性选择器:[attr=value]、[attr~=value]、[attr|=value]、[attr^=value]、[attr$=value]、[attr*=value] 2. 伪类选择器::nth-child()、:nth-last-child()、:nth-of-type()、:nth-last-of-type()、:first-child、:last-child、:first-of-type、:last-of-type、:only-child、:only-of-type、:not() 3. 伪元素选择器:::before、::after、::first-letter、::first-line、::selection 4. 组合选择器:A B、A > B、A + B、A ~ B
Promise和async/await都是用于处理异步操作的方式,但是它们之间有一些区别。
语法:Promise是一种基于回调函数的异步编程方式,使用.then()和.catch()方法来处理异步操作的结果。而async/await是ES2017引入的异步编程方式,使用async和await关键字来处理异步操作的结果。
可读性:async/await相对于Promise来说更加易读易懂,代码更加简洁明了。
错误处理:在Promise中,错误处理需要使用.catch()方法来捕获错误。而在async/await中,可以使用try/catch语句来捕获错误。
链式调用:Promise可以链式调用多个异步操作,而async/await只能在一个异步操作完成后再进行下一个异步操作。 总的来说,async/await是一种更加直观、易读、易懂的异步编程方式,但是在某些情况下,Promise也是非常有用的。
重排和重绘是浏览器渲染页面时的两个重要概念。 重排(reflow)是指当页面中的元素发生布局变化时,浏览器需要重新计算元素的位置和大小,并重新排列页面的布局。重排会导致页面的重新布局和重新渲染,是一种比较耗费性能的操作。 重绘(repaint)是指当页面中的元素的样式发生变化时,浏览器需要重新绘制元素的样式。重绘不会改变页面的布局,只会重新绘制元素的样式,因此比重排的性能开销要小。 触发重排的条件包括: 1. 页面初次渲染 2. 浏览器窗口大小发生变化 3. 元素的位置、大小、内容发生变化 4. 元素的样式发生变化 5. 页面滚动 触发重绘的条件包括: 1. 元素的样式发生变化 2. 元素的背景色、边框颜色、文本颜色等属性发生变化 3. 元素的透明度发生变化 4. 元素的文本内容发生变化 总的来说,重排和重绘都会影响页面的性能,因此在开发过程中需要尽量避免频繁触发重排和重绘。可以通过合理的布局设计、使用 CSS3 动画代替 JavaScript 动画等方式来优化页面性能。
1、原型链继承:通过将子类的原型对象指向父类的实例对象来实现继承。 2、构造函数继承:指通过在子类构造函数中调用父类构造函数来实现继承。 3、组合继承:组合继承指的是将原型链和构造函数继承结合起来的一种继承方式,实现方式就是通过在子类构造函数中调用父类构造函数来继承父类的属性,并将子类的原型对象指向一个新的父类实例对象来继承的方法。 4、ES6中的class继承:通过使用extends关键字来继承父类,并使用super来调用父类的构造函数和方法。
严格模式是 JavaScript 的一种执行模式,它强制执行一些限制,以帮助开发者编写更加健壮的代码。在严格模式下,一些不安全的行为会被禁止,一些错误也会被抛出。 严格模式下的限制包括: 1. 禁止使用未声明的变量。 2. 禁止删除变量、函数或函数参数。 3. 禁止使用 eval() 函数创建变量或函数。 4. 禁止使用 with 语句。 5. 禁止在函数内部使用 arguments.callee 和 arguments.caller。 6. 禁止对只读属性赋值。 7. 禁止扩展内置对象的原型。 8. 禁止在函数内部重复声明变量。 严格模式可以通过在代码的开头添加 "use strict"; 来启用。在严格模式下编写代码可以帮助开发者避免一些常见的 JavaScript 错误,并提高代码的可读性和可维护性。
从数组的最后一个元素开始,向前遍历数组。
随机生成一个 0 到当前遍历的索引值之间的整数。
将当前遍历的元素与随机生成的索引所对应的元素交换位置。
继续向前遍历数组,重复步骤 2 和 3,直到遍历到数组的第一个元素为止。
Vue的自定义指令钩子函数包括:bind、inserted、update、componentUpdated、unbind。 1、 bind:只调用一次,指令第一次绑定到元素时调用,可以在这里进行一次性的初始化设置。 2、 inserted:被绑定元素插入父节点时调用,但可能在其父节点还未插入到DOM中。 3、 update:被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。 4、 componentUpdated:被绑定元素所在模板完成一次更新周期时调用。 5、 unbind:只调用一次,指令与元素解绑时调用。 我曾经使用自定义指令实现了一个点击外部区域关闭弹窗的功能。具体实现方式是在bind钩子函数中绑定一个document的click事件,当点击事件触发时判断点击的区域是否在弹窗内部,如果不是则关闭弹窗。在unbind钩子函数中解绑该事件。
1、keep-alive 可以通过当前页面的BeforeRouter(to,from,next) 当to ===“B” & from ===”A” keep-alive的meta中参数为true 当to ===“C” & from ===”A” keep-alive的meta中参数为false 2、生命周期,获取 this.router.meta 修改页面的meta里面的参数,keep-alive回根据meta中的参数决定是否对组件进行缓存
1、Vue2和Vue3中的响应式原理都是基于Object.defineProperty实现的。当数据发生变化时,会自动触发视图的更新。但是Vue3中对响应式原理进行了优化,使用了Proxy代理对象来替代了Object.defineProperty,使得响应式系统更加高效和灵活。 2、Vue2中的响应式原理是在实例化Vue对象时,会对data中的每个属性进行递归地遍历,将每个属性都转换为getter和setter,当属性被访问或修改时,会触发getter和setter方法,从而实现响应式更新。 3、Vue3中的响应式原理使用了Proxy代理对象,它可以拦截对象的访问和修改操作,从而实现响应式更新。Vue3中的响应式系统还支持了reactive函数,可以将一个普通对象转换为响应式对象,使得开发者可以更加灵活地使用响应式系统。 4、总的来说,Vue3中的响应式系统相比Vue2更加高效和灵活,但是在使用上也有一些区别,需要开发者进行适当的学习和调整。
1、将所有权限按照等级,划分为一级权限和二级权限,生成相对的tree数,获取每个权限的id,将每个id放到一个列表中,赋值给角色的权限外键 2、按钮权限是,每个按钮绑定一个处理方法,当登录的用户,返回的角色id没有对应这个按钮的权限方法时候,会对按钮进行隐藏处理
第一周
性能优化:Vue3在性能方面进行了大量的优化,包括编译器优化、响应式系统优化、虚拟DOM优化等,使得Vue3的性能比Vue2更快。
Composition API:Vue3引入了Composition API,它是一种新的API风格,可以更好地组织和重用组件逻辑,使得代码更加清晰和易于维护。
TypeScript支持:Vue3对TypeScript的支持更加完善,可以更好地进行类型检查和代码提示,提高代码的可靠性和可维护性。
更好的Tree-Shaking:Vue3采用了更加现代的ES模块语法,可以更好地支持Tree-Shaking,减小打包体积。
更好的适配性:Vue3对Web和移动端的适配性更加优秀,可以更好地支持PWA和SSR等技术。
更好的错误处理:Vue3引入了错误处理机制,使得开发者能够更加容易地定位和解决错误。
1、vue3中组件通信的流程分为父传子、子传父两种方式 2、父传子: 父组件通过props向子组件传递数据,子组件通过props接收数据。父组件可以在模板中使用子组件,并且通过v-bind指令将数据传递给子组件,子组件可以在props中声明接收的数据类型和默认值 3、子传父: 子组件通过$emit的方法向父组件发送事件,父组件通过v-on指令监听子组件发送的事件,子组件可以通过$emit方法来传递给父组件
1、Apply、call和bind都是JavaScript中用于改变函数执行上下文的方法。 2、allpy和call的作用都是一样的,都是改变函数的执行上下文,就是改变函数内部的this指向,它们的区别就在于传参的方式不同,apply接收一个数组作为参数,call接收多个参数 3、bind方法也是用于改变函数的执行上下文,但是他不会立即执行函数,而是返回一个新的函数,这个新的函数的this指向被绑定的对象 4、总的来说,apply、call和bind都是用于改变函数执行上下文的方法,它们的区别在于传参的方式和返回值。apply和call会立即执行函数,而bind会返回一个新的函数。
1、原型是JavaScript中的一个重要概念,它是一个对象,其他对象可以通过它来实现属性和方法的继承。每个JavaScript对象都有一个原型对象,它定义了该对象的属性和方法。如果在当前对象中找不到某个属性或方法,JavaScript引擎会自动查找该对象的原型对象,直到找到为止。 2、原型链是由原型对象组成的链式结构,它是JavaScript中实现继承的一种方式。当一个对象需要访问另一个对象的属性或方法时,JavaScript引擎会沿着原型链向上查找,直到找到该属性或方法为止。如果在整个原型链中都找不到该属性或方法,则返回undefined。 3、在JavaScript中,每个对象都有一个proto属性,它指向该对象的原型对象。当我们访问一个对象的属性或方法时,JavaScript引擎会先查找该对象自身是否有该属性或方法,如果没有,则会沿着原型链向上查找,直到找到为止。如果在整个原型链中都找不到该属性或方法,则返回undefined。 4、总之,原型和原型链是JavaScript中非常重要的概念,它们可以帮助我们实现对象之间的继承和共享属性和方法。
1、ES6中的Generator是一种特殊的函数,它可以在执行过程中暂停并保存当前的状态,然后在需要的时候恢复执行。Generator函数通过yield关键字来实现暂停和恢复执行的功能。 2、Generator函数可以用于异步编程,可以通过yield关键字来暂停异步操作的执行,等待异步操作完成后再继续执行。Generator函数还可以用于实现迭代器,可以通过yield关键字来返回一个值,然后在下一次调用时继续执行。 3、另外,Generator函数还可以接受参数,可以在调用Generator函数时传入参数,然后在函数内部使用这些参数。 4、总之,Generator函数是一种非常强大的工具,可以用于实现异步编程、迭代器等功能,可以大大简化代码的编写和维护。
浏览器事件循环和Node.js的事件循环有以下几个区别: 1. 浏览器事件循环是单线程的,而Node.js的事件循环是多线程的。 2. 浏览器事件循环中的任务分为宏任务和微任务两种,而Node.js的事件循环中只有宏任务。 3. 浏览器事件循环中的微任务包括Promise、MutationObserver和process.nextTick,而Node.js的事件循环中没有process.nextTick,但有setImmediate。 4. 浏览器事件循环中的宏任务包括script、setTimeout、setInterval、I/O、UI rendering等,而Node.js的事件循环中的宏任务包括I/O、定时器、setImmediate等。 5. 浏览器事件循环中的任务执行顺序是先执行所有微任务,再执行一个宏任务,而Node.js的事件循环中的任务执行顺序是先执行所有的I/O和定时器任务,再执行setImmediate任务。 总的来说,浏览器事件循环和Node.js的事件循环都是基于事件驱动的模型,但是它们的实现方式和任务执行顺序有所不同。
浏览器缓存机制是指浏览器在访问网页时,会将一些静态资源(如图片、CSS、JS等)缓存到本地,以便下次访问同一网页时可以直接从本地缓存中读取,从而提高网页加载速度和用户体验。 1、浏览器缓存机制分为两种:强缓存和协商缓存。 2、强缓存是指浏览器在第一次请求资源时,会将资源的过期时间(Expires)或最大缓存时间(Cache-Control)存储在本地,下次请求时会先判断本地缓存是否过期,如果没有过期则直接从本地缓存中读取资源,不会向服务器发送请求。 3、协商缓存是指浏览器在第一次请求资源时,会将资源的标识(ETag或Last-Modified)存储在本地,下次请求时会向服务器发送请求,服务器会根据资源的标识判断资源是否有更新,如果没有更新则返回304状态码,浏览器直接从本地缓存中读取资源。 4、浏览器缓存机制可以有效减少网络请求,提高网页加载速度和用户体验,但也可能导致资源更新不及时,需要在开发中合理使用缓存机制,避免出现问题。
浏览器内核又可以分为两个部分:渲染引擎和JS引擎 1、渲染引擎:负责取得网页的内容(HTML,XML,图像等等)、整理讯息(加入css等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器内核的不同对于网页的语法解释会有所不同,所以渲染的效果也不同 2、JS引擎:则是解析JavaScript语言,执行JavaScript语言来实现网页的动态效果 浏览器内核的不同会影响浏览器的渲染效果、速度、兼容性等方面,因此选择合适的浏览器内核对于浏览器的性能和用户体验都非常重要。
Vue的响应式原理是通过数据劫持来实现的。当一个Vue实例被创建时,Vue会对其所有的数据进行监听,当数据发生变化时,Vue会自动更新视图。具体实现方式如下: 1. Vue会在实例化时对data对象进行遍历,将每个属性转换为getter/setter,这样当属性被访问或修改时,Vue能够监听到。 2. 当数据发生变化时,Vue会通过setter方法监听到变化,并通知所有依赖该数据的组件进行更新。 3. Vue使用了一个Dep类来管理所有的依赖关系,每个数据都会对应一个Dep实例,当数据发生变化时,Dep会通知所有依赖该数据的Watcher实例进行更新。 4. Watcher实例是Vue中的一个重要概念,它会在组件渲染时被创建,并且会在数据发生变化时被通知进行更新。每个Watcher实例都会与一个Dep实例关联,当数据发生变化时,Dep会通知所有关联的Watcher实例进行更新。 总的来说,Vue的响应式原理是通过数据劫持、Dep类和Watcher实例来实现的,它能够自动监听数据变化并更新视图,大大简化了开发过程。
1、Methods 和 watch 都是 Vue.js 中用于监听数据变化的方式 2、Methods 是 Vue.js 中的一个选项,用于定义组件中的方法。它可以接受参数,执行一些操作,并返回结果。当组件中的数据发生变化时,如果需要重新计算某些数据,就需要在方法中重新计算并返回结果。 3、Watch 是 Vue.js 中的一个特殊选项,用于监听数据的变化并执行一些操作。它可以监听一个或多个数据的变化,并在数据变化时执行指定的回调函数。当需要在数据变化时执行一些异步操作或复杂的计算时,就需要使用 watch。 4、区别在于: 1、Methods 是用于定义组件中的方法,可以接受参数并执行一些操作,返回结果。而 watch 是用于监听数据变化并执行一些操作,不能接受参数,也不能返回结果。 2、Methods 通常用于计算属性或处理事件等简单的操作,而 watch 通常用于处理复杂的异步操作或计算,或者需要监听多个数据变化的情况。
Computed是Vue.js中的一个计算属性,它也可以在模板中调用,但是它的实现方式和Methods不同。Computed是基于依赖缓存的,也就是说,只有当依赖的数据发生变化时,才会重新计算。如果依赖的数据没有发生变化,那么Computed会直接返回缓存中的结果,从而提高了性能。
Virtual DOM是一种用于优化Web应用程序性能的技术。它是一个轻量级的JavaScript对象,它模拟了真实DOM的层次结构和属性,并且可以在内存中进行操作,而不是直接操作真实DOM。当Virtual DOM发生变化时,它会与真实DOM进行比较,只更新需要更新的部分,从而减少了DOM操作的次数,提高了应用程序的性能。 Virtual DOM的优点包括: 1. 提高应用程序的性能:由于Virtual DOM只更新需要更新的部分,因此减少了DOM操作的次数,提高了应用程序的性能。 2. 简化应用程序的开发:由于Virtual DOM可以在内存中进行操作,因此可以更轻松地进行应用程序的开发和测试。 3. 提高应用程序的可维护性:由于Virtual DOM可以更轻松地进行应用程序的开发和测试,因此可以提高应用程序的可维护性。 总之,Virtual DOM是一种非常有用的技术,可以帮助我们提高Web应用程序的性能和可维护性。
1、nextTick是Vue.js中的一个异步方法,它的作用是在下一次DOM更新循环结束之后执行指定的回调函数。nextTick的主要作用是在Vue.js更新DOM之后,立即执行一些操作,例如更新数据后立即获取DOM元素的尺寸或位置等。 2、nextTick的实现原理是利用了JavaScript的事件循环机制。当Vue.js更新DOM时,它会将所有的DOM更新操作放入一个队列中,然后等待下一次事件循环时执行。而nextTick方法就是将指定的回调函数放入这个队列中,等待下一次事件循环时执行。 3、nextTick的使用场景比较广泛,例如在Vue.js中使用$nextTick方法可以在DOM更新后立即执行一些操作,例如获取DOM元素的尺寸或位置等。另外,在Vue.js中使用nextTick方法也可以解决一些异步更新数据的问题,例如在更新数据后立即获取更新后的数据。 4、总之,nextTick是Vue.js中非常重要的一个异步方法,它可以帮助我们在DOM更新后立即执行一些操作,从而提高应用程序的性能和用户体验。
Webpack是一个现代化的JavaScript应用程序打包工具。它可以将多个JavaScript文件、CSS文件、图片等静态资源打包成一个或多个bundle文件,以便于在浏览器中加载和使用。
Webpack的主要功能包括: 1. 模块化管理:Webpack支持CommonJS、AMD、ES6等多种模块化规范,可以将多个模块打包成一个文件,减少HTTP请求次数,提高页面加载速度。 2. 代码转换:Webpack可以将ES6、TypeScript、CoffeeScript等高级语言转换成浏览器可识别的JavaScript代码。 3. 代码分割:Webpack可以将应用程序分割成多个chunk,实现按需加载,提高页面加载速度。 4. 资源管理:Webpack可以处理CSS、图片、字体等静态资源,将它们打包成一个或多个文件,并且可以对它们进行压缩、优化等操作。 5. 插件系统:Webpack提供了丰富的插件系统,可以实现各种自动化操作,如代码压缩、文件复制、HTML生成等。 总之,Webpack是一个非常强大的工具,可以帮助开发者更好地管理和打包JavaScript应用程序,提高开发效率和用户体验。
1、GET和POST是HTTP协议中常用的两种请求方法 2、区别: 1. GET请求方法是用于获取资源,而POST请求方法是用于提交数据。 2. GET请求方法的数据会附加在URL后面,以问号“?”分隔,参数之间以“&”符号分隔,而POST请求方法的数据则包含在请求体中。 3. GET请求方法的数据传输量较小,一般不超过2KB,而POST请求方法的数据传输量较大,可以传输任意大小的数据。 4. GET请求方法的数据可以被缓存,可以被收藏为书签,可以被浏览器历史记录记录,而POST请求方法的数据不会被缓存,也不能被收藏为书签,也不会被浏览器历史记录记录。 5. GET请求方法的安全性较低,因为数据会被暴露在URL中,容易被截获和篡改,而POST请求方法的安全性较高,因为数据不会被暴露在URL中,只有请求体中的数据才能被截获和篡改。
1、HTTP是超文本传输协议,是一种用于传输数据的协议,它是明文传输的,数据容易被窃听和篡改。 2、而HTTPS是在HTTP的基础上加入了SSL/TLS协议,通过加密和认证技术保证数据的安全性。HTTPS使用的是加密传输,数据传输过程中会进行加密,保证数据的机密性和完整性。 3、具体来说,HTTPS在传输数据之前会先进行SSL/TLS握手,建立安全通道,然后再进行数据传输。SSL/TLS协议使用了非对称加密和对称加密两种加密方式,非对称加密用于建立安全通道,对称加密用于加密数据传输。 4、在SSL/TLS握手过程中,服务器会向客户端发送自己的公钥,客户端使用该公钥加密一个随机数,然后发送给服务器,服务器使用自己的私钥解密该随机数,然后使用该随机数生成对称密钥,用于加密数据传输。 5、HTTPS相对于HTTP来说,具有更高的安全性和保密性,适用于需要保护用户隐私和敏感信息的网站,如银行、电商等网站。
TCP协议需要进行三次握手来建立连接,主要是为了确保通信双方都能够正常收发数据。 具体原因如下: 1. 第一次握手:客户端向服务器发送连接请求报文段,服务器收到请求后会回复一个确认报文段,表示已经收到了客户端的请求。 2. 第二次握手:服务器收到客户端的请求后,会向客户端发送一个确认报文段,表示已经收到了客户端的请求,并准备好了与客户端进行通信。 3. 第三次握手:客户端收到服务器的确认报文段后,会向服务器发送一个确认报文段,表示已经收到了服务器的确认,并准备好了与服务器进行通信。 4、通过三次握手,可以确保通信双方都能够正常收发数据,并且可以避免因网络延迟或丢包等问题导致连接失败或数据传输错误的情况发生。同时,三次握手还可以防止因网络中的恶意攻击或误传等问题导致的安全问题。
Proxy代理是一种网络应用程序,它充当客户端和服务器之间的中介。它的原理是在客户端和服务器之间建立一个代理服务器,客户端向代理服务器发送请求,代理服务器再将请求转发给服务器,服务器响应后将结果返回给代理服务器,代理服务器再将结果返回给客户端。
Proxy代理的工作流程如下: 1. 客户端向代理服务器发送请求。 2. 代理服务器接收请求,并将请求转发给服务器。 3. 服务器响应请求,并将结果返回给代理服务器。 4. 代理服务器接收到结果,并将结果返回给客户端。
Proxy代理的作用主要有以下几个方面: 1. 提高访问速度:代理服务器可以缓存请求结果,当下次有相同的请求时,直接返回缓存结果,从而提高访问速度。 2. 访问控制:代理服务器可以对客户端的请求进行过滤和控制,例如限制访问某些网站或者限制某些客户端的访问。 3. 隐藏客户端信息:代理服务器可以隐藏客户端的真实IP地址,从而保护客户端的隐私。 4. 负载均衡:代理服务器可以将请求分发到多个服务器上,从而实现负载均衡,提高服务器的性能和可靠性。 总之,Proxy代理是一种非常有用的网络应用程序,它可以提高访问速度、保护隐私、实现负载均衡等多种功能。
内存泄漏指程序在运行过程中,申请的内存空间没有被正确释放,导致系统中的可用内存不断减少,最终导致程序崩溃或系统崩溃的现象。内存泄漏通常是由于程序中存在一些错误的内存管理操作,例如未释放动态分配的内存、重复释放内存、使用已经释放的内存等。
内存泄漏的情况有以下几种: 1. 动态分配内存后未释放:程序在运行过程中使用了动态分配的内存,但在使用完毕后未将其释放,导致内存泄漏。 2. 循环引用:当两个或多个对象相互引用时,如果它们之间的引用关系没有被正确处理,就会导致内存泄漏。 3. 文件未关闭:程序在使用文件时,如果没有正确关闭文件,就会导致内存泄漏。 4. 缓存未清理:程序在使用缓存时,如果没有正确清理缓存,就会导致内存泄漏。 5. 程序错误:程序中存在一些错误的内存管理操作,例如使用已经释放的内存、重复释放内存等,都会导致内存泄漏。
内存泄漏会导致程序运行速度变慢,甚至会导致程序崩溃或系统崩溃,因此在程序开发中,需要注意内存管理,及时释放不再使用的内存空间。
第三周
箭头函数和普通函数的区别主要有以下几点: 1. 箭头函数没有自己的this,它的this是继承自外层作用域的。而普通函数的this是在函数被调用时动态绑定的,它的值取决于函数的调用方式。 2. 箭头函数不能使用arguments对象,也不能使用new关键字调用。而普通函数可以使用arguments对象,也可以使用new关键字调用。 3. 箭头函数没有prototype属性,因此不能作为构造函数使用。而普通函数可以作为构造函数使用,创建新的对象实例。 4. 箭头函数的语法更加简洁,可以省略函数体中的return关键字和花括号。而普通函数必须使用return关键字返回值,并且函数体必须用花括号括起来。 5、总的来说,箭头函数适合用于简单的函数,可以让代码更加简洁易读。而普通函数则更加灵活,可以应对各种不同的场景。
代码优化:检查代码中是否存在冗余、重复或不必要的代码,尽可能减少代码量,优化代码结构和算法,以提高页面加载速度。
图片优化:对于图片过大的情况,可以使用图片压缩工具进行压缩,减小图片大小,从而提高页面加载速度。
懒加载:对于页面中的图片、视频等资源,可以使用懒加载技术,只有当用户滚动到相应位置时才加载,从而减少首屏加载时间。
CDN加速:使用CDN(Content Delivery Network)加速服务,将静态资源分布在全球各地的服务器上,从而提高页面加载速度。
缓存优化:使用浏览器缓存技术,将页面中的静态资源缓存到本地,下次访问时直接从缓存中读取,从而减少服务器请求,提高页面加载速度。
服务器优化:对于服务器响应速度慢的情况,可以考虑使用更高配置的服务器,或者使用负载均衡技术,将请求分散到多个服务器上,从而提高页面加载速度。
babel-loader:将ES6/ES7/JSX等语法转换为ES5语法,解决了浏览器兼容性问题。
css-loader:解析CSS文件,处理其中的依赖关系,例如@import和url()等,使得CSS文件可以被打包到JS文件中。
style-loader:将CSS代码注入到HTML页面中的<style>标签中,使得样式生效。
file-loader:将文件复制到输出目录,并返回文件路径,解决了文件路径问题。
url-loader:与file-loader类似,但是可以将小于指定大小的文件转换为base64编码,减少HTTP请求,提高页面加载速度。
image-loader:加载并压缩图片文件,解决了图片加载速度慢的问题。
json-loader:加载JSON文件,解决了使用JSON文件时需要手动解析的问题。
xml-loader:加载XML文件,解决了使用XML文件时需要手动解析的问题。 这些Loader解决了不同的问题,例如浏览器兼容性、文件路径、样式注入、图片加载速度等,使得Webpack可以处理各种类型的文件,并将它们打包成一个或多个JS文件,提高了应用程序的性能和可维护性。
SPA单页面应用是指整个应用只有一个页面,所有的页面内容都是通过异步加载数据并动态更新页面来实现的。SPA应用通常使用前端框架(如React、Angular、Vue等)来实现。 优点: 1. 用户体验好:SPA应用可以实现无刷新页面切换,用户体验更加流畅。 2. 前后端分离:SPA应用可以将前端和后端分离,前端只需要关注页面展示和交互逻辑,后端只需要提供API接口。 3. 提高性能:SPA应用可以减少页面刷新,减少服务器负担,提高性能。 缺点: 1. 首屏加载慢:SPA应用需要加载所有的前端代码和数据,首屏加载时间较长。 2. SEO不友好:由于SPA应用只有一个页面,搜索引擎难以抓取页面内容,对SEO不友好。 3. 浏览器兼容性问题:SPA应用需要使用HTML5的一些新特性,对浏览器的兼容性要求较高。 实现SPA应用的方法: 1. 使用前端框架:使用React、Angular、Vue等前端框架可以快速实现SPA应用。 2. 使用路由库:使用React Router、Vue Router等路由库可以实现页面的无刷新切换。 3. 使用AJAX技术:使用AJAX技术可以实现异步加载数据,动态更新页面内容。
Vue中组件和插件的区别如下: 1. 组件是Vue中的基本概念,是Vue应用中的可复用的代码块,用于封装UI组件或业务逻辑。组件可以在Vue应用中多次使用,可以接收父组件传递的数据,也可以向父组件发送数据。 2. 插件是Vue中的扩展功能,是一些可选的功能模块,用于增强Vue应用的功能。插件可以添加全局方法或属性,也可以添加全局指令或过滤器,还可以添加Vue实例方法或混入。 3. 组件和插件的使用方式也不同。组件需要在Vue应用中注册后才能使用,可以通过Vue.component()方法或Vue.extend()方法来注册组件。而插件可以通过Vue.use()方法来安装插件,也可以直接在Vue实例中使用。 4. 组件和插件的作用范围也不同。组件主要用于封装UI组件或业务逻辑,作用范围通常是局部的,只在某个组件内部使用。而插件主要用于增强Vue应用的功能,作用范围通常是全局的,可以在整个Vue应用中使用。
Vue组件之间的通信方式有以下几种: 1. 父子组件通信:父组件通过props向子组件传递数据,子组件通过事件向父组件传递数据。 2. 兄弟组件通信:可以通过一个共同的父组件作为中介,将数据传递给兄弟组件。 3. 跨级组件通信:可以使用provide/inject来向下传递数据,或者使用$parent/$root来向上查找父级组件。 4. 非父子组件通信:可以使用事件总线(Event Bus)或者Vuex来实现非父子组件之间的通信。事件总线是一个空的Vue实例,可以用来触发和监听事件。Vuex是一个状态管理库,可以将数据集中管理,实现组件之间的共享状态。
Vue的diff算法是一种高效的虚拟DOM比较算法,用于计算前后两个虚拟DOM树之间的差异,并将差异应用到真实的DOM上,以达到最小化DOM操作的目的。 Vue的diff算法采用了双端比较的策略,即同时从新旧虚拟DOM树的头部和尾部开始比较,以尽可能地减少比较次数。具体来说,Vue的diff算法分为以下几个步骤: 1. 首先比较新旧虚拟DOM树的根节点,如果节点类型不同,则直接替换整个节点;如果节点类型相同,则进入下一步比较。 2. 比较节点的属性和事件,如果有变化,则更新节点的属性和事件。 3. 比较节点的子节点,如果子节点数量不同,则直接替换整个节点的子节点;如果子节点数量相同,则进入下一步比较。 4. 对于相同位置的子节点,递归执行上述步骤,直到所有子节点都比较完毕。 5. 对于新虚拟DOM树中多余的节点,直接添加到真实DOM中;对于旧虚拟DOM树中多余的节点,直接从真实DOM中删除。 通过以上步骤,Vue的diff算法可以高效地计算出前后两个虚拟DOM树之间的差异,并将差异应用到真实的DOM上,以达到最小化DOM操作的目的。
1、Virtual Dom 是一种将页面的状态抽象成一个虚拟的 DOM 树的技术。它是 React 和 Vue 等前端框架的核心技术之一。 2、Virtual Dom 的工作原理是,当页面状态发生变化时,框架会先将新的状态转换成一个新的虚拟 DOM 树,然后将这个新的虚拟 DOM 树与旧的虚拟 DOM 树进行比较,找出两者之间的差异,最后只更新需要更新的部分,从而避免了不必要的 DOM 操作,提高了页面的性能。 3、使用 Virtual Dom 的好处是,它可以让开发者专注于页面的状态管理,而不需要关心页面的具体实现细节。同时,由于 Virtual Dom 可以减少 DOM 操作,因此可以提高页面的性能和响应速度。
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有以下不同: 1. 组织代码的方式不同:Composition Api 是基于函数的,而 Options Api 是基于对象的。 2. 可复用性更强:Composition Api 可以更好地实现逻辑复用,可以将逻辑代码封装成函数,方便在多个组件中复用。 3. 更好的类型推断:Composition Api 可以更好地支持 TypeScript,因为它使用了更多的类型推断。 4. 更好的代码可读性:Composition Api 可以更好地组织代码,使代码更加清晰易读,减少了 Options Api 中的混乱和重复。 5. 更好的响应式:Composition Api 中的 reactive 和 ref 可以更好地处理响应式数据,使得代码更加简洁易懂。 总之,Composition Api 在代码组织、可复用性、类型推断、代码可读性和响应式等方面都有很大的优势,可以更好地帮助开发者构建高质量的 Vue 应用程序。
在 React 中,setState 是用来更新组件状态的方法。当调用 setState 方法时,React 会将新的状态对象合并到当前状态对象中,然后重新渲染组件。 具体的执行机制如下: 1. 调用 setState 方法时,React 会将新的状态对象添加到一个更新队列中。 2. 如果在同一个事件循环中多次调用 setState 方法,React 会将这些更新合并成一个更新,只执行一次更新操作。 3. 在组件生命周期函数和事件处理函数中调用 setState 方法时,React 会将更新添加到队列中,并在当前事件循环结束后执行更新操作。 4. 在异步操作中调用 setState 方法时,React 会将更新添加到队列中,并在下一个事件循环中执行更新操作。 5. 在更新操作执行前,React 会对更新队列进行优化,去除重复的更新和无效的更新,以提高性能。 总之,React 的 setState 方法是一个异步操作,它会将更新添加到队列中,并在合适的时机执行更新操作。在使用 setState 方法时,需要注意避免出现死循环和不必要的更新,以提高组件的性能。
1、类组件和函数组件都是用来定义组件的一种方式。 2、类组件是使用ES6中的class语法来定义的,必须继承React.Component类,并且必须实现render的方法来返回组件的jsx;类组件可以使用state和生命周期方法来管理组件的状态和行为 3、函数组件使用函数来定义的,它们只需要返回JSX即可,函数组件不能使用state和生命周期方法,但是可以使用React Hook来管理组件的状态和行为 区别: 1. 语法:类组件使用class语法,函数组件使用函数语法。 2. 状态管理:类组件可以使用state来管理组件的状态,而函数组件需要使用React Hooks来管理状态。 3. 生命周期:类组件有生命周期方法,如componentDidMount()和componentWillUnmount()等,而函数组件没有生命周期方法。 4. 性能:函数组件通常比类组件更轻量级,因为它们不需要继承React.Component类和实现render()方法。但是,如果需要管理状态和行为,函数组件可能需要使用React Hooks,这可能会影响性能。
React Hooks 是 React 16.8 中引入的新特性,它可以让我们在不编写 class 的情况下使用 state 和其他 React 特性。 React Hooks 解决了以下问题: 1. 在组件之间复用状态逻辑很难。React Hooks 提供了一种方式来共享状态逻辑,称为自定义 Hook。 2. 复杂组件变得难以理解。React Hooks 可以将组件拆分成更小的函数,每个函数只关注一个特定的功能。 3. Class 组件中的生命周期方法和状态逻辑之间的关系不直观。React Hooks 可以将生命周期方法和状态逻辑分离,使代码更易于理解和维护。 4. Class 组件中的 this 绑定问题。React Hooks 中的函数组件没有 this 绑定问题,使代码更加简洁和易于维护。 总之,React Hooks 提供了一种更简单、更直观的方式来编写 React 组件,使代码更易于理解和维护。
UseMemo和useCallback都可以用来优化React组件的性能。 UseMemo可以缓存计算结果,避免重复计算,从而提高组件的渲染性能。 它的应用场景包括: 1. 计算开销较大的值,例如从API获取数据并进行复杂的计算。 2. 优化子组件的渲染,避免不必要的渲染。 3. 避免在每次渲染时都创建新的对象或数组。 UseCallback可以缓存函数,避免在每次渲染时都创建新的函数,从而提高组件的渲染性能。 它的应用场景包括: 1. 将函数作为props传递给子组件时,避免子组件不必要的渲染。 2. 在使用useEffect时,避免因为函数引用变化而导致useEffect重复执行。 3. 在使用useMemo时,避免因为函数引用变化而导致useMemo重复计算。
Vue-router是Vue.js官方提供的路由管理插件。 它的实现原理主要包括以下几个方面: 1. 基于Vue.js的组件化开发思想,将路由规则抽象成一个个组件,通过组件的嵌套和切换来实现页面的跳转和刷新。 2. 利用HTML5的History API,通过pushState和replaceState方法来改变浏览器的URL地址,从而实现前端路由的跳转和刷新。 3. 利用Vue.js的响应式数据绑定机制,将路由信息存储在Vue实例的data属性中,通过watch监听路由变化,从而实现路由的动态更新和响应。 4. 利用Vue.js的生命周期钩子函数,如beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave等,来实现路由的拦截和控制,从而实现路由的权限管理和页面的动态加载。 总之,Vue-router的实现原理是基于Vue.js的组件化开发思想和响应式数据绑定机制,利用HTML5的History API和Vue.js的生命周期钩子函数来实现前端路由的跳转、刷新、拦截和控制。
要封装组件以便在不同的项目中使用,可以按照以下步骤进行: 1. 创建一个独立的组件库项目,该项目包含所有要封装的组件。 2. 在组件库项目中,为每个组件创建一个独立的文件夹,并在其中包含组件的所有代码和样式。 3. 在每个组件文件夹中,创建一个
index.js
文件,该文件将导出组件的所有必要内容,例如组件类、样式和其他依赖项。 4. 在组件库项目中,使用打包工具(例如 webpack)将所有组件打包到一个单独的 JavaScript 文件中。 5. 将组件库项目发布到 npm 或其他包管理器中,以便其他项目可以使用它。 6. 在其他项目中,使用npm install
命令安装组件库。 7. 在需要使用组件的文件中,导入所需的组件并使用它们。
Vue、React、Angular 都是现代化的 JavaScript 框架,用于构建单页应用程序(SPA)和动态 Web 应用程序。 它们之间的区别如下: 1. Vue.js 是一种轻量级的框架,易于学习和使用,适合小型项目。React.js 是一个库,提供了更多的灵活性和可定制性,适合大型项目。Angular 是一个完整的框架,提供了许多功能和工具,适合大型企业级项目。 2. Vue.js 的模板语法更加简单和直观,易于理解和维护。React.js 使用 JSX 语法,需要更多的学习和理解。Angular 使用 HTML 和 TypeScript,需要更多的学习和掌握。 3. Vue.js 的性能比较好,因为它使用了虚拟 DOM 和异步渲染。React.js 也使用了虚拟 DOM,但是需要手动优化性能。Angular 的性能相对较差,因为它使用了双向数据绑定和大量的依赖注入。 4. Vue.js 和 React.js 都是开源的,社区活跃,有大量的插件和组件可用。Angular 也是开源的,但是由于其复杂性和学习曲线,社区相对较小。
Redux是一个JavaScript状态管理库,它可以帮助我们在应用程序中管理和更新状态。Redux的核心概念是store,它是一个包含整个应用程序状态的JavaScript对象。Redux通过使用action和reducer来更新store中的状态。 当应用程序中的某个事件发生时,我们可以创建一个action对象,它描述了这个事件的类型和相关的数据。然后,我们将这个action对象传递给一个reducer函数,它会根据action的类型来更新store中的状态。reducer函数接收当前的状态和action对象作为参数,并返回一个新的状态对象。 Redux的工作原理可以概括为以下几个步骤: 1. 创建一个store对象,它包含整个应用程序的状态。 2. 定义action对象,它描述了应用程序中的事件。 3. 创建reducer函数,它根据action的类型来更新store中的状态。 4. 将action对象传递给reducer函数,它会返回一个新的状态对象。 5. 更新store中的状态,使其与新的状态对象匹配。 6. 在应用程序中订阅store的变化,以便在状态发生变化时更新UI。
Redux的优点是可以帮助我们更好地组织和管理应用程序的状态,使得应用程序更加可预测和可维护。同时,Redux还可以与React等框架和库进行集成,使得我们可以更方便地使用它来管理应用程序的状态。
第一次周考2205A
盒子模型是指在网页中,每个元素都被看作是一个矩形的盒子,这个盒子由四个边框、内边距、外边距和内容区域组成。这个模型可以帮助我们更好地理解和控制网页中元素的布局和样式。 具体来说,盒子模型包括以下几个部分: 1. 内容区域(content):元素的实际内容,例如文本、图片等。 2. 内边距(padding):内容区域与边框之间的空白区域,可以通过设置 padding 属性来控制。 3. 边框(border):包围内容区域和内边距的线条,可以通过设置 border 属性来控制。 4. 外边距(margin):边框与相邻元素之间的空白区域,可以通过设置 margin 属性来控制。 在实际应用中,我们可以通过设置盒子模型的各个属性来控制元素的大小、位置、边框样式、背景颜色等。同时,盒子模型也是 CSS 布局的基础,通过合理地使用盒子模型,我们可以实现各种复杂的布局效果。
CSS的选择器有以下几种: 1. 元素选择器(element selector):通过元素名称来选择元素,如p、div、a等。 2. 类选择器(class selector):通过类名来选择元素,以“.”开头,如.class。 3. ID选择器(ID selector):通过ID来选择元素,以“#”开头,如#id。 4. 属性选择器(attribute selector):通过元素的属性来选择元素,如[type="text"]。 5. 伪类选择器(pseudo-class selector):通过元素的状态来选择元素,如:hover、:active、:visited等。 6. 伪元素选择器(pseudo-element selector):用于选择元素的某个部分,如::before、::after等。 CSS选择器的优先级从高到低依次为: 1. !important 2. 行内样式(style属性) 3. ID选择器 4. 类选择器、属性选择器、伪类选择器 5. 元素选择器、伪元素选择器 可以继承的CSS属性有以下几种: 1. 字体系列属性(font-family、font-size、font-weight等) 2. 文本系列属性(text-align、text-indent、text-decoration等) 3. 颜色属性(color、background-color等) 4. 列表属性(list-style-type、list-style-image等) 5. 表格布局属性(border-collapse、border-spacing等) 6. 其他属性(visibility、cursor等)
元素水平垂直居中的方法有以下几种: 1. 使用flex布局:将父元素设置为display: flex;,并设置justify-content: center;和align-items: center;即可实现水平垂直居中。 2. 使用绝对定位:将父元素设置为相对定位,子元素设置为绝对定位,并设置top: 50%;和left: 50%;,再使用transform: translate(-50%, -50%);即可实现水平垂直居中。 3. 使用表格布局:将父元素设置为display: table;,子元素设置为display: table-cell;,并设置vertical-align: middle;和text-align: center;即可实现水平垂直居中。
如果元素不定宽高,可以使用以下方法: 1. 使用flex布局:将父元素设置为display: flex;,并设置justify-content: center;和align-items: center;,子元素设置为flex: 1;即可实现水平垂直居中。 2. 使用绝对定位:将父元素设置为相对定位,子元素设置为绝对定位,并设置top: 50%;和left: 50%;,再使用transform: translate(-50%, -50%);和max-width: 100%;和max-height: 100%;即可实现水平垂直居中 3. 使用表格布局:将父元素设置为display: table;,子元素设置为display: table-cell;,并设置vertical-align: middle;和text-align: center;,再使用max-width: 100%;和max-height: 100%;即可实现水平垂直居中。
回流(reflow)和重绘(repaint)是浏览器渲染页面时的两个重要概念。 回流指的是当页面中的元素发生位置、大小等属性的变化时,浏览器需要重新计算元素的位置和大小,然后重新布局整个页面,这个过程就是回流。回流会导致页面的重新渲染,因此会比较耗费性能。 重绘指的是当页面中的元素的样式属性发生变化时,浏览器只需要重新绘制这些元素的样式,而不需要重新计算元素的位置和大小,这个过程就是重绘。重绘的性能消耗比回流要小。
在以下场景下会触发回流和重绘: 1. 当页面首次加载时,浏览器需要进行回流和重绘。 2. 当页面中的元素的位置、大小、内容等属性发生变化时,会触发回流和重绘。 3. 当页面中的元素的样式属性发生变化时,会触发重绘。 4. 当浏览器窗口大小发生变化时,会触发回流和重绘。 5. 当页面滚动时,会触发重绘。
因此,在编写页面时,应该尽量避免频繁的回流和重绘,可以通过以下方式来优化页面性能: 1. 使用 CSS3 的 transform 和 opacity 属性来实现动画效果,避免使用 position 和 float 等属性。 2. 使用 position: absolute 或 fixed 来定位元素,避免使用 margin 和 padding 等属性。 3. 避免频繁修改 DOM 元素的样式属性,可以将多个修改操作合并成一次操作。 4. 使用虚拟列表等技术来优化大量数据的渲染。
响应式设计是一种网页设计方法,可以使网站在不同设备上(如桌面电脑、平板电脑、手机等)呈现出最佳的用户体验。响应式设计的基本原理是通过使用CSS媒体查询和弹性网格布局等技术,根据不同设备的屏幕大小和分辨率,自动调整网页的布局、字体大小、图片大小等元素,以适应不同设备的屏幕大小和分辨率。要做好响应式设计,需要遵循以下几个步骤: 1. 设计弹性网格布局:使用相对单位(如百分比、em等)来定义网页元素的大小和位置,以适应不同设备的屏幕大小。 2. 使用CSS媒体查询:根据不同设备的屏幕大小和分辨率,使用CSS媒体查询来调整网页的布局、字体大小、图片大小等元素。 3. 优化图片大小:使用适当的图片格式和压缩技术来减小图片的大小,以提高网页加载速度。 4. 测试和优化:在不同设备上测试网页的响应式设计效果,并根据测试结果进行优化,以提高用户体验。
1、盒子模型就是指的在网页中,每个元素都被看做是一个矩形的盒子,包含了内容、内边距、边框和外边距四个部分,其中,内容区域是元素实际显示内容的区域,内边距是内容区域与边框之间的距离,边框是围绕内容和内边距的线条,外边距是边框与相邻元素之间的距离。
2、盒子模型的大小由元素的高度和宽度属性决定,但是实际大小还要加上内边距、边框和外边距的值,在css中,可以通过box-sizing属性来控制盒子模型的计算方式。有两种取值:content-box和border-box。content-box表示盒子模型的大小只包括内容区域,而border-box表示盒子模型的大小包括内容区域、内边距和边框,但不包括外边距。
3、盒子模型在网页布局中非常重要,可以通过设置元素的宽度、高度、内边距、边框和外边距等属性来实现各种布局效果。同时,盒子模型还可以通过CSS的定位属性来控制元素的位置和层级关系。
使用flex布局,将父容器设置为display:flex,然后使用justify-content:center和align-items:center来实现水平垂直居中
使用绝对定位,将盒子的left和top属性设置为50%,然后使用transform:translate(-50%,-50%)来实现水平垂直居中。
使用表格布局,将父容器设置为display:table,然后将盒子设置为display:table-cell,使用vertical-align:middle和text-align:center来实现水平垂直居中。
JavaScript有七种数据类型,分别是:
基本数据类型:Number、String、Boolean、Null、Undefined、Symbol(ES6新增)。
引用数据类型:Object。
基本数据类型的值存储在栈内存中,而引用数据类型的值存储在堆内存中,栈内存中存储的是指向堆内存中实际数据的指针。
当我们创建一个基本数据类型的变量时,会在栈内存中分配一段空间,将值存储在这个空间中;
当我们创建一个引用数据类型的变量时,会在栈内存中分配一段空间,这个空间中存储的是指向堆内存中实际数据的指针,而实际数据存储在堆内存中。
1、响应式网站合计是一种网络页面设计布局,页面设计与开发应当根据用户的行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整
2、媒体查询:使用@media可以根据不同的屏幕尺寸来定义不同的样式
3、百分比:相对于包含块的计量单位,通过对属性设置百分比来适应不同的屏幕
4、vw/vh:视口单位,可以根据浏览器的窗口大小来进行适配
5、rem:指相对于根元素的字体大小的单位,rem只是一个相对单位
1、避免过度的约束
2、避免后代选择符
3、使用紧凑的语法
4、避免不必要的命名空间
5、避免不必要的重复
6、最好使用表示语义的名字来进行定义
7、避免!important,可以选择其他的选择器
8、尽可能的精简规则,可以合并不同类的重复规则
1、 typeof :
a. 可以判断数据类型,它返回表示数据类型的字符串,返回的结果只能包括number,Boolean,string,function,object,undefined
b. 可以使用typeof判断变量是否存在
c. typeof运算符的问题是无论引用的对象是什么类型,它都返回object
2、instanceof方法:
般用来检测引用数据类型,表达式为:A instanceof B,判断A是否是B的实例,如果 A 是 B 的实例,则返回 true,否则返回 false,由构造类型判断出数据类型
3、constructor方法:
constructor是prototype对象上的属性,指向构造函数,
4、无敌万能的方法:jquery.type()
如果对象是undefined或null,则返回相应的“undefined”或“null”。
如果对象有一个内部的[[Class]]和一个浏览器的内置对象的 [[Class]] 相同,我们返回相应的 [[Class]] 名字
1、
call
、apply
、bind
作用是改变函数执行时的上下文,简而言之就是改变函数运行时的this
指向2、
apply
接受两个参数,第一个参数是this
的指向,第二个参数是函数接受的参数,以数组的形式传入,改变this
指向后原函数会立即执行,且此方法只是临时改变this
指向一次3、
call
方法的第一个参数也是this
的指向,后面传入的是一个参数列表,跟apply
一样,改变this
指向后原函数会立即执行,且此方法只是临时改变this
指向一次,当第一个参数为null
、undefined
的时候,默认指向window
(在浏览器中)4、bind方法和call很相似,第一参数也是
this
的指向,后面传入的也是一个参数列表(但是这个参数列表可以分多次传入),改变this
指向后不会立即执行,而是返回一个永久改变this
指向的函数5、区别:
三者都可以改变函数的
this
对象指向三者第一个参数都是
this
要指向的对象,如果如果没有这个参数或参数为undefined
或null
,则默认指向全局window
三者都可以传参,但是
apply
是数组,而call
是参数列表,且apply
和call
是一次性传入参数,而bind
可以分为多次传入
bind
是返回绑定this之后的函数,apply
、call
则是立即执行
修改this
指向
动态传递参数
// 方式一:只在bind中传递函数参数 fn.bind(obj,1,2)() // 方式二:在bind中传递函数参数,也在返回函数中传递参数 fn.bind(obj,1)(2)
兼容new
关键字
整体实现代码如下:
Function.prototype.myBind = function (context) { // 判断调用对象是否为函数 if (typeof this !== "function") { throw new TypeError("Error"); } // 获取参数 const args = [...arguments].slice(1), fn = this; return function Fn() { // 根据调用方式,传入不同绑定值 return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments)); } }
1、一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure),也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域
2、应用场景:
创建私有变量、
延长变量的生命周期
缓存数据
实现回调函数
1、事件代理(Event Delegation),又称之为事件委托。是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown......)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
1、防抖是当事件被触发后,延迟
n
秒后再执行回调,如果在这n
秒内事件又被触发,则重新计时。2、节流就是 n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时,可以减少一段时间内事件的触发频率。
3、区别:
相同点:
都可以通过使用
setTimeout
实现目的都是,降低回调执行频率。节省计算资源.
不同点:
函数防抖,在一段连续操作结束后,处理回调,利用
clearTimeout
和setTimeout
实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次
例如,都设置时间频率为500ms,在2秒时间内,频繁触发函数,节流,每隔 500ms 就执行一次。防抖,则不管调动多少次方法,在2s后,只会执行一次
4、应用场景:
防抖在连续的事件,只需触发一次回调的场景有:
搜索框搜索输入。只需用户最后一次输入完,再发送请求
手机号、邮箱验证输入检测
窗口大小
resize
。只需窗口调整完成后,计算窗口大小。防止重复渲染。节流在间隔一段时间执行一次回调的场景有:
滚动加载,加载更多或滚到底部监听
搜索框,搜索联想功能
1、在当前作用域中查找所需变量,但是
该作用域没有
这个变量,那这个变量就是自由变量
。如果在自己作用域找不到
该变量就去父级作用域查
找,依次向上级作用域
查找,直到访问到window对象就被终止,这一层层的关系就是作用域链。
2、作用域链的作用是保证对执行环境有权访问的所有变量和函数的有序访问,通过作用域链,可以访问到外层环境的变量和函数。作用域链的本质上是一个指向变量对象的指针列表。变量对象是一个包含了执行环境中所有变量和函数的对象。作用域链的前端始终都是当前执行上下文的变量对象。
1、原型:
JS声明构造函数(用来实例化对象的函数)时,会在内存中创建一个对应的对象,这个对象就是原函数的原型。构造函数默认有一个prototype属性,prototype的值指向函数的原型。同时原型中也有一个constructor属性,constructor的值指向函数对象。
通过构造函数实例化出来的对象,并不具有prototype属性,其默认有一个proto属性,proto的值指向构造函数的原型。在原型对象上添加或修改的属性,在所有实例化出的对象上都可共享。
作用:数据共享、节约内存空间;实现继承
2、原型链:
当在实例化的对象中访问一个属性时,首先会在该对象内部(自身属性)寻找,如找不到,则会向其proto指向的原型中寻找,如仍找不到,则继续向原型中proto指向的上级原型中寻找,直至找到或Object.prototype.proto为止(值为null),这种链状过程即为原型链。
作用:查找对象的属性方法
1、vue的生命周期就是指从开始创建、初始化数据、编译模板、挂在DOM和渲染、更新渲染、卸载的一系列过程
2、beforeCreate():创建前,在new一个vue实例后,只有一些默认的生命周期钩子和默认事件,其他的东西都还没创建。在此生命周期执行的时候,data和methods中的数据都还没有初始化。不能在这个阶段使用data中的数据和methods中的方法
3、created():被创建,data 和 methods都已经被初始化好了,可以调用了
4、BeforeMount():挂载前,在内存中已经编译好了模板了,但是还没有挂载到页面中,此时,页面还是旧的
5、mounted():已挂载,Vue实例已经初始化完成了。此时组件脱离了创建阶段,进入到了运行阶段。 如果我们想要通过插件操作页面上的DOM节点,最早可以在和这个阶段中进行
6、beforeupdate():更新前,页面中的显示的数据还是旧的,data中的数据是更新后的, 页面还没有和最新的数据保持同步
7、updated():更新,页面显示的数据和data中的数据已经保持同步了,都是最新的
8、beforeDestory():销毁前,Vue实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁
9、Destoryed():被销毁,Vue实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
1、
javaScript
本地缓存的方法我们主要讲述以下四种:
cookie
sessionStorage
localStorage
indexedDB
2、关于
cookie
、sessionStorage
、localStorage
三者的区别主要如下:
存储大小:
cookie
数据大小不能超过4k
,sessionStorage
和localStorage
虽然也有存储大小的限制,但比cookie
大得多,可以达到5M或更大有效时间:
localStorage
存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage
数据在当前浏览器窗口关闭后自动删除;cookie
设置的cookie
过期时间之前一直有效,即使窗口或浏览器关闭数据与服务器之间的交互方式,
cookie
的数据会自动的传递到服务器,服务器端也可以写cookie
到客户端;sessionStorage
和localStorage
不会自动把数据发给服务器,仅在本地保存3、针对不对场景的使用选择:
标记用户与跟踪用户行为的情况,推荐使用
cookie
适合长期保存在本地的数据(令牌),推荐使用
localStorage
敏感账号一次性登录,推荐使用
sessionStorage
存储大量数据的情况、在线文档(富文本编辑器)保存编辑历史的情况,推荐使用
indexedDB
月考111
1、递归是一种算法或者函数的实现方式,他通过调用自身来解决问题。在递归的过程中,每次调用都会将问题分解为更小的子问题,直到问题被分解为足够小的部分,可以直接求解
2、递归通常可以用来解决具有递归结构的问题,比如像树形结构和图形结构等。
1、Link和@import都是用于引入外部资源的方法,但是也有所区别
区别:
1、加载时间:Link标签在页面加载时同时进行加载;@import是在页面加载完毕后再进行加载。
2、兼容性:Link标签是HTML标签,兼容性比较好;@import是css语法,不兼容旧版本的浏览器。
3、作用范围:Link标签可以引入各种类型的文件,比如CSS、JS、图片等;而@import只能引入CSS文件
4、权重:Link标签引入的CSS文件的权重高于@import引入的CSS文件,因此在样式进行冲突的时候,Link标签引入的样式会覆盖@import引入的样式
1、FOUC是文档样式暂时失效,指的是在网页加载时,由于CSS文件未能及时加载,导致页面出现短暂的样式化内容的现象。
如何避免:
1、将CSS文件放在HTML文档的头部,这样可以确保CSS文件在页面加载时首先被加载
2、使用内联CSS样式,将CSS样式直接嵌入HTML文档中,这样可以避免CSS问价加载时的延迟。
3、使用CSS预处理器,比如Sass和Less,可以将CSS文件编译为单个CSS文件,从而减少HTTP请求量
4、使用浏览器缓存,将CSS缓存到本地,可以减少页面的加载时间
5、使用JavaScript可以在页面加载时检测CSS文件是否已经加载完成,如果加载未完成,则可以延迟页面的渲染,直到CSS文件加载完成
1、预编译器就是一种程序,它在编译源代码之前对源代码进行处理,它可以执行一些预处理的操作,例如宏替换、条件编译、头文件包含等。预编译器是编译器的一部分,他可以在编译的过程中自动执行,也可以通过命令进行执行
2、预编译器的主要作用是将源代码中的宏定义替换为实际的代码,以及将头文件中的内容插入到源代码中。这样可以减少代码的重复性,提高代码的可读性和可维护性。
3、预编译器还可以进行条件编译,根据不同的条件编译选项生成不同的代码。这样可以根据不同的需求生成不同的代码,提高代码的灵活性和可移植性。
1、shouldComponentUpdate是React生命周期方法之一,用于控制组件是否需要重新渲染。它的作用是在组件重新渲染之前,判断组件的props和state是否发生了变化,如果没有变化则返回false,否则返回true,告诉React需要重新渲染组件。
2、 使用shouldComponentUpdate可以提高React应用的性能,因为它可以避免不必要的重新渲染。当组件的props或state发生变化时,React会重新渲染组件,如果组件的props或state没有变化,那么重新渲染是没有必要的,这时候就可以使用shouldComponentUpdate来避免不必要的重新渲染。
React中的事务处理逻辑是指在React组件的生命周期中,React会自动创建一个事务对象,用于管理组件的更新过程。事务对象包含了一系列的生命周期钩子函数,用于在组件更新过程中执行特定的操作。
1、React组件可以根据其功能和用途划分为业务组件和技术组件。
2、业务组件是指与业务相关的组件,例如登录框、购物车、商品列表等。这些组件通常是具有特定功能的,可以被多个页面或应用程序共享。业务组件通常是由多个技术组件组成的,例如表单、按钮、列表等。
3、技术组件是指与技术相关的组件,例如表单、按钮、列表等。这些组件通常是具有通用功能的,可以被多个业务组件共享。技术组件通常是由HTML、CSS和JavaScript代码组成的,可以通过props和state属性进行交互。
React性能优化是在shouldComponentUpdate生命周期函数中进行的。该函数在组件更新前被调用,可以通过返回false来阻止组件的重新渲染,从而提高应用的性能。在该函数中,可以通过比较前后两次的props和state来决定是否需要重新渲染组件。
1、Fiber架构是一种基于协程的轻量级并发模型,它可以在单个线程中实现高并发的处理能力。
2、Fiber架构的核心思想是将一个长时间的任务分解成多个小任务,然后在这些小任务之间进行切换,从而实现并发处理。
Fiber架构的应用场景主要包括以下几个方面:
1. 高并发的网络应用:Fiber架构可以在单个线程中处理大量的网络请求,从而提高应用的并发处理能力。 2. 高性能的数据库访问:Fiber架构可以在单个线程中处理多个数据库请求,从而提高数据库访问的性能。 3. 大规模的数据处理:Fiber架构可以将大规模的数据处理任务分解成多个小任务,从而提高数据处理的效率。 4. 实时数据处理:Fiber架构可以实现实时数据处理,例如实时监控、实时日志处理等。
使用PureComponent或shouldComponentUpdate:PureComponent是React提供的一个优化性能的组件,它会自动进行浅比较,如果props和state没有变化,就不会重新渲染组件。如果使用的是普通的Component,可以手动实现shouldComponentUpdate方法,进行自定义的比较逻辑。
使用React.memo:React.memo是React提供的一个高阶组件,它可以缓存组件的渲染结果,如果props没有变化,就直接返回缓存的结果,不会重新渲染组件。
避免在render方法中进行复杂的计算和操作:render方法会在每次组件更新时被调用,如果在其中进行复杂的计算和操作,会影响组件的性能。可以将这些计算和操作放到组件的生命周期方法中,或者使用memoization技术进行缓存。
使用React.lazy和Suspense:React.lazy是React提供的一个懒加载组件的方式,可以将组件的加载延迟到需要使用时再进行。Suspense是React提供的一个组件,可以在组件加载时显示一个loading状态,等待组件加载完成后再显示组件。
使用shouldComponentUpdate和React.memo进行性能测试:可以使用React的性能测试工具进行测试,找出哪些组件需要进行优化,然后使用shouldComponentUpdate或React.memo进行优化。
使用React的Profiler工具进行性能分析:React提供了一个Profiler工具,可以帮助开发者分析组件的渲染性能,找出哪些组件需要进行优化。
Flux是一种架构模式,用于构建可扩展的Web应用程序。它的核心思想是单向数据流,即数据只能从一个地方流向另一个地方,这样可以避免数据的混乱和不一致。
CSS渲染的过程是将HTML文档和CSS样式表结合起来,生成可视化的Web页面。具体过程如下:
1. 浏览器解析HTML文档,构建DOM树。 1. 浏览器解析CSS样式表,构建CSSOM树。 1. 将DOM树和CSSOM树结合起来,生成渲染树。 1. 根据渲染树中的节点信息,计算每个节点的位置和大小。 1. 将渲染树中的节点绘制到屏幕上,生成最终的Web页面。
DOM0、DOM2、DOM3是指不同版本的JavaScript DOM(文档对象模型)事件处理规范。
1、DOM0事件处理:在DOM0事件处理中,事件处理程序直接赋值给DOM元素的属性
2、DOM2事件处理:DOM2事件处理规范引入了addEventListener()和removeEventListener()方法,这些方法允许在同一元素上添加多个事件处理程序。
3、DOM3事件处理:DOM3事件处理规范引入了更多的事件类型和更多的事件处理程序选项。
判断页面滚动到底部可以通过以下方式:
获取页面的滚动高度scrollTop、页面可视高度clientHeight和页面总高度scrollHeight。
判断scrollTop + clientHeight是否等于scrollHeight,如果相等则表示页面已经滚动到底部。
判断页面中元素是否进入可视化区域可以通过以下方式:
1.获取元素的位置信息,包括元素的offsetTop、offsetLeft、offsetWidth和offsetHeight。
获取页面的滚动高度scrollTop和页面可视高度clientHeight。
判断元素的位置信息是否在scrollTop和scrollTop + clientHeight之间,如果在则表示元素已经进入可视化区域。
1、浏览器Event Loop和nodejs中Event Loop的主要区别在于它们的实现方式和运行环境。
2、 浏览器Event Loop是基于单线程的JavaScript引擎实现的,它负责处理JavaScript代码的执行和事件的处理。
3、浏览器中的Event Loop主要包括宏任务和微任务两种类型的任务队列。宏任务包括setTimeout、setInterval、DOM事件等,而微任务包括Promise、MutationObserver等。在每次事件循环中,先执行所有的微任务,然后执行一个宏任务,然后再执行所有的微任务,如此循环往复。
4、 而nodejs中的Event Loop是基于多线程的C++实现的,它负责处理JavaScript代码的执行和I/O操作的处理。
5、nodejs中的Event Loop主要包括六个阶段:timers、pending callbacks、idle、prepare、poll和check。在每个阶段中,Event Loop会执行相应的任务队列,直到所有任务都被执行完毕。
1、Vue-router的底层实现原理主要是基于Vue.js的响应式系统和路由的hash模式或history模式。
2、在Vue.js中,每个组件都有一个响应式的状态对象,当状态发生变化时,Vue.js会自动更新视图。Vue-router利用这个特性,将路由信息存储在一个响应式的状态对象中,当路由发生变化时,Vue.js会自动更新视图。
3、 在hash模式下,Vue-router监听浏览器的hashchange事件,当hash发生变化时,Vue-router会根据新的hash值更新路由状态对象,并触发视图更新。
4、 在history模式下,Vue-router使用HTML5的history API,通过pushState和replaceState方法改变浏览器的URL,同时更新路由状态对象,并触发视图更新。
5、为了防止用户手动修改URL导致路由状态对象和视图不一致,Vue-router还使用了popstate事件监听浏览器的后退和前进操作,以便及时更新路由状态对象和视图。
6、除此之外,Vue-router还提供了路由守卫、动态路由、嵌套路由等功能,这些功能的实现也是基于Vue.js的响应式系统和路由模式的特性。
1、Vuex是一个状态管理库,它的实现原理是基于Vue.js的响应式系统和单向数据流模式。
2、Vuex将应用程序的状态存储在一个中央存储库中,称为store。组件可以通过getter和mutation访问和修改store中的状态,而action可以用于异步操作。
4、commit方法是用于提交mutation的方法,它接收两个参数:mutation的名称和payload(可选)。当调用commit方法时,Vuex会在store中查找对应的mutation并执行它,从而修改store中的状态。
5、 dispatch方法是用于触发action的方法,它接收两个参数:action的名称和payload(可选)。当调用dispatch方法时,Vuex会在store中查找对应的action并执行它,从而触发异步操作或其他一些副作用。
1、可以在路由配置中使用
<keep-alive>
标签来实现组件缓存。2、在路由配置中,将需要缓存的组件包裹在
<keep-alive>
标签中,并设置include
属性为需要缓存的组件名称3、在组件中,通过
activated
和deactivated
生命周期钩子来判断是否需要缓存。如果需要缓存,则在activated
钩子中设置$route.meta.keepAlive
为true
,在deactivated
钩子中设置为false
4、 在跳转时,根据需要缓存的组件名称来判断是否需要缓存。如果需要缓存,则在跳转时设置
$route.meta.keepAlive
为true
,否则设置为false
专高六第二周
1、MVVM是一种软件架构模式,它将应用程序分为三个部分:模型Model、视图View、视图模型ModelView。其中,模型表示应用程序的数据和业务逻辑,视图表示用户界面,视图模型就是连接模型和视图的中间件。
2、在MVVM中,视图模型负责将模型中的数据转换为视图可以使用的格式,并将视图中的用户操作转换为模型可以理解的模式,视图模型还负责处理视图和模型之间的通信,比如像数据绑定、命令绑定等。
3、MVVM的优点?
1、分离关注点:将应用程序的数据和业务逻辑与用户界面分离,使得代码更加清晰易懂。
2、可测试性:由于视图模型与视图和模型之间的通信是通过数据绑定和命令绑定实现的,因此可以更加容易的对视图模型进行单元测试。
3、可维护性:由于MVVM将应用程序分为三个部分,因此可以更加容易的对应用程序进行维护和扩展。
vue生命周期指的是vue实例从创建到销毁的整个过程,vue生命周期分为八个阶段:
1、beforeCreate:在实例被创建之前调用,此时实例的数据和方法都还未初始化,无法访问data、computed、methods等属性。
2、created:在实例创建完成后调用,此时实例的数据和方法已经初始化完成,但是DOM还未渲染,无法访问DOM元素。
3、 beforeMount:在DOM挂载之前调用,此时模板已经编译完成,但是还未将其挂载到页面上。
4、 mounted:在DOM挂载完成后调用,此时实例已经挂载到页面上,可以访问DOM元素。
5、 beforeUpdate:在数据更新之前调用,此时数据已经更新,但是DOM还未重新渲染。
6、updated:在数据更新完成后调用,此时数据已经更新,DOM也已经重新渲染完成。
7、beforeDestroy:在实例销毁之前调用,此时实例还未销毁,可以进行一些清理工作。
8、 destroyed:在实例销毁之后调用,此时实例已经销毁,无法访问实例的数据和方法。
Vue组件之间的数据传递方式有以下几种:
父子组件传递数据:父组件通过props向子组件传递数据,子组件通过$emit触发事件向父组件传递数据。
兄弟组件传递数据:可以通过一个共同的父组件作为中介,将数据传递给兄弟组件。
使用Vuex进行数据管理:Vuex是Vue的状态管理库,可以将数据存储在全局的store中,各个组件可以通过getter和mutation来获取和修改数据。
使用事件总线进行数据传递:可以使用Vue实例作为事件总线,通过$on和$emit方法来进行组件之间的数据传递。
使用provide和inject进行数据传递:父组件通过provide向子组件提供数据,子组件通过inject注入数据。
使用$refs进行数据传递:可以通过$refs获取到子组件的实例,从而直接访问子组件的数据和方法。
UE的路由实现主要有两种模式:hash模式和history模式。
hash模式 在hash模式下,URL中的#符号后面的内容被称为hash值,它不会被发送到服务器,而是在客户端进行处理。当URL中的hash值发生变化时,浏览器会触发hashchange事件,我们可以通过监听该事件来实现路由的切换。
例如,当我们访问Example Domain时,浏览器会将#后面的内容作为hash值,即/home。当我们点击页面上的链接切换到另一个路由时,实际上是修改了URL中的hash值,而不是发送一个新的请求。
history模式 在history模式下,URL中不再需要#符号,而是直接使用正常的URL路径。
当我们访问http://example.com/home时,浏览器会向服务器发送一个请求,服务器会返回对应的页面内容。当我们点击页面上的链接切换到另一个路由时,实际上是使用了HTML5的history API,通过pushState或replaceState方法修改了浏览器的历史记录,同时也修改了URL路径。
Vue路由的钩子函数包括:
beforeEach(to, from, next):在路由跳转之前执行,可以用来进行全局的路由拦截和权限控制。
afterEach(to, from):在路由跳转之后执行,可以用来进行页面的统计和日志记录等操作。
beforeRouteEnter(to, from, next):在进入路由之前执行,可以用来进行异步数据的获取和页面的初始化等操作。
beforeRouteUpdate(to, from, next):在当前路由更新时执行,可以用来进行组件的更新和数据的同步等操作。
beforeRouteLeave(to, from, next):在离开当前路由之前执行,可以用来进行数据的保存和页面的确认等操作。
v-if和v-show都是用来控制元素的显示与隐藏
1、v-if是根据表达式的值来决定是否渲染元素,如果表达式的值为false,则元素不会被渲染到页面中,如果表达式的值为true,则元素会被渲染到页面中。
2、v-if在切换时有较高的切换性能开销,因为它会在每次切换时重新渲染元素及其子组件。 v-show也是根据表达式的值来决定元素是否显示
3、但是不同的是,v-show只是控制元素的CSS属性display的值,如果表达式的值为false,则元素的display属性被设置为none,元素仍然存在于DOM中,如果表达式的值为true,则元素的display属性被设置为原来的值,元素仍然存在于DOM中。
4、v-show在切换时没有额外的性能开销,因为元素始终存在于DOM中,只是控制其显示与隐藏。
$route和$router都是Vue.js中的路由相关对象,但是它们的作用和使用方式有所不同。
$route是Vue.js中的路由信息对象,它包含了当前路由的一些信息,比如路由路径、参数、查询参数等。
$route对象可以在组件中通过this.$route访问到。
$router是Vue.js中的路由实例对象,它负责管理路由的跳转和导航。
$router对象可以在组件中通过this.$router访问到。通过$router对象,我们可以进行路由的跳转、导航等操作。
CSS模块化 使用CSS模块化,可以将CSS文件与组件文件分离,每个组件都有自己的CSS文件,这样可以避免CSS样式的冲突,在React中,可以使用CSS Modules库来实现CSS模块化。
使用CSS Modules的步骤如下: 1. 在组件文件中引入CSS文件,并将CSS文件名改为“文件名.module.css”。 2. 在组件中使用CSS类名时,需要使用“styles.类名”来引用。
在组件中使用样式
使用less文件,只需要保证最外层容器类名不相同就可以了
<keep-alive></keep-alive>
的作用是什么?
<keep-alive></keep-alive>
是Vue.js中的一个内置组件,它的作用是用来缓存组件实例,以避免重复渲染和销毁。当一个组件被包裹在
<keep-alive></keep-alive>
标签中时,它不会被销毁,而是被缓存起来,直到它被再次使用。这样可以提高应用程序的性能,因为不需要每次重新渲染和初始化组件。
在使用
<keep-alive></keep-alive>
时,可以通过设置include
和exclude
属性来控制哪些组件需要缓存,哪些不需要。
在Vue中使用插件的步骤如下:
安装插件:使用npm或yarn等包管理工具安装需要的插件。
引入插件:在Vue项目的入口文件(如main.js)中引入插件。
注册插件:使用Vue.use()方法注册插件。
使用插件:在Vue组件中使用插件提供的功能。
created:在实例创建完成后被立即调用,可以在这个阶段进行数据的初始化和方法的定义等操作。
mounted:在实例挂载到DOM元素上后被立即调用,可以在这个阶段进行DOM操作和异步请求等操作。
updated:当数据发生变化时,组件会重新渲染,此时updated钩子函数会被调用,可以在这个阶段进行DOM操作和数据更新等操作。
vue SSR是指在服务器端将vue组件渲染成HTML字符串,然后将其发送到浏览器端进行展示的过程。
优点
更好的SEO:由于搜索引擎爬虫无法执行JavaScript,因此传统的客户端渲染对SEO不友好。而SSR可以在服务器端生成完整的HTML页面,有利于搜索引擎的爬取和索引。
更快的首屏加载速度:传统的客户端渲染需要先下载JavaScript文件,然后再进行渲染,这会导致首屏加载速度较慢。而SSR可以在服务器端生成完整的HTML页面,减少了客户端渲染的时间,从而提高了首屏加载速度。
更好的用户体验:由于SSR可以在服务器端生成完整的HTML页面,因此用户可以更快地看到页面内容,减少了等待时间,提高了用户体验
1、更加灵活:proxy可以代理整个对象,而不是像defined Property只能代理对象的某个属性,这就使得proxy更加的灵活,可以处理更多的场景
2、更加强大:proxy可以拦截更多的操作,比如像函数的调用、构造函数等,而defined Property只能拦截对象属性的读写操作
3、更加直观:proxy的api更加直观,易于理解和使用,而defined Property的api比较复杂,需要更深入的了解对象的内部机制
4、更加安全:proxy可以防止一些常见的安全漏洞,比如对象属性被篡改,对象属性被删除等,而defined Property无法完全的解决这些问题
5、更加高效:proxy的性能比defined Property更好,因为proxy可以在底层实现中进行优化,而defined Property的实现比较复杂,性能相对较差
vuex是一个专门为vuejs设计的状态管理库,它可以集中管理vue应用中的所有组件的状态,vuex的核心概念包括state、mutation、getters、actions、modules
state:存储应用的状态数据,可以通过this.$store.state访问。
mutations:用于修改state中的数据,只能进行同步操作,可以通过this.$store.commit()方法调用。
actions:用于处理异步操作,可以通过this.$store.dispatch()方法调用。
getters:用于从state中派生出一些状态,可以通过this.$store.getters访问。
modules:将应用的状态分割成多个模块,每个模块都有自己的state、mutations、actions和getters
使用Vuex需要先在Vue应用中安装它,可以通过npm或者CDN方式引入。然后在Vue应用中创建一个store对象,将state、mutations、actions、getters和modules等配置项传入,最后在Vue实例中将store对象注入到Vue实例中即可。
使用Vuex的场景包括: - 应用中有多个组件需要共享状态数据。 - 应用中有复杂的状态逻辑,需要集中管理。 - 应用中有大量的异步操作,需要统一管理。
vue2.x的响应式原理是通过数据劫持和发布订阅模式来进行实现
数据劫持:Vue2.x通过Object.defineProperty()方法来实现数据劫持,即在数据被访问或修改时,能够触发相应的操作。在Vue2.x中,每个组件实例都有一个对应的Watcher实例,当组件中的数据发生变化时,Watcher实例会通知组件进行重新渲染。
发布订阅模式:Vue2.x中使用了发布订阅模式来实现数据的响应式。在Vue2.x中,每个组件实例都有一个对应的Dep实例,用于存储Watcher实例。当组件中的数据发生变化时,Dep实例会通知所有的Watcher实例进行更新。
具体实现流程如下:
在Vue2.x中,通过Object.defineProperty()方法来实现数据劫持,即在数据被访问或修改时,能够触发相应的操作。
在组件实例创建时,会对组件中的所有数据进行遍历,为每个数据创建一个对应的Dep实例,并将该数据的所有Watcher实例存储到Dep实例中。
当组件中的数据发生变化时,会触发对应数据的setter方法,setter方法会通知该数据对应的Dep实例进行更新。
Dep实例会遍历存储在其中的所有Watcher实例,并通知它们进行更新。 5. Watcher实例接收到更新通知后,会触发组件的重新渲染。
ES5是ECMAScript 5的缩写,是JavaScript的第五个版本,于2009年发布。
ES6是ECMAScript 6的缩写,也称为ES2015,是JavaScript的第六个版本,于2015年发布。
ES6相对于ES5来说,增加了很多新的语法和特性,包括箭头函数、let和const关键字、模板字符串、解构赋值、类和模块等。
这些新特性使得JavaScript更加现代化、易读易写、可维护性更高。
ES2015是ES6的另一个名称,因为在发布时,ECMAScript委员会决定将ES6更名为ES2015,以反映其发布年份。从ES2015开始,ECMAScript每年都会发布一个新版本,因此ES6也可以看作是ES2015的第一个版本。
let和var都是用来声明变量的关键字,但它们有一些不同之处。
作用域:使用var声明的变量是函数作用域或全局作用域,而使用let声明的变量是块级作用域。块级作用域指的是在if语句、for循环、函数等花括号内部声明的变量只在该花括号内部有效。
变量提升:使用var声明的变量会发生变量提升,即变量可以在声明之前使用,但是值为undefined。而使用let声明的变量不会发生变量提升,即在声明之前使用会报错。
重复声明:使用var声明的变量可以重复声明,后面的声明会覆盖前面的声明。而使用let声明的变量在同一作用域内不能重复声明。
模板字符串:使用反引号(`)来创建字符串模板,可以在其中插入变量或表达式,更加方便易读。
字符串扩展方法:ES6提供了许多新的字符串方法,如startsWith()、endsWith()、includes()、repeat()等,使字符串的操作更加方便。
解构赋值:可以使用解构赋值来将字符串拆分成单个字符或子串,更加灵活。
字符串的遍历器接口:ES6为字符串添加了遍历器接口,可以使用for...of循环遍历字符串中的每个字符。
Unicode支持:ES6支持Unicode字符集,可以使用\u或\u{}来表示Unicode字符,同时也提供了一些新的Unicode相关方法,如codePointAt()、String.fromCodePoint()等。
正则表达式升级:ES6对正则表达式进行了升级,添加了u修饰符,支持处理Unicode字符,同时也提供了新的正则表达式方法,如sticky、flags等。
扩展运算符(Spread Operator):可以将一个数组展开成多个参数,或者将多个参数组合成一个数组。
Array.from()方法:可以将类数组对象或可迭代对象转换成数组。
Array.of()方法:可以将一组值转换成数组。
find()和findIndex()方法:可以在数组中查找符合条件的元素,并返回它的值或索引。
includes()方法:可以判断数组中是否包含某个元素。
fill()方法:可以用指定的值填充数组中的所有元素。
flat()和flatMap()方法:可以将嵌套的数组展开成一维数组,并对每个元素执行指定的操作。
reduce()方法的初始值参数:可以指定reduce()方法的初始值,避免空数组时出现错误。
箭头函数和forEach()方法:可以简化数组的遍历操作。 10. map()、filter()和reduce()方法的返回值:可以链式调用这些方法,使代码更加简洁易读。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。