9.7 vue/react面经

Babel 的原理是什么?

babel 的转译过程也分为三个阶段,这三步具体是:
解析 Parse: 将代码解析生成抽象语法树( 即 AST ),即词法分析与语法分 析的过程
转换 Transform: 对于 AST 进行变换一系列的操作,babel 接受得到 AST 并通过 babel-traverse 对其进行遍历,在此过程中进行添加、更新 及移除等操作
生成 Generate: 将变换后的 AST 再转换为 JS 代码, 使用到的模块是 babel-generator
在这里插入图片描述

有使用过 Vue 吗?说说你对 Vue 的理解

Vue 是一个构建数据驱动的渐进性框架,它的目标是通过 API 实现响应数据绑定视图更新

说说 Vue 的优缺点

优点:
1、数据驱动视图,对真实 dom 进行抽象出 virtual dom(本质就是一个 js 对象),并配合 diff 算法、响应式和观察者、异步队列等手段以最小代价更新 dom,渲染页面
2、组件化,组件用单文件的形式进行代码的组织编写,使得我们可以在一个文 件里编写 html\css(scoped属性配置css 隔离)\js 并且配合 Vue-loader 之后,支持更强大的预处理器等功能
3、强大且丰富的 API 提供一系列的 api 能满足业务开发中各类需求
4、由于采用虚拟 dom,让 Vue ssr 先天就足
5、生命周期钩子函数,选项式的代码组织方式,写熟了还是蛮顺畅的,但仍然 有优化空间(Vue3 composition-api)
6、生态好,社区活跃

缺点:
1、由于底层基于 Object.defineProperty 实现响应式,而这个 api 本身不支持 IE8 及以下浏览器
2、csr 的先天不足,首屏性能问题(白屏)
3、由于百度等搜索引擎爬虫无法爬取 js 中的内容,故 spa 先天就对 seo 优化心 有余力不足(谷歌的 puppeteer 就挺牛逼的,实现预渲染底层也是用到了这个工 具)

vue生命周期

vue 如何监听键盘事件?

@keyup.方法
@keyup.enter=“handleKey”
addEventListener

watch 怎么深度监听对象变化

deep 设置为 true 就可以监听到对象的变化

let vm = new Vue({ 
	el:"#first", 
	data:{
	    msg:{name:'北京'}
	}, 
	watch: { 
		msg:{
			handler (newMsg,oldMsg){ 
				console.log(newMsg); 
			},
			immediate:true, 
			deep:true 
		} 
	} 
})

删除数组用 delete 和 Vue.delete 有什么区别?

delete:只是被删除数组成员变为 empty / undefined,其他元素键值不变
Vue.delete:直接删了数组成员,并改变了数组的键值(对象是响应式的,确保删除能触发更新视图,这个方法主要用于避开 Vue 不能检测到属性被删除的限 制)

watch 和计算属性有什么区别

通俗来讲,既能用 computed 实现又可以用 watch 监听来实现的功能,推荐用 computed, 重点在于 computed 的缓存功能
computed 计算属性是用来声明式的描述一个值依赖了其它的值,当所依赖的值或者变量 改变时,计算属性也会跟着改变;
watch 监听的是已经在 data 中定义的变量,当该变量变化时,会触发 watch 中的方法。

Vue 双向绑定原理

Vue 数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的。利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)。

v-model 是什么?有什么用呢?

一则语法糖,相当于 v-bind:value=“xxx” 和 @input,意思是绑定了一个 value 属性的值, 子组件可对 value 属性监听,通过$emit(‘input’, xxx)的方式给父组件通讯。自己实现 v-model 方式的组件也是这样的思路。

Vue3.0 里为什么要用 Proxy API 替代 defineProperty API?

a. defineProperty API 的局限性最大原因是它只能针对单例属性做监听。 Vue2.x 中的响应式实现正是基于 defineProperty 中的 descriptor,对 data 中的属性做了遍 历 + 递归,为每个属性设置了 getter、setter。 这也就是为什么 Vue 只能对 data 中预定义过的属性做出响应的原因,在 Vue 中使用 下标的方式直接修改属性的值或者添加一个预先不存在的对象属性是无法做到 setter 监 听的,这是 defineProperty 的局限性。
b. Proxy API 的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作,这就完全可以代理所有属性,将会带来很大的性能提升和更优的代码。 Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须 先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
c. 响应式是惰性的 在 Vue.js 2.x 中,对于一个深层属性嵌套的对象,要劫持它内部深层次的变化,就需要 递归遍历这个对象,执行 Object.defineProperty 把每一层对象数据都变成响应式的,这 无疑会有很大的性能消耗。 在 Vue.js 3.0 中,使用 Proxy API 并不能监听到对象内部深层次的属性变化,因此它的 处理方式是在 getter 中去递归响应式,这样的好处是真正访问到的内部属性才会变成响 应式,简单的可以说是按需实现响应式,减少性能消耗。

React 生命周期函数

componentWillMount:组件即将被装载、渲染到页面上
componentDidMount:组件真正在被装载之后
shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回 false,接收数据 后不更新,阻止 render 调用,后面的函数不会被继续执行了)
componentWillUpdate:组件即将更新不能修改属性和状态
render:组件重新描绘
componentDidUpdate:组件已经更新
componentWillUnmount:组件即将销毁

React 性能优化是哪个周期函数?

shouldComponentUpdate 这个方法用来判断是否需要调用 render 方法重新描绘 dom。因 为 dom 的描绘非常消耗性能,如果我们能在 shouldComponentUpdate 方法中能够写出更 优化的 dom diff 算法,可以极大的提高性能。

为什么虚拟 dom 会提高性能

虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能
具体实现步骤如下:
1.用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中;
2.当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异;
把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。

diff算法

1.把树形结构按照层级分解,只比较同级元素。
2.给列表结构的每个单元添加唯一的 key 属性,方便比较。
3.React 只会匹配相同 class 的 component(这里面的 class 指的是组件的名字)
4.合并操作,调用 component 的 setState 方法的时候, React 将其标记为 dirty.到每一个 事件循环结束, React 检查所有标记 dirty 的 component 重新绘制.
5.选择性子树渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能。

React 性能优化方案

1)重写 shouldComponentUpdate 来避免不必要的 dom 操作。
2)使用 production 版本的 React.js。
3)使用 key 来帮助 React 识别列表中所有子组件的最小变化

React 解决了什么问题?

解决了三个问题:
1.组件复用问题,
2.性能问题,
3.兼容性问题:

了解 shouldComponentUpdate 吗?

React 虚拟 dom 技术要求不断的将 dom 和虚拟 dom 进行 diff 比较,如果 dom 树比价大, 这种比较操作会比较耗时,因此 React 提供了 shouldComponentUpdate 这种补丁函数,如 果对于一些变化,如果我们不希望某个组件刷新,或者刷新后跟原来其实一样,就可以 使用这个函数直接告诉 React,省去 diff 操作,进一步的提高了效率。

React 的工作原理?

React 会创建一个虚拟 DOM(virtual DOM)。当一个组件中的状态改变时,React 首先会 通过 “diffing” 算法来标记虚拟 DOM 中的改变,第二步是调节(reconciliation),会用 diff 的结果来更新 DOM。

使用 React 有何优点

1.只需查看 render 函数就会很容易知道一个组件是如何被渲染的
2.JSX 的引入,使得组件的代码更加可读,也更容易看懂组件的布局,或者组件之间是 如何互相引用的
3.支持服务端渲染,这可以改进 SEO 和性能
4.易于测试
5.React 只关注 View 层,所以可以和其它任何框架(如 Backbone.js, Angular.js)一起使用

展示组件(Presentational component)和容器组件(Container component)之间有 何不同?

1.展示组件关心组件看起来是什么。展示专门通过 props 接受数据和回调,并且几乎不会有自身的状态,但当展示组件拥有自身的状态时,通常也只关心 UI 状态而不是数据的状态。
2.容器组件则更关心组件是如何运作的。容器组件会为展示组件或者其它容器组件提供数据和行为(behavior),它们会调用 Flux actions,并将其作为回调提供给展示组件。容器组件经常是有状态的,因为它们是(其它组件的)数据源

类组件(Class component)和函数式组件(Functional component)之间有何不同?

1.类组件不仅允许你使用更多额外的功能,如组件自身的状态生命周期钩子,也能使组件直接访问 store 并维持状态
2.函数组件仅是接收 props,并将组件自身渲染到页面时,该组件就是一个 ‘无状态组件 (stateless component)’,可以使用一个纯函数来创建这样的组件。这种组件也被称为哑组件(dumb components)或展示组件

(组件的)状态(state)和属性(props)之间有何不同?

  1. State 是一种数据结构,用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变,但多数时候是作为用户事件行为的结果。
  2. Props(properties 的简写)则是组件的配置。props 由父组件传递给子组件,并且就子组件而言,props 是不可变的(immutable)。组件不能改变自身的 props,但是可以把其子组件的 props 放在一起(统一管理)。Props 也不仅仅是数据–回调函数也可以通过 props 传递

应该在 React 组件的何处发起 Ajax 请求?

在 React 组件中,应该在 componentDidMount 中发起网络请求。这个方法会在组件第 一次“挂载”(被添加到 DOM)时执行,在组件的生命周期中仅会执行一次。更重要的是, 你不能保证在组件挂载之前 Ajax 请求已经完成,如果是这样,也就意味着你将尝试在 一个未挂载的组件上调用 setState,这将不起作用。在 componentDidMount 中发起网络 请求将保证这有一个组件可以更新了

在 React 中,refs 的作用是什么?

Refs 可以用于获取一个 DOM 节点或者 React 组件的引用。何时使用 refs 的好的示例 有管理焦点/文本选择,触发命令动画,或者和第三方 DOM 库集成。你应该避免使用 String 类型的 Refs 和内联的 ref 回调。Refs 回调是 React 所推荐的

何为高阶组件(higher order component)?

高阶组件是一个以组件为参数并返回一个新组件的函数。HOC 运行你重用代码、逻辑 和引导抽象。最常见的可能是 Redux 的 connect 函数。除了简单分享工具库和简单的 组合,HOC 最好的方式是共享 React 组件之间的行为。如果你发现你在不同的地方写了大量代码来做同一件事时,就应该考虑将代码重构为可重用的 HOC

使用箭头函数(arrow functions)的优点是什么?

  1. 作用域安全:在箭头函数之前,每一个新创建的函数都有定义自身的 this 值(在构造 函数中是新对象;在严格模式下,函数调用中的 this 是未定义的;如果函数被称为“对 象方法”,则为基础对象等),但箭头函数不会,它会使用封闭执行上下文的 this 值。
  2. 简单:箭头函数易于阅读和书写
  3. 清晰:当一切都是一个箭头函数,任何常规函数都可以立即用于定义作用域。开发者 总是可以查找 next-higher 函数语句,以查看 this 的值

为什么建议传递给 setState 的参数是一个 callback 而不是一个对象?

因为 this.props 和 this.state 的更新可能是异步的,不能依赖它们的值去计算下一个 state。

除了在构造函数中绑定 this,还有其它方式吗?

可以使用属性初始值设定项(property initializers)来正确绑定回调,create-React-app 也是 默认支持的。在回调中你可以使用箭头函数,但问题是每次组件渲染时都会创建一个新的回调。

当渲染一个列表时,何为 key?设置 key 的目的是什么?

Keys 会有助于 React 识别哪些 items 改变了,被添加了或者被移除了。Keys 应该被赋 予数组内的元素以赋予(DOM)元素一个稳定的标识,选择一个 key 的最佳方法是使用一 个字符串,该字符串能惟一地标识一个列表项。很多时候你会使用数据中的 ID 作为 keys,当你没有稳定的 IDs 用于被渲染的 items 时,可以使用项目索引作为渲染项的 key,但这种方式并不推荐,如果 items 可以重新排序,就会导致 re-render 变慢

在构造函数中)调用 super(props) 的目的是什么?

在 super() 被调用之前,子类是不能使用 this 的,在 ES2015 中,子类必须在 constructor 中调用 super()。传递 props 给 super() 的原因则是便于(在子类中)能在 constructor 访问 this.props。

何为 JSX

JSX 是 JavaScript 语法的一种语法扩展,并拥有 JavaScript 的全部功能。JSX 生产 React “元素”,你可以将任何的 JavaScript 表达式封装在花括号里,然后将其嵌入到 JSX 中。在编译完成之后,JSX 表达式就变成了常规的 JavaScript 对象,这意味着你可以在 if 语句和 for 循环内部使用 JSX,将它赋值给变量,接受它作为参数,并从函数中返回它。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值