1. 程式人生 > >vue頁面載入閃爍問題的解決方法

vue頁面載入閃爍問題的解決方法

v-if 和 v-show 的區別

v-if只會在滿足條件時才會編譯,而v-show不管是否滿足條件始終會編譯,v-show的顯示與隱藏只是簡單的切換CSS的display屬性。

也就是說,在使用v-if時,若值為false,那麼頁面將不會有這個html標籤生成。而v-show:不論其值是false還是true,html元素都會存在,只是簡單的切換css的display屬性。

使用場景

    一般來說,v-if 有更高的切換消耗而 v-show 有更高的初始渲染消耗。因此,如果需要頻繁切換 v-show 較好,如果在執行時條件不大可能改變 v-if 較好。   

另外

    1.v-if 指令可以應用於template包裝元素上,而v-show不支援template

    2.將v-show應用在元件上時,因為指令的優先順序 v-else 會出現問題,解決辦法就是用另一個 v-show 替換 v-else

1

2

3

4

5

6

// 錯誤

 <custom-component v-show="condition"></custom-component>

 <p v-else>這可能也是一個元件</p>

    // 正確做法

 <custom-component v-show="condition"></custom-component>

 <p v-show="!condition">這可能也是一個元件</p>

解決vue頁面載入時出現{{message}}閃退

方法一:v-cloak

    v-cloak指令和css規則如[v-cloak]{display:none}一起用時,這個指令可以隱藏未編譯的Mustache標籤直到例項準備完畢。
    v-cloak 指令可以像css選擇器一樣繫結一套css樣式然後這套css會一直生效到例項編譯結束。

?

1

2

3

4

5

6

7

8

eg:

  // <div> 不會顯示,直到編譯結束。

  [v-cloak]{

    display:none;

      }

  <div v-cloak>

     {{ message }}

  </div>

方法二:v-text

vue中我們會將資料包在兩個大括號中,然後放到HTML裡,但是在vue內部,所有的雙括號會被編譯成textNode的一個v-text指令。

而使用v-text的好處就是永遠更好的效能,更重要的是可以避免FOUC (Flash of Uncompiled Content) ,也就是上面與遇到的問題。

1

2

3

4

eg:

  <span v-text="message"></span>

  <!-- same as -->

  <span>{{message}}</span>

補充:

vue 頁面載入進度條元件

頁面載入進度條最初我是在youtube上看到的,後面幾乎在各大網站上都能見到它的身影,可以讓使用者在載入頁面的時候不會對著完全空白的頁面發呆,提升使用者體驗

但是從開發角度講,這種進度條在真實性上確實很難把握,因為在邏輯程式碼載入完成之前,我們都不能統計到進度,而邏輯程式碼自身的進度也無法統計。另外,我們不可能監控到所有資源的載入情況。

事實上,使用者並不是在乎你的頁面究竟載入了百分之幾,而真正關心的是離載入完還有多久,以及這個空白頁面是沒有載入完,還是載入完就是空白的。所以沒我們需要去“模擬”一個進度條,在後端資料返回前利用一個假的動畫效果模擬載入,在資料返回後讀完進度條並且隱藏。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

// progress-bar.vue

<template>

 <transition name="fade">

  <div class="progress-bar" v-if="isShow">

  </div>

 </transition>

</template>

<script type="text/babel">

 export default {

  data() {

   return {

    isShow: true, // 是否顯示進度條

    val: 0, // 進度

   }

  },

  props: {

   /**

    * 每10毫秒自增幅度

    */

   step: {

    type: Number,

    default: 5,

   },

   /**

    * 初始值

    */

   initVal: {

    type: Number,

    default: 0,

   },

   /**

    * 到一定進度停止

    */

   stopVal: {

    type: Number,

    default: 80,

   },

   /**

    * 進度條繼續到成功

    */

   isOk: {

    type: Boolean,

    default: false,

   },

  },

  mounted() {

   // 初始化後加載進度,載入到百分之多少由stopVal決定

   this.val = this.initVal

   let step = this.step

   let timer = setInterval(() => {

    this.val = this.val + step

    this.$el.style.width = this.val + '%'

    // 父元件資料載入完前進度條最多到stopVal的這個百分值

    if (this.val >= this.stopVal) {

     clearInterval(timer)

     return

    }

   }, 10)

  },

  watch: {

   /**

    * 監聽元件props變化決定是否繼續載入,一般在父元件資料載入完後改變此標誌位

    */

   isOk() {

    let val = this.val

    let step = this.step

    let timer = setInterval(() => {

     val = val + step

     this.$el.style.width = val + '%'

     // 載入到百分百完成

     if (val >= 100) {

      // 關閉定時器

      clearInterval(timer)

      // 載入完成關閉進度條

      this.isShow = false

      // 載入完成的回撥

      this.$emit('callback', 'load success')

      return

     }

    }, 10)

   },

  },

 }

</script>

<style lang="stylus" rel="stylesheet/stylus">

 .progress-bar {

  position fixed

  top 0

  height 6px

  width 0

  background-color #999

 }

 .fade {

  &-enter-active, &-leave-active {

   transition: all .3s

  }

  &-enter, &-leave-active {

   opacity: 0

  }

 }

</style>