2021最新Vue 面試題

Vue面試題

  1. v-html 會有XSS風(fēng)險,會覆蓋子組件

  2. computed 有緩存蚕断,data不變則不會重新計算

  3. watch 默認(rèn)不會深度監(jiān)聽欢伏,要deep:true開啟

  4. watch 監(jiān)聽引用類型入挣,拿不到oldVal,因?yàn)橹羔樝嗤跖。藭r已經(jīng)指向了新的val

  5. style指令需要駝峰式命名方式寫径筏,例如{fontSize: '10px'}

  6. v-if v-else 可使用變量葛假,也可使用===表達(dá)式

  7. v-if 和 v-show 的區(qū)別

    v-if false不渲染,適合更新不頻繁的滋恬,節(jié)省性能

    v-show false也渲染

  8. v-for 和 v-if 不能一起使用聊训,v-for 比 v-if 優(yōu)先級高,影響性能

  9. 事件的event是原生的event恢氯,沒有裝飾過带斑,事件是掛載到當(dāng)前元素

  10. v-for 的 key 因?yàn)?VDOM 的 diff 算法,通過判斷新vnode和舊vnode的key是否相等勋拟,從而復(fù)用與新節(jié)點(diǎn)對應(yīng)的老節(jié)點(diǎn)勋磕,節(jié)約性能開銷

  11. 用index做key在diff算法中不起作用,用index拼接其他值會導(dǎo)致節(jié)點(diǎn)不能復(fù)用敢靡,所以用唯一值做key挂滓,比如數(shù)據(jù)id

  12. props 和 $emit

    props父組件通過子組件屬性給子組件傳值

    $emit子組件綁定父組件方法,在子組件內(nèi)使用$emit觸發(fā)父組件的方法

  13. Vue組件如何通訊

    父子組件事件props $emit

    自定義事件 $emit $on

    通過vuex

  14. 組件間通訊-自定義事件(常用兄弟組件通訊)

    Vue自有實(shí)現(xiàn)啸胧,使用EventBus方式(bus總線機(jī)制/發(fā)布訂閱者模式/觀察者模式)

    import Vue from 'vue'
    var event = new Vue()
    export default event
    

    在A組件內(nèi)使用

    event.$emit('onHandle', params)
    

    在B組件內(nèi)的mounted中綁定自定義事件

    event.$on('onHandle', this.handle)
    

    在B組局內(nèi)beforeDestroy中及時銷毀監(jiān)聽事件赶站,否則可能造成內(nèi)存泄露

    event.$off('onHandle', this.handle)
    
  15. 組件生命周期 <font color="red">* 必須背會</font>

    掛載

    beforeCreate->create->beforeMount->mounted
    

    beforeCreate里沒有this,實(shí)例還未初始化纺念,在數(shù)據(jù)觀測(data observer)和event/watcher事件配置前

    create 初始化示例贝椿,沒有渲染,取不到dom陷谱,沒有$el团秽,通常初始化某些屬性值

    beforeMount 掛載開始之前,相關(guān)渲染首次被調(diào)用

    mounted 是渲染完了叭首,通常是初始化頁面完成后习勤,再對html的dom節(jié)點(diǎn)進(jìn)行一些需要的操作

    先父組件create->子組件create->子組件mounted->父組件mounted


    更新

    beforeUpdate->updated
    

    beforeUpdate 重新渲染和打補(bǔ)丁之前,在這里更改狀態(tài)不會觸發(fā)重新渲染

    updated 由于數(shù)據(jù)更改導(dǎo)致的重新渲染和打補(bǔ)丁觸發(fā)

    先父組件beforeUpdate-->子組件beforeUpdate->updated->父組件->updated


    銷毀

    beforeDestroy->Destroyed
    

    beforeDestroy 實(shí)例銷毀之前焙格,里面可以用this

    Destroyed 實(shí)例銷毀之后图毕,所以東西解綁,移除所以監(jiān)聽眷唉,銷毀所以子實(shí)例予颤,在服務(wù)端渲染不會被調(diào)用

    先父組件beforeDestroy-->子組件beforeDestroy->Destroyed->父組件->Destroyed

  16. 高級特性

    • <font color="red">可以不深入,但必須知道</font>
    • <font color="red">熟練基本用法冬阳,了解使用場景</font>
    • <font color="red">最好能和自己的項(xiàng)目經(jīng)驗(yàn)結(jié)合</font>
    1. 自定義v-model

      v-model會默認(rèn)利用名為value的prop和名為input的事件蛤虐,model會避免單選,復(fù)選將value特性用于不同目的的沖突

      v-model等于

      <input type="text" 
            :value="val" 
            @input="val=$event.target.value">
      

      demo:

      //父組件
      <CustomVModel v-model="name"/>
      <script>
      import CustomVModel from './CustomVModel'
      export default {
          components: {
              CustomVModel
          },
          data() {
              return {
                  name: ''
              }
          }
      }
      </script>
      // 子組件內(nèi)
      <template>
         <!--
         1. input使用了 :value 而不是 v-model
         2. change 和 model.even 要對應(yīng)
         3. text 屬性要對應(yīng) model.prop 和 props.text
         -->
         <input type="text" 
                 :value="text" 
                 @input="$emit('change', $event.target.value)"
          />
      </template>
      <script>
      export default {
          // 改變默認(rèn)v-model的綁定屬性和拋出事件
          model: {
              prop: 'text' // 對應(yīng)props text,
              event: 'change'
          },
          props: {
              text: String,
              default() {
                  return ''
              }
          }
      }
      </script>
      
    2. $nextTick肝陪、$refs

      $nextTick

      Vue是異步渲染驳庭,$nextTick會在DOM渲染之后被觸發(fā)

      頁面渲染會將 data 的修改做整合,多次 data 修改只會渲染一次


      $refs 在節(jié)點(diǎn)內(nèi)寫ref="dom" 使用this.$refs.dom拿到節(jié)點(diǎn)的dom元素

    3. slot

      基本使用

      父組件在子組件內(nèi)插入節(jié)點(diǎn)內(nèi)容

      // 父組件
      <SlotDemo>
         {{user.name}}
      </SlotDemo>
      // 子組件 SlotDemo
      <div>
          <slot>默認(rèn)顯示</slot>
      </div>
      

      作用域插槽

      父組件在子組件內(nèi)插入節(jié)點(diǎn)內(nèi)容,使用子組件的數(shù)據(jù)

      // 父組件
      <ScopedSlotDemo>
         <template v-slot="slotProps">
             {{slotProps.slotData.name}}
          </template>
      </ScopedSlotDemo>
      // 子組件 ScopedSlotDemo
      <div>
          <slot :slotData="user"></slot>
      </div>
      

      具名插槽

      用于定義多個插槽

      // 父組件
      <NameSlot>
          <template v-slot:header>
             <h1>插入 header slot中</h1>
          </template>
         <p>插入 main slot中饲常,即未命名的 slot</p>
         <template v-slot:footer>
             <p>插入 footer slot中</p>
          </template>
      </NameSlot>
      // 子組件 NameSlot
      <div class="container">
        <header>
          <slot name="header"></slot>
        </header>
        <main>
          <slot></slot>
        </main>
        <footer>
          <slot name="footer"></slot>
        </footer>
      </div>
      
    4. 動態(tài)蹲堂、異步組件

      動態(tài)組件

      用法 :is='component-name'

      需要根據(jù)數(shù)據(jù),動態(tài)渲染的場景贝淤,即組局類型不確定柒竞,例如 信息流

      <div v-for="item in components" v-key="id">
         <component :is="item.name" />    
      </div>
      
      <script>
      import TextInfoComponent from './TextInfoComponent'
      import ImageInfoComponent from './TextInfoComponent'
      export default {
          components: {
              TextInfoComponent,
              ImageInfoComponent
          },
          data() {
              return {
                 components: [{
                     id: 1,
                     name: 'TextInfoComponent',
                 },{
                     id: 2,
                     name: 'ImageInfoComponent',
                 }]
              }
          }
      }
      </script>
      

      異步組件

      import() 函數(shù)

      按需加載, 異步加載大組件

      export default {
          conponents: {
              component: () => import('./component')
          }
      }
      
    5. keep-alive

      緩存組件播聪,頻繁切換朽基,不需要重復(fù)渲染 例如 tab切換

      <keep-alive>
       <KeepAliveStage></KeepAliveStage>
      </keep-alive>
      <script>
      import KeepAliveStage from './KeepAliveStage'
      export default {
          conponents: {
              KeepAliveStage
          }
      }
      </script>
      
    6. mixin

      多組件有相同的邏輯,抽離出來离陶,和主組件混合合并代碼

      會出現(xiàn)問題

      • 變量來源不明確踩晶,不利于閱讀
      • 多mixin會造成命名沖突
      • mixin和組件可能出現(xiàn)多對多的關(guān)系,復(fù)雜度較高

      Vue 3 提出的Composition API 旨在解決這些問題

      // 定義 ./myMixin.js
      export default {
          data() {
              return {}
          },
          mounted() {},
          methots: {}
      }
      
      // 使用
      import myMixin from './myMixin'
      export default {
          mixins: [myMixin] // 可以多個枕磁,自動合并
      }
      
  17. Vuex 使用

    可能會考察 state 的數(shù)據(jù)結(jié)構(gòu)設(shè)計

    vuex.png
+ 基本概念

1. state // 單一狀態(tài)樹
2. getters // 獲取屬性茂翔,計算屬性啥的
3. actions // 類似控制器蝙场,commit 多個 mutations,這里可以異步操作,其他的不行
4. mutations // 更改狀態(tài)埃跷,必須是同步函數(shù)
5. module // 模塊化Store
6. plugins //插件五芝,相當(dāng)mutation的攔截器谐丢,提供store.subscribe((mutation, state) => {})

--------------

+ Vue組件內(nèi)

1. dispatch // 用來觸發(fā) actions
2. commit // 用來觸發(fā) mutations
3. mapState // 映射 state 的函數(shù)揭蜒,computed 中 ...mapState()
4. mapGetters  // 映射 getters 的函數(shù),computed 中 ...mapState()
5. mapActions // 映射 actions 的函數(shù)传藏,methods 中 ...mapActions()
6. mapMutations // 映射 mutations 的函數(shù)腻暮,methods 中 ...mapMutations()
  1. Vue-router 使用

    路由模式(hash,H5 history)毯侦,后者需要server支持

    mode:‘history’

    路由配置(動態(tài)路由哭靖,懶加載)

    :id那種,在$route.params.id取到

  2. Vue 原理

    • 如何理解MVVM

      mvvm.png

      Model-View-ViewModel 數(shù)據(jù)模型-視圖-視圖數(shù)據(jù)

      數(shù)據(jù)驅(qū)動視圖

      View和Model沒有直接關(guān)聯(lián)侈离,ViewMode是給他們提供雙向數(shù)據(jù)綁定的聯(lián)系试幽,優(yōu)點(diǎn)是讓開發(fā)者只需關(guān)注業(yè)務(wù),不需要手動操作DOM卦碾,也不需要關(guān)注數(shù)據(jù)狀態(tài)同步的問題

    • 監(jiān)聽data變化的核心API是什么铺坞,怎么深度監(jiān)聽-遞歸

      Vue 2 是通過 Object.defineProperty 的 getter 和 setter,并結(jié)合觀察者模式實(shí)現(xiàn)數(shù)據(jù)綁定的

      能監(jiān)聽屬性的get set方法

      缺點(diǎn)

      用于深度監(jiān)聽要遞歸到底,一次性計算量大

      無法監(jiān)聽新增屬性/刪除屬性

      無法原生監(jiān)聽數(shù)組洲胖,需要特殊處理

      Vue 3 是通過 es6的 proxy

      優(yōu)點(diǎn)是之前操作的是對象的屬性济榨,現(xiàn)在是操作對象,對js引擎比較友好

      缺點(diǎn)是兼容不好绿映,不能用polyfill擒滑,不支持低版本瀏覽器

      監(jiān)聽數(shù)組-重新定義數(shù)組原型鏈

      const oldArrayProperty = Array.prototype
      // 創(chuàng)建新對象,原型指向oldArrayProperty,在擴(kuò)展新的方法不會影響原型
      const arrProto = Object.create(oldArrayProperty)
      ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {
          arrProto[methodName] = function() {
              updateView() // 更新視圖
              oldArrayProperty[methodName].call(this, ...arguments)
          }
      })
      
    • 虛擬DOM

      vdom (Virtual DOM) 是實(shí)現(xiàn)vue的重要基石

      用JS模擬DOM結(jié)構(gòu),計算出最小的變更橘忱,操作DOM

      數(shù)據(jù)驅(qū)動視圖,控制DOM操作

    • diff算法

      diff算法是vdom中的核心卸奉,最關(guān)鍵的部分

      vue2 參考snabbdom钝诚,雙端比較

      diff01.png

      核心思路

      patch新舊vnode的children

      新的沒有不管舊的有沒有,就移除children

      新舊都有榄棵,就去對比新舊vnode的children

      新有舊沒有凝颇,就添加children

      對比新舊vnode的children,先用四個指針指向新舊nodeChildren的頭尾

      然后循環(huán)指針到中間疹鳄,循環(huán)內(nèi)進(jìn)行對比key和sel是否相等

      1. 舊children的開始 和 新children的開始 對比
      2. 舊children的結(jié)束 和 新children的結(jié)束 對比
      3. 舊children的開始 和 新children的結(jié)束 對比
      4. 舊children的結(jié)束 和 新children的開始 對比
      5. 以上有相同的拧略,就執(zhí)行處理新舊節(jié)點(diǎn)的children,并對應(yīng)移動指針
      6. 以上都沒找到相同的瘪弓,則去用新的key看看舊的里面有沒有垫蛆,如果沒有則插入,然后移動指針腺怯,如果有再判斷sel是否相同袱饭,不相同就插入,然后移動指針呛占,相同就執(zhí)行處理新舊節(jié)點(diǎn)的children虑乖,去掉舊節(jié)點(diǎn),插入新節(jié)點(diǎn)晾虑,然后移動指針
      // children 和 text 是不會共存的疹味,要么是節(jié)點(diǎn)要么是文本
      // elm 對應(yīng)的dom元素
      // 所有元素都可以有key
      Vnode = {sel, data, children, text, elm, key}
      
      //先創(chuàng)建Vnode
      h() => Vnode
      
      patch(oldVnode, newVnode) => {
          if 第一個參數(shù)不是Vnode
              創(chuàng)建一個空的Vnode,關(guān)聯(lián)到這個elm元素
          
          if 判斷Vnode是否相同,則去對比(兩個Vnode的key 和 sel 都相等)
              Vnode對比: patchVnode()
          else 不同的Vnode直接刪掉重建 
      }
      
      patchVnode(oldVnode, newVnode) => {
          執(zhí)行 prepatch hook
          設(shè)置 vnode.elm帜篇,把新的 elm 賦值成舊的 elm, 讓新的知道更新到了哪個 elm
          得到 oldChildren 和 newChildren
          if 判斷newVnode 有沒有 children糙捺, newVnode.text == undefined (vnode.children 一般有值) 
              if 新舊都有 children
                  更新children: updateChildren()
              else if 新 children 有,舊 children 無 (舊 text 有)
                  if 如果就的 text 有值笙隙,則清空 text
                  添加 children
              else if 新 children 無继找,舊 children 有
                  移除 children
              else 舊 text 有
                  清空 text
              清空 text
          else vnode.children 沒有值,則刪除舊的 children 并設(shè)置清空 text
      }
      
      // 核心方法
      updateChildren(elm, oldChildren, newChildren) => {
          // 用于循環(huán)從四周到中間
          定義指針 oldStartIndex, oldEndIndex, newStartIndex, oldStartIndex
          
          while(指針到中間停止) {
              if 判斷元素是否是空逃沿,操作指針移動
              else if oldStart == newStart 開始和開始婴渡,判斷是否相同(key 和 sel 都相等)
                  patchVnode(), 操作指針移動
              else if oldEnd == newEnd 結(jié)束和結(jié)束,判斷是否相同(key 和 sel 都相等)
                  patchVnode(), 操作指針移動
              else if oldStart == newEnd 開始和結(jié)束凯亮,判斷是否相同(key 和 sel 都相等)
                  patchVnode(), 操作指針移動
              else if oldEnd == newStart 結(jié)束和開始边臼,判斷是否相同(key 和 sel 都相等)
                  patchVnode(), 操作指針移動
              else 以上四個都未命中
                  // 用新節(jié)點(diǎn) key,判斷能否對應(yīng) oldChildren 中某個節(jié)點(diǎn)的 key
                  在oldChildren中假消,用新節(jié)點(diǎn)的key去拿節(jié)點(diǎn)
                  if 沒拿到?jīng)]對應(yīng)上柠并,則
                      插入新節(jié)點(diǎn), 操作指針移動
                  else 對應(yīng)上
                      if sel 是否相等
                          插入新節(jié)點(diǎn), 操作指針移動
                      else key 和 sel 都相等
                          patchVnode(),去掉舊節(jié)點(diǎn),插入新節(jié)點(diǎn), 操作指針移動
          }
      }
      

      vue3 參考inferno臼予,最長遞增子序列

      兩個理念鸣戴。第一個是相同的前置與后置元素的預(yù)處理;第二個則是最長遞增子序列

      1. 從頭對比找到相同的節(jié)點(diǎn)patch,發(fā)現(xiàn)不同則跳出

      2. 如果1沒有patch完粘拾,則從后往前找相同的節(jié)點(diǎn)patch窄锅,發(fā)現(xiàn)不同則跳出

      3. 如果新節(jié)點(diǎn)大于與舊節(jié)點(diǎn),對剩余的都創(chuàng)建新的vnode

      4. 如果舊節(jié)點(diǎn)大于新節(jié)點(diǎn)缰雇,對于超出的舊節(jié)點(diǎn)全部卸載

      5. 如果3入偷,4都沒有,則是對于不確定的元素(沒有patch到相同的vnode)

        1. 把沒有比較過的新vnode保存在map里

        2. 記錄已經(jīng)patch節(jié)點(diǎn)的熟練patched械哟,沒有經(jīng)過patch的新節(jié)點(diǎn)數(shù)量tuBePatched

        3. 建立一個數(shù)組newIndexToOldIndexMap疏之,每個元素都記錄舊節(jié)點(diǎn)的索引,這個數(shù)組的索引就是新節(jié)點(diǎn)的索引

        4. 遍歷舊節(jié)點(diǎn)

          1. 如果toBePatched為0暇咆,那么統(tǒng)一卸載舊節(jié)點(diǎn)
          2. 如果舊節(jié)點(diǎn)key存在锋爪,通過key找到對應(yīng)新節(jié)點(diǎn)的index
          3. 如果舊節(jié)點(diǎn)key不存在,遍歷剩下的所有新節(jié)點(diǎn)爸业,試圖找到新節(jié)點(diǎn)對應(yīng)的index
          4. 如果沒有找到對應(yīng)的新節(jié)點(diǎn)就卸載舊節(jié)點(diǎn)
          5. 如果找到對應(yīng)的新節(jié)點(diǎn)几缭,把舊節(jié)點(diǎn)的索引記錄在新節(jié)點(diǎn)的數(shù)組中,如果節(jié)點(diǎn)發(fā)生移動就記錄已經(jīng)移動了沃呢,最后patch新節(jié)點(diǎn)
        5. 如果發(fā)生移動年栓,根據(jù)newIndexToOldIndexMap找到最長穩(wěn)定序列,

        6. 如果證明不存在舊節(jié)點(diǎn)就創(chuàng)建新節(jié)點(diǎn)薄霜,對于發(fā)生移動的節(jié)點(diǎn)進(jìn)行移動處理

  3. 模版編譯

    模版編譯為 render 函數(shù)某抓,執(zhí)行 render 函數(shù)返回 vnode

    基于 vnode 再執(zhí)行 patch 和 diff

    使用webpack vue-loader

    • JS的 with 語法

      改變 {} 內(nèi)自由變量的查找規(guī)則,當(dāng)做 obj 屬性來查找

      如果找不到匹配的 obj 屬性惰瓜,就會報錯

      with 要慎用否副,它打破了作用域規(guī)則,易讀性變差

      // with 能改變 {} 內(nèi)自由變量的查找方式崎坊,將 {} 內(nèi)自由變量备禀,當(dāng)做 obj 的屬性來查找
      const obj = {a:100, b:200}
      console.log(obj.a)
      console.log(obj.b)
      console.log(obj.c) // undefined
      with(obj) {
          console.log(a)
          console.log(b)
          console.log(c) // 會報錯
      }
      
  4. 組件 渲染/更新 過程

data.png
> 初次渲染的過程
>
> > 解析模版為 render 函數(shù)
> >
> > 觸發(fā)響應(yīng)式,監(jiān)聽 data 屬性的 getter setter
> >
> > 執(zhí)行 render 函數(shù)奈揍,生成 vnode, 執(zhí)行 patch(elm, vnode)
>
> 更新過程
>
> > 修改 data曲尸,觸發(fā) setter
> >
> > 重新執(zhí)行 render 函數(shù),生成 newVnode
> >
> > 執(zhí)行 patch(vnode, newVnode)
>
> 異步渲染 $nextTick
>
> > 匯總 data 的修改男翰,一次性更新視圖
> >
> > 減少 DOM 操作次數(shù)另患,提升性能
  1. 路由原理

    稍微復(fù)制的SPA,都需要路由

    hash-window.onhashchange

    H5 history-history.pushState 和 window.onpopstate

    H5 history 需要后端支持

    兩者選擇

    toB 推薦hash蛾绎,簡單易用昆箕,對 url 規(guī)范不敏感

    toC 可以考慮選擇H5 history鸦列,但需要服務(wù)端支持

    能選擇簡單的就別用復(fù)雜的,要考慮成本和收益

    hash 特點(diǎn)

    hash 變化會觸發(fā)網(wǎng)頁跳轉(zhuǎn)鹏倘,即瀏覽器的前期薯嗤、后退

    hash 變化不會刷新頁面,SPA必需的特點(diǎn)

    hash 永遠(yuǎn)不會提交到server端(前端自生自滅)

    H5 history

    用 url 規(guī)范的路由纤泵,但跳轉(zhuǎn)時不刷新頁面

    history.pushState

    window.onpopstate

  2. 面試題

    v-show 和 v-if 的區(qū)別

    v-show 通過 css display 控制顯示和隱藏

    v-if 是組件真正的渲染和銷毀骆姐,而不是顯示和隱藏

    頻繁切換顯示狀態(tài)用 v-show,否則用 v-if

    為什么 v-for 中用 key

    必須用 key夕吻,而且不能是 index 和 random

    diff 算法中通過 tag 和 key 來判斷诲锹,是否是 sameNode

    減少渲染次數(shù)繁仁,提升渲染性能

    描述 vue 組件的生命周期

    單組件生命周期圖

    父子組件生命周期關(guān)系比如 mount 和 update

    Vue 組件如何通訊

    父子組件 props 和 this.$emit

    自定義事件 event.on event.off event.$emit

    vuex

    描述組件渲染和更新的過程

    渲染圖

    雙向數(shù)據(jù)綁定 v-model 的實(shí)現(xiàn)原理

    input 元素的 value = this.name

    綁定 input 事件 this.name = $event.target.value

    data 更新觸發(fā) re-render

    對 MVVM 的理解

    computed 有何特點(diǎn)

    緩存涉馅,data 不變不會重新計算

    提高性能

    為何組件 data 必須是一個函數(shù)

    js 特性導(dǎo)致的,Object 是引用數(shù)據(jù)類型黄虱,會導(dǎo)致同一個屬性改一個都變了稚矿,是函數(shù)的時候才能實(shí)例獨(dú)立不相互影響

    ajax 應(yīng)該放在哪個生命周期

    mounted

    js 是單線程,ajax 是異步獲取數(shù)據(jù)

    放在 mounted 之前沒有用捻浦,只會讓邏輯更加混亂晤揣,除非有特殊需求

    如何將組件所有的 props 傳遞給子組件

    $props

    <Uer v-bind="$props" />

    如何自己實(shí)現(xiàn) v-model

    多個組件有相同的邏輯,如何抽離

    mixin

    mixin 的缺點(diǎn)

    何時要使用異步組件

    加載大組件

    路由異步加載

    何時需要使用 keep-alive

    緩存組件朱灿,不需要重復(fù)渲染

    多個靜態(tài) tab 頁的切換

    優(yōu)化性能

    何時需要使用beforeDestory

    解綁自定義事件 event.$off

    清楚定時器

    解綁自定義的 DOM 事件昧识,如 window scroll 等

    什么是作用域插槽

    把子組件的數(shù)據(jù)傳給父組件顯示

    vuex 中 action 和 mutation 有何區(qū)別

    action 中處理異步,mutation 不可以

    mutation 做原子操作

    action 可以整合多個 mutation

    vue-router 常用的路由模式

    hash 默認(rèn)

    H5 history

    vue-router 兩種模式是怎么實(shí)現(xiàn)的

    hash window.onhashchange

    H5 history window.history.pushState window.history.onpopstate

    vue-router 兩種模式的區(qū)別

    hash有#號盗扒,能控制瀏覽器前后跳轉(zhuǎn)跪楞,不會提交到server端

    H5 history 是規(guī)范 url,需要 server 端配合

    如何配置 vue-router 異步加載

    通過 () => import()

    用 vnode 描述一個 DOM 結(jié)構(gòu)

    監(jiān)聽 data 變化的核心 API 是什么

    Object.defineProperty

    有何缺點(diǎn)

    深度監(jiān)聽需要遞歸侣灶、監(jiān)聽數(shù)組需要特殊處理甸祭,無法監(jiān)聽新增和刪除的屬性,使用vue.set vue.delete

    Vue3 Proxy 兼容問題褥影,而且不能 polyfill

    Vue 如何監(jiān)聽數(shù)組變化

    Object.defineProperty 不能監(jiān)聽數(shù)組變化

    重新定義原型池户,重新push pop等方法,實(shí)現(xiàn)監(jiān)聽

    Proxy 可以原生支持監(jiān)聽數(shù)組變化

    描述響應(yīng)式原理

    監(jiān)聽 data 變化

    組件渲染和更新的流程

    diff 算法的時間復(fù)雜度

    O(n) 凡怎,在O(n^3)基礎(chǔ)上做的調(diào)整校焦,只比較同一層級,比較tag不相同直接銷毀重建统倒,通過tag和key判斷是不是同一組件斟湃,是就不重復(fù)對比

    簡述 diff 算法過程

    patch(elem, vnode) 和 patch(vnode, newVnode)

    patchVnode 和 addVnodes 和 removeVnodes

    updateChildren,通過key判斷是不是同一節(jié)點(diǎn)

    vue為何是異步渲染檐薯,$nextTick 何用

    異步渲染凝赛,合并 data 修改注暗,提高性能

    $nextTick 在 DOM 更新之后,觸發(fā)回調(diào)

    vue 常見性能優(yōu)化

    合理使用 v-show v-if

    合理使用 computed

    v-for 時加 key墓猎,以及避免和 v-if 同時使用

    自定義事件捆昏,DOM事件及時銷毀

    合理使用異步組件

    合理使用 keep-alive

    data 層級不要太深

    使用 vue-loader 在開發(fā)環(huán)境做模版編譯(預(yù)編譯)

    webpack 層面的優(yōu)化

    前端通用的性能優(yōu)化,如圖片懶加載

    使用ssr

  3. Vue 3

    Vue3 比 Vue2 有什么優(yōu)勢

    性能更好

    體積更小

    更好的 ts 支持

    更好的代碼組織

    更好的邏輯抽離

    更多新功能

    Vue3 聲明周期

    Options API: beforeDestory 改為 beforeUnmount destoryed 改為 unmouted

    升級內(nèi)容

    全部用 ts 重寫

    性能提升毙沾,代碼量減少

    調(diào)整部分API

  4. 持續(xù)更新中...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末骗卜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子左胞,更是在濱河造成了極大的恐慌寇仓,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烤宙,死亡現(xiàn)場離奇詭異遍烦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)躺枕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門服猪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拐云,你說我怎么就攤上這事罢猪。” “怎么了叉瘩?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵膳帕,是天一觀的道長。 經(jīng)常有香客問我薇缅,道長危彩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任捅暴,我火速辦了婚禮恬砂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蓬痒。我一直安慰自己泻骤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布梧奢。 她就那樣靜靜地躺著狱掂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪亲轨。 梳的紋絲不亂的頭發(fā)上趋惨,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天,我揣著相機(jī)與錄音惦蚊,去河邊找鬼器虾。 笑死讯嫂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的兆沙。 我是一名探鬼主播欧芽,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼葛圃!你這毒婦竟也來了千扔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤库正,失蹤者是張志新(化名)和其女友劉穎曲楚,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體褥符,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡龙誊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了属瓣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片载迄。...
    茶點(diǎn)故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡讯柔,死狀恐怖抡蛙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情魂迄,我是刑警寧澤粗截,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站捣炬,受9級特大地震影響熊昌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜湿酸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一婿屹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧推溃,春花似錦昂利、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至硬萍,卻和暖如春扩所,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背朴乖。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工祖屏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留助赞,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓袁勺,卻偏偏與公主長得像嫉拐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子魁兼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容