【面試總結】記一次失敗的 bilibili 面試總結(3)
- 面試總結(1):HTML佈局、CSS選擇器及JS基礎綜合能力知識點
- 演算法基礎:陣列flat、去重及排序
- React Vue 理解及基礎知識
- 跨域問題解決方案
- http協議狀態碼
- 快取及更新問題
- webview與原生應用互動
- 伺服器端知識
React 、 Vue 和 Angular 已形成了前端界三足鼎立之勢。尤其是 React 與 Vue, React 出色的生態與 Vue 完善的中文文件在國內,已經是大部分公司的前端首選技術棧。瞭解 React 與 Vue 的基礎知識考點也是十分之有必要了。下面通過對比的形式整理一下 React 與 Vue 的基礎考點,最後附上自己的認知。
ps:近期工作內容接觸 React 可能比較多,Vue 方面可能言辭欠妥,一旦發現,立馬糾正。
React 與 Vue 的基礎知識考點
生命週期
React
React 的生命週期可以大致分為3種類型
-
建立
componentWillMount render componentDidMount
-
更新
componentWillReceiveProps shouldComponentUpdate componentWillUpate render componentDidUpdate
-
解除安裝
-
componentWillUnmount
—— 元件即將被銷燬,在此處可以清理定時器、取消RxJS的訂閱行為等,防止記憶體溢位。
-
React V16後,因為引入了 Fiber 機制,之前的部分API可能會被反覆呼叫,所以React對生命週期的API進行了部分調整。
-
建立
-
componentWillMount
static getDerivedFromProps(nextProps, state)
—— 新的API是一個靜態方法,返回一個物件來更新state,如果返回null則不更新任何內容 -
render
-
componentDidMount
-
-
更新
-
componentWillReceiveProps
static getDerivedFromProps
-
shouldComponentUpdate
-
componentWillUpate
-
render
-
getSnapshotBeforeUpdate
—— 在最近一次渲染輸出(提交到 DOM 節點)之前呼叫,它使得元件能在發生更改之前從 DOM 中捕獲一些資訊(例如,滾動位置)。此生命週期的任何返回值將作為引數傳遞給 componentDidUpdate()。 -
componentDidUpdate
-
-
解除安裝
-
componentWillUnmount
-
vue
Vue的生命週期先附上官方文件。
Vue的生命週期也分成3個階段進行對比,vue的生命週期基本通過命名就可以瞭解大概的意思了,我著重說一下每個階段 Vue 都完成了什麼工作。
-
建立
beforeCreate created beforeMount mounted
-
更新
beforeUpdate updated
-
解除安裝
beforeDestory destroyed
元件通訊——父子元件
React
class Parent extends Component { state = { a: 6 } changeA = () => this.setState({ a: this.state.a + 1 }) render() { return ( <div> <Child // 完成 父 => 子 通訊,直接通過設定 props 傳遞 a={this.state.a} // 子 => 父 通訊,通過傳入繫結 this 的函式完成 changeA={this.changeA} /> <div> ) } } 複製程式碼
class Child extends Component { render() { return ( <div> {this.props.a} <button // 觸發父元件的方法,改變a的值,完成 子 => 父 的通訊 onClick={this.props.changeA} > +1 <button> <div> ) } } 複製程式碼
Vue
<template> <div> <Child <!-- 完成 父 => 子 的通訊 --> :a="a" <!-- 自定義事件 addOne 觸發時, 執行methods中的 addOne 方法 --> <!-- 完成 子 => 父 的通訊 --> @addOne="addOne" ></Child> </div> </template> <script> import Child from 'xxx'; export default { name: 'Parent', data() { return { a: 5 } }, methods: { addOne(value) { this.data = value } }, components: { Child } } </script> 複製程式碼
<template> <div> {{a}} <button @click={changeA}>+1</button> </div> </template> <script> export default { name: 'Child', props: { a: Number }, methods: { changeA() { // 出發 自定義事件 addOne, 並將第二個常數作為引數傳遞 this.$emit('addOne', this.a + 1) } } } </script> 複製程式碼
React 的一句話作答
setState 執行後為什麼state無法正確獲取設定之後的值
setState之後, React並沒有立刻更改 state 的值, 因為每次改變state都去計算生成新的VDom樹並更新Dom是一件代價高昂的事情, React的做法是將setState設計成為一個非同步行為, 多次setState會合併成為一次, 在最後去計算生成Dom, 優化效能。
this.setState({ a: 5 }, () => { // setState 提供的第二個引數是一個回撥函式 // 這裡能夠正確獲取 state 裡面的值 }) 複製程式碼
為什麼建議使用 Stateless Function
- 程式碼更少, 邏輯更清晰
- 更加符合 React 資料流從頂部開始的設計初衷
- 不用使用 bind 方法
React如何使用 Virtual Dom 及其優勢
在JS中操作Dom的開銷由於會引發瀏覽器的重排重繪機制, 效能消耗十分顯著, 然後在JS中操作物件的效率很高。React團隊通過Diff演算法, 對比新舊兩個 VDom 的內容, 找出不同, 一次性更新Dom, 減少開銷。React團隊通過直接對比相同層的內容等演算法的優化, 將演算法複雜度降低到O(n)。
Vue 的一句話作答
v-if 與 v-show 的區別
v-if會將Dom直接從當前Dom樹移除, v-show則是相當於設定了display: none
, 但是Dom依舊存在於Dom樹中。兩種情況各有利弊,類似快取,視情況不同選擇不同。
為什麼 data 使用的是function 返回一個物件
data 如果是一個物件的話,當某元件有多個例項時,修改某一例項中 data 屬性,因為 data 是引用型別,會導致其他例項均受到影響。