欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue實(shí)現(xiàn)骨架屏的示例

 更新時(shí)間:2021年04月25日 09:06:09   作者:我在曾經(jīng)眺望彼岸  
這篇文章主要介紹了vue實(shí)現(xiàn)骨架屏的示例,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下

骨架屏用途

  • 作為spa中路由切換的 loading, 結(jié)合組件的生命周期和ajax請(qǐng)求返回的時(shí)機(jī)來使用.( 作為loading 使用)。作為與用戶聯(lián)系最為密切的前端開發(fā)者,用戶體驗(yàn)是最值得關(guān)注的問題。關(guān)于頁面loading狀態(tài)的展示,主流的主要有l(wèi)oading圖和進(jìn)度條兩種。除此之外,越來越多的APP采用了“骨架屏”的方式去展示未加載內(nèi)容,給予了用戶煥然一新的體驗(yàn)。
  • 作為首屏渲染的優(yōu)化

Vue架構(gòu)骨架屏

思路大綱

  • 定義一個(gè)抽象組件,在抽象組件的render函數(shù)里獲取插槽
  • 深度循環(huán)遍歷插槽,將每個(gè)元素都添加上gm-skeleton的類名
  • 將vnode textContent預(yù)暫后清空保證骨架屏出現(xiàn)時(shí)不會(huì)出現(xiàn)默認(rèn)文字
  • 返回slots

定義一個(gè)抽象組件

什么是抽象組件? 在渲染時(shí)會(huì)被跳過,只做運(yùn)行時(shí)的操作的組件

    export default {
      name: 'GmSkeleton',
      abstract: true // 抽象組件的屬性
    }

獲取插槽并初始化操作骨架屏

    render(h) {
      const slots = this.$slots.default || [h('')]
      this.$nextTick().then(() => {
        this.handlerPrefix(slots, this.showSpin ? this.addSkeletPrefix : this.removeSkeletPrefix)
      })

      return slots.length > 1 ? h('div', {
         staticClass: this.showSpin ? 'g-spinner' : ''
      }, slots) : slots
    }

這里我們將處理slots的方法放置在nextTick里面, 因?yàn)閔andlerPrefix里需要獲取真實(shí)的DOM,nextTick是用來執(zhí)行排序后的更新隊(duì)列里的所有方法, 在執(zhí)行render前, GMSkeleton組件的renderWatcher已被收集到更新隊(duì)列里,所以此時(shí)定義nextTick CallBack函數(shù)里能獲取到渲染后對(duì)應(yīng)插槽里所有真實(shí)DOM,若是不了解nextTick原理,請(qǐng)移步你不知道的nextTick

循環(huán)slots操作類名

    handlerComponent(slot, handler/* addSkeletPrefix | removeSkeletPrefix */, init) {
      const originchildren = (((slot.componentInstance || {})._vnode || {}).componentOptions || {}).children
      const compchildren = ((slot.componentInstance || {})._vnode || {}).children
      !init && handler(slot)
      if (compchildren) this.handlerPrefix(compchildren, handler, false)
      if (originchildren) this.handlerPrefix(originchildren, handler, false)
    },
    handlerPrefix(slots, handler, init = true) {
      slots.forEach(slot => {
        var children = slot.children || (slot.componentOptions || {}).children || ((slot.componentInstance || {})._vnode || {}).children
        if (slot.data) {
          if (!slot.componentOptions) {
            !init && handler(slot)
          } else if (!this.$hoc_utils.getAbstractComponent(slot)) {
            ;(function(slot) {
              const handlerComponent = this.handlerComponent.bind(this, slot, handler, init)
              const insert = (slot.data.hook || {}).insert
              ;(slot.data.hook || {}).insert = () => { // 函數(shù)重構(gòu), 修改原有的組件hook, 并且保證insert只執(zhí)行一次
                insert(slot)
                handlerComponent()
              }
              ;(slot.data.hook || {}).postpatch = handlerComponent
            }).call(this, slot)
          }
        }
        if (slot && slot.elm && slot.elm.nodeType === 3) {
          if (this.showSpin) {
            slot.memorizedtextContent = slot.elm.textContent
            slot.elm.textContent = ''
          } else {
            slot.elm.textContent = slot.memorizedtextContent || slot.elm.textContent || slot.text
          }
        }
        children && this.handlerPrefix(children, handler, false)
      })
    },

逐步分析:

  1. 我們遍歷slots插槽
  2. 獲取當(dāng)前vnode下的children集合以備做下一次循環(huán)
  3. 判斷是否是原生HTML元素,只有組件vnode才會(huì)具備componentOptions屬性
  4. 判斷是否抽象組件,我們知道抽象組件是不會(huì)渲染到真實(shí)DOMTree上的,例如keep-alive、transition,每個(gè)組件的vnode擁有獨(dú)有的hooks生命周期: init(初始化)、insert(插入)、prepatch(更新)、destroy(銷毀),每個(gè)生命周期會(huì)在不同階段觸發(fā), 劫持insert,保留原有的insert方法,隨后重構(gòu)vnode的insert方法在里面調(diào)用handlerComponent方法進(jìn)行添加類名,這里與上面的mounted的nextTick用法理念類似,由于handlerComponent需要知道子組件的實(shí)例,所以必須在實(shí)例化后去調(diào)用,而組件的init方法會(huì)實(shí)例組件并且直接調(diào)用watcher.update(watcher.render()), 也就是我們?cè)谡{(diào)用insert方法的時(shí)候其實(shí)是在update(render())后,所以這里能夠獲取到實(shí)例化后子組件
  5. 判斷nodeType是否是文本節(jié)點(diǎn),若是的話需要先將textContent保存后進(jìn)行刪除,保證在骨架屏出現(xiàn)時(shí)不會(huì)顯示默認(rèn)文字,在骨架屏消失時(shí),將原先保留的默認(rèn)文字返回給vnode,這樣就能自由在骨架屏的顯示隱藏期間自由切換

操作vnode的靜態(tài)類名

    addSkeletPrefix(slot) {
      const rootVnode = slot.componentOptions ? (slot.componentInstance || {})._vnode || {} : slot;
      if (rootVnode.elm) {
        rootVnode.elm.classList.add(this.skeletPrefix)
      } else {
        ;(rootVnode.data || {}).staticClass += ` ${this.skeletPrefix}`
      }
    },
    removeSkeletPrefix(slot) {
      const rootVnode = slot.componentOptions ? (slot.componentInstance || {})._vnode || {} : slot;
      if (rootVnode.elm) {
        rootVnode.elm.classList && rootVnode.elm.classList.remove(this.skeletPrefix)
      } else if (rootVnode.data.staticClass) {
        rootVnode.data.staticClass = rootVnode.data.staticClass.replace(` ${this.skeletPrefix}`, '')
      }
    }

addSkeletePrefix用于添加gm-skeleton類名,而removeSkeletonPrefix則是用于刪除gm-skeleton類名

使用方法

  import Vue from 'vue'
  import GMSkeleton from 'path/to/GMSkeleton'
  
  Vue.use(GMSkeleton)
  <gm-skeleton>
    <Component />
    <div></div>
    <div><span>前端馬丁</span></div>
  </gm-skeleton>

傳值

屬性名 描述
showSpin Boolean 是否開啟骨架屏,默認(rèn)為true
skeletPrefix String 骨架屏類名, 默認(rèn)是gm-skeleton

效果如下

具體樣式是根據(jù)開發(fā)者自己寫的樣式來生成的,通過gm-skeleton包裹,如上的使用方法,以下是一個(gè)簡(jiǎn)單的例子

完整地址

80行代碼實(shí)現(xiàn)Vue骨架屏

以上就是vue實(shí)現(xiàn)骨架屏的示例的詳細(xì)內(nèi)容,更多關(guān)于vue實(shí)現(xiàn)骨架屏的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue計(jì)算屬性的使用

    Vue計(jì)算屬性的使用

    本篇文章主要介紹了Vue計(jì)算屬性的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • 從vue源碼看props的用法

    從vue源碼看props的用法

    平時(shí)寫vue的時(shí)候知道 props 有很多種用法,今天我們來看看vue內(nèi)部是怎么處理 props 中那么多的用法的。非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2019-01-01
  • vite多頁面配置項(xiàng)目實(shí)戰(zhàn)

    vite多頁面配置項(xiàng)目實(shí)戰(zhàn)

    vite官方文檔中有關(guān)于多頁面應(yīng)用模式如果配置的說明,下面這篇文章主要給大家介紹了關(guān)于vite多頁面配置的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • vue element 關(guān)閉當(dāng)前tab 跳轉(zhuǎn)到上一路由操作

    vue element 關(guān)閉當(dāng)前tab 跳轉(zhuǎn)到上一路由操作

    這篇文章主要介紹了vue element 關(guān)閉當(dāng)前tab 跳轉(zhuǎn)到上一路由操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • 從0搭建vue-cli4腳手架

    從0搭建vue-cli4腳手架

    這篇文章主要介紹了從0搭建vue-cli4腳手架,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 解決前后端分離 vue+springboot 跨域 session+cookie失效問題

    解決前后端分離 vue+springboot 跨域 session+cookie失效問題

    這篇文章主要介紹了前后端分離 vue+springboot 跨域 session+cookie失效問題的解決方法,解決過程也很簡(jiǎn)單 ,需要的朋友可以參考下
    2019-05-05
  • vue使用Echarts設(shè)置數(shù)據(jù)無效問題記錄及解決方法

    vue使用Echarts設(shè)置數(shù)據(jù)無效問題記錄及解決方法

    這篇文章主要介紹了vue使用Echarts設(shè)置數(shù)據(jù)無效問題記錄,本文通過場(chǎng)景分析給大家分享解決方法,需要的朋友可以參考下
    2022-08-08
  • Vue加載中動(dòng)畫組件使用方法詳解

    Vue加載中動(dòng)畫組件使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了Vue加載中動(dòng)畫組件使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • vue前后端端口不一致的問題解決

    vue前后端端口不一致的問題解決

    本文主要介紹了vue前后端端口不一致的問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-10-10
  • Vue前端項(xiàng)目部署的三種方案詳解

    Vue前端項(xiàng)目部署的三種方案詳解

    這篇文章主要介紹了Vue前端項(xiàng)目部署的三種方案,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08

最新評(píng)論