【面試總結】記一次失敗的 bilibili 面試總結(3)

一顆賽艇?發表於2019-04-07

傳送門

React 、 Vue 和 Angular 已形成了前端界三足鼎立之勢。尤其是 React 與 Vue, React 出色的生態與 Vue 完善的中文文件在國內,已經是大部分公司的前端首選技術棧。瞭解 React 與 Vue 的基礎知識考點也是十分之有必要了。下面通過對比的形式整理一下 React 與 Vue 的基礎考點,最後附上自己的認知。

ps:近期工作內容接觸 React 可能比較多,Vue 方面可能言辭欠妥,一旦發現,立馬糾正。

React 與 Vue 的基礎知識考點

生命週期

React

React 的生命週期可以大致分為3種型別

  • 建立
    • componentWillMount —— 元件掛載前觸發;
    • render —— 建立一棵由 React 元素組成的樹;
    • componentDidMount —— 元件掛載後觸發,此時頁面已經存在DOM,建議在此處發起請求等操作,完成資料初始化;
  • 更新
    • componentWillReceiveProps —— 元件將要接受到上級的Props,此處可以通過props修改 state 的值;
    • shouldComponentUpdate —— React優化的重要API,決定該元件是否應該更新,當該元件繼承 PureComponent 時,shouldComponentUpdate 會對 props 與 state 做一個淺比較,來決定是否更新;
    • componentWillUpate —— 元件即將出發更新
    • render —— 建立一棵由 React 元素組成的樹;
    • componentDidUpdate —— 元件更新完畢
  • 解除安裝
    • componentWillUnmount —— 元件即將被銷燬,在此處可以清理定時器、取消RxJS的訂閱行為等,防止記憶體溢位。

React V16後,因為引入了 Fiber 機制,之前的部分API可能會被反覆呼叫,所以React對生命週期的API進行了部分調整。

  • 建立
    • componentWillMount static getDerivedStateFromProps(nextProps, state) —— 新的API是一個靜態方法,返回一個物件來更新state,如果返回null則不更新任何內容, 感謝@我可以 指正
    • render
    • componentDidMount
  • 更新
    • componentWillReceiveProps static getDerivedStateFromProps
    • shouldComponentUpdate
    • componentWillUpate
    • render
    • getSnapshotBeforeUpdate —— 在最近一次渲染輸出(提交到 DOM 節點)之前呼叫,它使得元件能在發生更改之前從 DOM 中捕獲一些資訊(例如,滾動位置)。此生命週期的任何返回值將作為引數傳遞給 componentDidUpdate()。
    • componentDidUpdate
  • 解除安裝
    • componentWillUnmount

vue

Vue的生命週期先附上官方文件。

Vue的生命週期也分成3個階段進行對比,vue的生命週期基本通過命名就可以瞭解大概的意思了,我著重說一下每個階段 Vue 都完成了什麼工作。

  • 建立
    • beforeCreate —— 混沌初開,完成例項初始化
    • created —— 例項建立完畢,完成 data 屬性的初始化,能夠進行訪問,但未掛載至DOM
    • beforeMount —— 編譯template,但是並未繫結data至檢視
    • mounted —— 完成data繫結至檢視,並完成掛載DOM操作
  • 更新
    • beforeUpdate —— 在DOM更新之前,可以訪問現有DOM
    • updated —— DOM更新完畢
  • 解除安裝
    • beforeDestory —— 鉤子函式在例項銷燬之前呼叫。在這一步,例項仍然完全可用,清理定時器等防止記憶體溢位的操作在此完成,
    • destroyed —— 鉤子函式在Vue 例項銷燬後呼叫。呼叫後,Vue 例項指示的所有東西都會解繫結,所有的事件監聽器會被移除,所有的子例項也會被銷燬。

元件通訊——父子元件

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 是引用型別,會導致其他例項均受到影響。

computed 與 methods 的區別

computed 方法會有快取值, methods 不會存在快取值。

vue 如何實現響應式的

vue的響應式, 可以分為依賴收集與響應兩部分, 簡單來說依賴收集部分告訴當前存在哪一些地方依賴了這個屬性, 響應部分通過 Object.defineProperty() 方法, 獲取 set 與 get 鉤子函式, 通過鉤子函式中進行操作,實現響應式。

總結

本身框架就是工具,框架??不代表專案??嗷。

ps: 大佬也可以賜教一些常考考點,做後續補充

相關文章