vue生命周期
生命周期:实例初始化之前:beforeCreate实例初始化:created挂载前:beforeMount(生成虚拟dom)挂载完成:mounted更新前:beforeUpdate更新完成:updated组件销毁前:beforeDestroy组件销毁完成:destroyed
操作dom在哪个生命周期
vuemounted
vue2.0和3.0的区别
Object.defineProperty是vue2.0的原理
Proxy是vue3.0的原理
vue2.0的缺点
Vue 不能检测数组和对象的变化。
Vue 无法检测对象属性的添加或移除。 因为Object.defineProperty的特性决定的
Vue 不能检测以下数组的长度length的改变 变异方法 7种
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
再执行dep.notify()
Vue.nextTick 是形成一个异步任务
MVVM
MVVM是Model-View-ViewModel的简写M----->Model层:请求的原始数据V----->View层:视图展示,由ViewController来控制VM---->ViewModel层:负责业务处理和数据转化
complie
模板编译
双向绑定的原理
vue实现数据双向绑定主要是采用数据劫持结合发布订阅模式的方式。通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调
computed watch methods
computed是计算属性,methods是方法。computed计算属性是基于它们的依赖进行缓存的computed只有在它的相关依赖发生改变时才会重新求值而对于method ,只要发生重新渲染,method 调用总会执行该函数总之:数据量大,需要缓存的时候用computed;每次确实需要重新加载,不需要缓存时用methods计算属性是计算属性,侦听器watch是侦听器watch侦听器watch是侦听一个特定的值,当该值变化时执行特定的函数
v-if v-show的区别
v-show和v-if都是用来显示隐藏元素v-show不管条件是真还是假,第一次渲染的时候都会编译出来,也就是标签都会添加到DOM中。之后切换的时候,通过display: none;样式来显示隐藏元素。可以说只是改变css的样式,几乎不会影响什么性能。v-if在首次渲染的时候,如果条件为假,什么也不操作,页面当作没有这些元素。当条件为真的时候,开始局部编译,动态的向DOM元素里面添加元素。当条件从真变为假的时候,开始局部编译,卸载这些元素,也就是删除。性能方面v-if绝对是更消耗性能的,因为v-if在显示隐藏过程中有DOM的添加和删除,v-show就简单多了,只是操作css。
vuex的理解
是一个vue实例vuex是适用于vue.js应用的状态管理库state:状态actions:异步操作mutations:同步操作getters:结合state使用modules:拆分store
辅助函数
mapStatemapGettersmapActionsmapMutations
REACT
react生命周期
react生命周期
JSX
react.createElement()实际就是一个对象在JSX中,我们结合了javascript和HTML,并生成了可以在DOM中呈现的react元素。优点:JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。它是类型安全的,在编译过程中就能发现错误。使用 JSX 编写模板更加简单快速。
setState的原理
是类组件中唯一更改state状态的方法,接收两个参数1. setState接收一个新的状态2. 该接收到的新状态不会被立即执行么,而是存入到pendingStates(等待队列)中3. 判断isBatchingUpdates(是否是批量更新模式) 1>. isBatchingUpdates: true 将接收到的新状态保存到dirtyComponents(脏组件)中 2>. isBatchingUpdates: false 遍历所有的dirtyComponents, 并且调用其 updateComponent方法更新pendingStates中的state 或者props。 执行完之后,回将isBatchingUpdates: true。
setState
react-fiber
react-fiber
hooks解决的问题
Hook 是 React 16.8 的新增特性。react分为两类组件:函数式组件和类组件,两个组件各有优劣,类组件有自己本身的状态和改变状态的方法。而想在函数式组件有自身的状态,可以用hooks。1. 在组件之间复用状态逻辑很难 providers,consumers,高阶组件,render props里面的嵌套会很多,所以组件之间的复用会很难。2.复杂组件变得难以理解3.难以理解的 class Hook 使你在非 class 的情况下可以使用更多的 React 特性。
react性能优化
react
dva初始化数据来源
dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。在框架umijs里面使用dva没有api,只有一个umijs的插件@umijs/plugin-dva
@umijs/plugin-dva
高阶组件的认识
一个高阶组件只是一个包装了另外一个 React 组件的 React 组件,类似于高阶函数。因为要访问它的内部状态,所以要用到继承高阶组件就是一个函数,它接受另一个组件作为参数,并返回一个新的组件。当 React 组件被包裹时(warped),高阶组件会返回一个增强的 React 组件。高阶组件让代码更具有复用性、逻辑性和抽象特性为了代码的复用性,减少代码的冗余
高阶组件
redux的使用
发布订阅
redux
class组件与函数组件的区别
class组件特点:
有组件实例
有生命周期
有 state 和 setState
函数组件特点:
没有组件实例
没有生命周期
没有 state 和 setState,只能接收 props
函数组件是一个纯函数,执行完即销毁,无法存储 state
函数组件的优势
函数式组件性能消耗小
函数式组件更灵活,更易拆分
useEffect理解
useEffect Hook 可以让你在函数组件中执行副作用操作
有两个参数,第一个参数是一个函数,里面写的是默认每次渲染之后会执行的动作
第二个参数是一个数组,当数组中的任意一项变化的时候,useEffect会被重新执行
是一个空数组的时候,就只会执行一次
react在那个生命周期操作dom
componentDidMount
在什么场景应用卸载生命周期
componentWillUnmount
受控组件和非受控组件
在React中,每当表单的状态发生变化时,都会被写入到组件的state中,这种组件在React被称为受控组件1. 可以通过在初始state中动态设置value值 2. 每当表单的值发生变化时,调用onChange事件处理器。如果添加了value (单选框和复选框对应的是checked)而没有添加onChange会受到react警告 3. 事件处理器通过合成事件对象e拿到改变后的状态,并更新state。4. setState触发视图的重新渲染,完成表单组件值得更新表现形式上,react中没有添加value属性(单选按钮和复选框对应的是checked)的表单组件元素就是非受控组件1.非受控组件即不受状态的控制,获取数据就是相当于操作DOM。 2.非受控组件的好处是很容易和第三方组件结合。
VUE和REACT混合
虚拟dom的理解
render 渲染真实dom
Virtual Domvue中的虚拟domreact的虚拟dom
diff算法
diff 作为 Virtual DOM 的加速器,其算法上的改进优化是React页面渲染的基础和性能保障。React中最值得称道的莫过于Virtual DOM与diff的完美结合,尤其是其高效的diff算法,可以帮助我们在页面蔌渲染的时候,计算出Virtual DOM真正变化的部分,并只针对该部分进行的原生DOM操作,而不是渲染整个页面,从而保证了每次操作后,页面的高效渲染。计算与上一次页面渲染时候的不同,只渲染不同的地方,不渲染整个页面diff算法是一种优化算法,会比较比较同级节点diff算法把树形结构按照层级划分,只比较同级元素
key
vue中v-for渲染数据时候用到唯一标识keyreact中的key 我们要确保key值的唯一,事实上如果key值不唯一的话,react只会渲染第一个,剩下的react会认为是同一项,直接忽略
组件通信的哪几种方式
react组件通信: 父组件向子组件通信 子组件向父组件通信 跨级组件通信 没有嵌套关系组件之间的通信 1.父组件向子组件通信 通过props 2.子组件向父组件通信 利用回调函数 利用自定义事件机制 3.跨级组件通信 层层组件传递props 使用context 4.没有嵌套关系组件之间的通信 使用自定义事件机制
react组件通信vue组件通信:(备注:不会的可以不说)父子通信:父向子传递数据是通过 props,子向父是通过 events($emit);通过父链 / 子链也可以通信($parent / $children);ref 也可以访问组件实例;provide / inject API;$attrs/$listeners兄弟通信:Bus;Vuex跨级通信:Bus;Vuex;provide / inject API、$attrs/$listenersvue组件通信
vue和react的区别
相同点: 1,都支持props进行父子组件间数据通信 2,都支持数据驱动试图,不直接操作真是DOM,更新状态数据界面就自动更新 3,都支持服务器端渲染不同点: 1,数据绑定:vue实现了数据的双向邦定,react数据流动是单向的 2, state对象在React应用中不可变的,需要使用setState方法更新状态,在vue中 state对不是必须的, 数据由data属性在vue对象中管理 3,Vue会跟踪每个组件,不需要重新渲染整个组件树,react就会全部组件都会重新渲染, 所以react中会需要shouldComponentUpdata 这个生命周期函数方法来进行控制Vue使用templates与React的JSX状态管理:vue使用vuexreact使用redux或dva或mobx
路由常见的钩子函数及相关参数
vue路由:route:首先它是个单数,译为路由,即我们可以理解为单个路由或者某一个路由;
routes:它是个复数,表示多个的集合才能为复数;即我们可以理解为多个路由的集合,
JS中表示多种不同状态的集合的形式只有数组和对象两种,事实上官方定义routes是一个数组;
所以我们记住了,routes表示多个数组的集合;
router:译为路由器,上面都是路由,这个是路由器,
我们可以理解为一个容器包含上述两个或者说它是一个管理者,负责管理上述两个;
举个常见的场景的例子:当用户在页面上点击按钮的时候,这个时候router就会去routes中去查找route,
就是说路由器会去路由集合中找对应的路由;
router-view 视图渲染
react路由:react-router-dom:参数:BrowserRouter(history模式的路由) Route(路由),Link||NavLink(路由跳转),Switch(是唯一的因为它仅仅只会渲染一个路径)Redirect(路由重定向)
CSS
清除浮动
清除浮动主要是为了解决,父元素因为子级元素浮动引起的内部高度为0的问题 1.额外标签法(在最后一个浮动标签后,新加一个标签,给其设置clear:both;) 2.父级添加overflow属性(父元素添加overflow:hidden) 3.使用after伪元素清除浮动 4.使用before和after双伪元素清除浮动
盒子模型
Margin(外边距) - 清除边框外的区域,外边距是透明的。Border(边框) - 围绕在内边距和内容外的边框。Padding(内边距) - 清除内容周围的区域,内边距是透明的。Content(内容) - 盒子的内容,显示文本和图像。 总元素的宽度=宽度+左填充+右填充+左边框+右边框+左边距+右边距 总元素的高度=高度+顶部填充+底部填充+上边框+下边框+上边距+下边距怪异盒模型:(IE)content+margin(padding+border已经包含在content中)
px和em的区别
px:绝对单位,页面按精确像素展示。em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算(浏览器默认字体是16px),整个页面内1em不是一个固定的值。rem:相对单位,可理解为”root em”, 相对根节点html的字体大小来计算
初始化页面闪动怎么解决
首先:在css里加上[v-cloak] {display: none;}。如果没有彻底解决问题,则在根元素加上style="display: none;" :style="{display: 'block'}"
flex布局
flex布局又叫弹性盒布局,在移动端使用比较多一点。设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。父元素称为“容器”,子元素称为“项目”。容器的属性: 1.flex-direction 2.flex-wrap 3.flex-flow 4.justify-content 5.align-items 6.align-content项目的属性: 1.order 2.flex-grow 3.flex-shrink 4.flex-basis 5.flex 6.align-self
flex布局
如何让元素水平垂直居中
水平垂直居中
使用 flex 弹性布局
使用 transform 变形
使用 position 定位
使用 transform 与 position 结合
CALC
css3calc() 函数用于动态计算长度值。运算符前后都需要保留一个空格;任何长度值都可以使用calc()函数进行计算;calc()函数支持 "+", "-", "*", "/" 运算;calc()函数使用标准的数学运算优先级规则;
BFC
BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
BFC
有几种定位方式
positionstatic 默认静态relative 绝对定位fixed 固定定位absolute 相对定位sticky 用户的滚动位置定位
怎么实现双飞翼布局
侧边两栏宽度固定,中间栏宽度自适应left、center、right三种都设置左浮动设置center宽度为100%设置负边距,left设置负边距为100%,right设置负边距为自身宽度设置content的margin值为左右两个侧栏留出空间,margin值大小为left和right宽度
box-sizing
在 CSS 盒子模型的默认定义里,你对一个元素所设置的 width 与 height 只会应用到这个元素的内容区。如果这个元素有任何的 border 或 padding ,绘制到屏幕上时的盒子宽度和高度会加上设置的边框和内边距值。content-box 是默认值。如果你设置一个元素的宽为100px,那么这个元素的内容区会有100px宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中。border-box 告诉浏览器:你想要设置的边框和内边距的值是包含在width内的。也就是说,如果你将一个元素的width设为100px,那么这100px会包含它的border和padding,内容区的实际宽度是width减去(border + padding)的值。
怎么解决移动端适配
移动端适配
rem.em.px区别
px是像素em是相对单位,一般都是以当前对象内的字体大小作基准的。em是相对于父元素的属性来计算的如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。rem是相对于根元素html的字体大小
移动端适配 有哪些常用的css单位
rem em
display有几个属性
display
JS
对同步和异步的理解
js是一个单线程的语言,同步和异步的差别就在于在单线程里面各个流程的执行顺序不同。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。举例子,setTimeout和setInterval是常见的异步任务。在执行程序的时候,浏览器会默认setTimeout以及ajax请求这一类的方法都是耗时程序(尽管可能不耗时),将其加入一个队列中,该队列是一个存储耗时程序的队列,在所有不耗时程序也就是同步任务执行过后,再来依次执行该队列中的程序。于是,所有任务可以分成两种,一种是同步任务,另一种是异步任务。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"的任务,只有等主线程任务执行完毕,"任务队列"开始通知主线程,请求执行任务,该任务才会进入主线程执行。
闭包
闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另外一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用域链,将函数内部的变量和方法传递到外部。1.函数内再嵌套函数2.内部函数可以引用外层的参数和变量3.参数和变量不会被垃圾回收机制回收
闭包
概念:
有权访问另一个函数作用域中的变量的函数;一般情况就是在一个函数中包含另一个函数。
第一,闭包是一个函数,而且存在于另一个函数当中
第二,闭包可以访问到父级函数的变量,且该变量不会销毁
闭包的原理:
闭包的实现原理,其实是利用了作用域链的特性,我们都知道作用域链就是在当前执行环境下访问某个变量时,如果不存在就一直向外层寻找,
最终寻找到最外层也就是全局作用域,这样就形成了一个链条。
闭包作用
作用1:隐藏变量,避免全局污染
作用2:可以读取函数内部的变量
同时闭包使用不当,优点就变成了缺点:
缺点1:导致变量不会被垃圾回收机制回收,造成内存消耗
缺点2:不恰当的使用闭包可能会造成内存泄漏的问题
闭包的特点:
函数里面可以嵌套函数
内部函数可以引用外层的参数和变量
参数和变量不会被垃圾回收机制回收
闭包使用的场景是:
模块,用来做模块内部实现通过接口的扩展给其他函数使用
闭包可以用作于缓存值
闭包
防抖节流
防抖节流用setTimeout实现所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。对于短时间内连续触发的事件(resize、scroll、mousemove),防抖的含义就是让某个时间期限内,事件处理函数只执行一次。所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。
apply, call, bind
apply 方法接收两个参数:一个是 this 绑定的对象,一个是参数数组。
call 方法接收的参数,第一个是 this 绑定的对象,后面的其余参数是传入函数执行的参数。
bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了使用 new 时会被改变,其他情况下都不会改变。
注:xx.xx() 就是方法调用
改变this指向
构造函数和普通函数的区别
箭头函数不能做为构造函数
面向对象
构造函数
通过new关键字来调用的函数叫构造函数(箭头不能通过new关键字来调用,箭头不能当作构造函数来使用)
new关键字调用步骤
创建实例对象
运行该函数
修改该函数的this指向,指向实例对象
返回实例对象
function EsDailog(){ this.init=function(){ console.log("init"); } this.init(); } const oDailog=new EsDailog();
EsDailog 构造函数 它是 函数对象 函数对象才有prototype属性指向的是 oDailog 的proto原型对象
oDailog 实例对象 也就是 this
原型链是一级一级往上找,如果找不到就会抛出一个报错
this 关键字是上下文对象,在调用时生成的
const o={ run(){ console.log("this--",this); } } o.run()// 方法调用, this指向一般拥有该函数方法的对象 const run1=o.run; run1() //普通函数调用,this指向一般指向全局对象(window) new (o.run)() //通过new关键字调用,run变成构造函数了,this指向实例对象 注:xx.xx() 就是方法调用 run1.call({}) // this指向 第一个参数 null代表全局对象 run.apply({}) //this指向 第一个参数 null代表全局对象 run1.call({}) // 第一个参数是改变this指向的参数 null代表全局对象 run1.apply({}) // 第一个参数是改变this指向的参数 第二个参数是数组 run.bind() //他的优先级最高 一旦通过它绑定的this指向,call、apply就改变不了this的指向了
js 有自己的垃圾回收机制
浏览器自己去运行垃圾回收,在你cpu使用频率不高时去运行,不太会占用js运行时间
类型 :基本类型,引用类型
引用类型:对象,函数,数组
对象是引用类型的值,存放在堆内存中
基本类型的值放在栈内存中
怎么去回收
标记清除法
在声明变量时浏览器会在当前作用域标记该变量。在离开当前作用域时并且该变量没有被引用,浏览器垃圾回收就会清除。
引用计数法
什么情况下会造成内存泄漏?
当变量或对象或函数没有被标记,并且没有被引用。会造成内存泄漏
闭包
频繁使用定时器可能会造成内存泄漏
使用dom事件没有及时卸载
js相关知识
this指向:call, apply, bind
1. call和apply第一个参数都是改变this指向,call是有很多参数,apply有两个参数,第一个是this指向,第二 个是数组
2. bind()创建的是一个新的函数(称为绑定函数),与被调用函数有相同的函数体,当目标函数被调用时this的值绑定到 bind()的第一个参数上
怎么判断他是什么类型 (instanceof)
1. typeof
2. instanceof
3. constructor
4. prototype
原理,作用
typeof : 一个值使用 typeof 操作符可能返回下列某个字符串,返回的类型都是字符串形式。
(1) undefined:如果这个值未定义
(2) boolean:如果这个值是布尔值
(3) string:如果这个值是字符串
(4) number:如果这个值是数值
(5) object:如果这个值是对象或null
(6) function:如果这个值是函数
需要注意:typeof不适合用于判断是否为数组。当使用typeof判断数组和对象的时候,都会返回object。可以使用isArray()来判断是否为数组。
instanceof
(1) instanceof 运算符用来判断一个构造函数的prototype属性所指向的对象是否存在另外一个要检测对象的原型链上。需要区分大小写。
简单的来说,instanceof 用于判断一个变量是否某个对象的实例。
例:var arr = new Array( );
alert(arr instanceof Array); // 返回true
需要注意的是,instanceof只能用来判断对象和函数,不能用来判断字符串和数字等。判断它是否为字符串和数字时,只会返回false
constructor
(1) constructor 属性返回对创建此对象的数组函数的引用。
(2) 在JavaScript中,每个具有原型的对象都会自动获得constructor属性。
prototype
(1)以上三种方法多少都会有一些不能判断的情况。为了保证兼容性,可以通过Object.prototype.toString方法,判断某个对象值属于哪种内置类型。
(2)需要注意区分大小写。
js数据类型
任务执行顺序
先同步再异步,先微任务再宏任务
宏任务(setTimeout, setImmediate, setInterval, Ajax, requestAnimationFrame)
微任务(Promise, MutationObserve, process.nextTick)