vue音樂播放器學(xué)習(xí)筆記(4) - ( vue的生命周期 ) + ( v-if 和 v-show的區(qū)別 ) + ( better-scroll下拉刷新,上拉加載 ) + ( Vue.set() 和 vm.$set ) + ( v-pre 和 v-once ) + ( font-awesone )

(一) vue的生命周期

https://segmentfault.com/a/1190000008010666

(1) beforeCreate

  • 在實(shí)例初始化之后,數(shù)據(jù)觀測(data observer) 和 event/watcher 事件配置之前被調(diào)用。組件屬性未被初始化,即實(shí)例中的data,el為undefined
  • beforeCreate在官方文檔描述中說,在做一些數(shù)據(jù)監(jiān)視和事件初始化,這里有一個容易讓人走偏的地方,就是事件初始化,其實(shí)就是為vue對象添加一些屬性,就是methods中的一些函數(shù)全部作為vue對象的屬性存在,Vue會講所有的data數(shù)據(jù)和methods中的函數(shù)添加到創(chuàng)建的vue對象上面。

(2) created

  • 實(shí)例已經(jīng)創(chuàng)建完成之后被調(diào)用。在這一步,實(shí)例已完成以下的配置:數(shù)據(jù)觀測(data observer),屬性和方法的運(yùn)算, watch/event 事件回調(diào)。然而,掛載階段還沒開始,$el 屬性目前不可見。
  • created 這個方法表示,vue對象已經(jīng)創(chuàng)建成功,這里要搞清楚vue對象并不是我們所說的虛擬dom,vue對象就是一個js對象,他內(nèi)部只是對數(shù)據(jù)進(jìn)行操作,通過對數(shù)據(jù)的操作進(jìn)而影響到虛擬dom的構(gòu)建,所以在這個方法中我們可以做一些數(shù)據(jù)初始化工作,最常見的就是發(fā)送ajax請求來對已經(jīng)構(gòu)建完畢的vue對象的靜態(tài)屬性進(jìn)行一些初始化。

(3) beforeMount

  • beforeMount:模板編譯/掛載之前,在掛載開始之前被調(diào)用。進(jìn)行模板編譯,但是,模板內(nèi)容還未插入頁面DOM中。
  • 這個過程就是根據(jù)編譯以后產(chǎn)生的虛擬dom結(jié)構(gòu)來構(gòu)造一個真實(shí)的dom結(jié)構(gòu),再說一遍,這兩個dom有很大的區(qū)別,前者只表示數(shù)據(jù)結(jié)構(gòu),后者可以直接添加到html文檔結(jié)構(gòu)中來渲染一個效果。在這個期間,我們就可以操作真實(shí)的dom對象了,包括我們?yōu)槟骋粋€特定的dom節(jié)點(diǎn)綁定事件,標(biāo)簽屬性,內(nèi)容的操作等,例如使用select2來修飾select,但是并不推薦在這里進(jìn)行一些事件綁定或者dom操作,因?yàn)樵谶@期間,Vue還要做一件非常重要的事情就是通過Vue自己的方式來標(biāo)識每一個真實(shí)的dom節(jié)點(diǎn),我們在vue里一般都是通過$els或者$refs來操作對應(yīng)的dom元素,但是這期間正是標(biāo)注所有元素的過程,很有可能會出一些意想不到的錯誤。

(4) mounted

  • mounted:模板編譯/掛載之后,el 被新創(chuàng)建的 vm.$el 替換,并掛載到實(shí)例上去之后調(diào)用該鉤子。如果 root 實(shí)例掛載了一個文檔內(nèi)元素,當(dāng) mounted 被調(diào)用時 vm.$el 也在文檔內(nèi)。( 將生成好的的模板掛載在DOM樹上,并且,組件屬性this.$el被賦值。)
  • mounted:見名知意,掛載,表示真實(shí)dom已經(jīng)構(gòu)造完畢,我們可以append到父容器當(dāng)中來構(gòu)造頁面了,在這里我們就可以完成一些對于真實(shí)dom的操作,不論是直接訪問dom的屬性內(nèi)容或者事件的綁定,都可以在這里放心大膽的做了,一般情況下我們不需要直接操作dom,Vue也不推薦這么做,但是這里你需要知道的事如果你有這種需求,完全可以在這里完成,掛載的過程就是將生成的真實(shí)DOM對象append到掛載點(diǎn)下面,就是appendChild的過程,這個時候的虛擬dom結(jié)構(gòu)跟生成出來的real dom結(jié)構(gòu)一模一樣,我們以后要操作的就是這個虛擬dom結(jié)構(gòu),就是前面根據(jù)模版生成出來的dom數(shù)據(jù)結(jié)構(gòu)。

(5) beforeUpdate

  • beforeUpdate: 組件更新之前,
  • beforeUpdate:這個方法在整個生命周期之中也只被調(diào)用一次,在做什么呢,想一想上面所做的事情,上面是根據(jù)模版構(gòu)造出來一個真實(shí)的dom對象,到現(xiàn)在他并沒有跟我們的vue實(shí)例對象扯上關(guān)系,怎么通過我們的vue實(shí)例來影響到真實(shí)的dom對象呢,怎么把我們的數(shù)據(jù)綁定的真實(shí)dom當(dāng)中了,以后我們只需要操作數(shù)據(jù)就可以影響到dom結(jié)構(gòu)的渲染呢?在這個方法里,Vue同樣依據(jù)前面的規(guī)則根據(jù)vue實(shí)例提供的數(shù)據(jù)在模版中的位置來重新生成一個虛擬dom數(shù)據(jù)結(jié)構(gòu),沒錯,你沒看錯,我們要生成兩個虛擬dom,前一個dom只是dom結(jié)構(gòu),并沒有綁定我們vue的屬性數(shù)據(jù),這一個dom是綁定了我們vue實(shí)例數(shù)據(jù)的dom結(jié)構(gòu),在這個dom生成的過程中,vue根據(jù)自己的語法規(guī)則,對比如指令,表達(dá)式之類的東西進(jìn)行替換,生成一個新的虛擬dom結(jié)構(gòu),接下來我們要做什么,就是進(jìn)行比較兩個虛擬dom之間存在的差異。

(5) updated

  • updated: 組件更新之后,
  • update:這個方法在我們整個生命周期之內(nèi)會反復(fù)調(diào)用,你會發(fā)現(xiàn),每一次對vue對象的變更都會觸發(fā)update方法,他做了什么呢,他就是在反復(fù)的生成一個virtual dom,生成的新dom不斷跟之前的dom結(jié)構(gòu)進(jìn)行比對。

(6) activated

  • keep-alive 組件激活時調(diào)用。
  • 使用場景:比如切換時,保持input框獲得焦點(diǎn)
  • activated是激活的意思
  • 該鉤子在服務(wù)器端渲染期間不被調(diào)用。

   <input type="text" v-model="showInputNotDirective" ref="input2">

   activated() {
      this.$refs.input2.focus()
    }

(7) deactivated

  • keep-alive 組件停用時調(diào)用。
  • 該鉤子在服務(wù)器端渲染期間不被調(diào)用。

(6) beforeDestroy

  • beforeDestroy: 組件/實(shí)例銷毀前被調(diào)用,在這一步,實(shí)例仍然完全可用。( 可以做一個確認(rèn)停止事件的確認(rèn)框,銷毀組件 )

(7) destoryed

  • destoryed: 組件/實(shí)例銷毀完畢。這時,組件上的watcher,子組件和事件監(jiān)聽都會被銷毀。

實(shí)用的鉤子:


Created:vue實(shí)例被生成后的一個生命周期鉤子函數(shù)。(頁面初始化數(shù)據(jù)加載一般寫這里);

beforeCreate:給個loading界面 created撤銷loading;

beforeDestory:你確認(rèn)刪除XX嗎?

mounted : 在這發(fā)起后端請求,拿回?cái)?shù)據(jù),配合路由鉤子做一些事情

destoryed:當(dāng)前組件已被刪除,清空相關(guān)內(nèi)容

圖解

(二) v-if 和 v-show

結(jié)論:如果需要頻繁切換使用 v-show 較好,如果在運(yùn)行時條件不大可能改變則使用 v-if較好。

  • v-if的初始化較快,但切換代價高;

  • v-show初始化慢,但切換成本低。

  • v-if 是真實(shí)的條件渲染,因?yàn)樗鼤_保條件塊在切換當(dāng)中適當(dāng)?shù)劁N毀與重建條件塊內(nèi)的事件監(jiān)聽器和子組件。
    v-if 也是惰性的:如果在初始渲染時條件為假,則什么也不做——在條件第一次變?yōu)檎鏁r才開始局部編譯(編譯會被緩存起來)。

  • v-show 條件性顯示或隱藏,
    v-show 的元素會始終渲染并保持在 DOM 中。v-show 是簡單的切換元素的 CSS屬性 display
    v-show 不支持 template

(三) better-scroll實(shí)現(xiàn)下拉刷新,上拉加載

https://juejin.im/post/59b777015188257e764c716f

下拉刷新 :

pullDownRefresh 配置項(xiàng),監(jiān)聽 pullingDown 事件,刷新數(shù)據(jù)。并在刷新數(shù)據(jù)完成之后,調(diào)用 finishPullDown() 方法,回彈到頂部邊界

(1) pullDownRefresh ( 選項(xiàng) )

  • threshold: 50, // 當(dāng)下拉到超過頂部 50px 時,觸發(fā) ( pullingDown ) 事件
  • stop: 20 // 刷新數(shù)據(jù)的過程中,回彈停留在距離頂部還有 20px 的位置

類型:Boolean | Object
默認(rèn)值:false
作用:這個配置用于做下拉刷新功能,默認(rèn)為 false。
當(dāng)設(shè)置為 true 或者是一個 Object 的時候,可以開啟下拉刷新,
可以配置頂部下拉的距離(threshold) 來決定刷新時機(jī)
以及回彈停留的距離(stop)

(2) pullingDown ( 事件 )

參數(shù):無
( 觸發(fā)時機(jī) ):在一次下拉刷新的動作后,這個時機(jī)一般用來去后端請求數(shù)據(jù)。

(3) finishPullDown() ( 方法 )

參數(shù):無
返回值:無
( 作用 ):當(dāng)下拉刷新數(shù)據(jù)加載完畢后,需要調(diào)用此方法告訴 better-scroll 數(shù)據(jù)已加載。


options.pullDownRefresh = {
  threshold: 50, // 當(dāng)下拉到超過頂部 50px 時,觸發(fā) pullingDown 事件
  stop: 20 // 刷新數(shù)據(jù)的過程中,回彈停留在距離頂部還有 20px 的位置
}

this.scroll = new BScroll(this.$refs.wrapper, options)


this.scroll.on('pullingDown', () => {
  // 刷新數(shù)據(jù)的過程中,回彈停留在距離頂部還有20px的位置
  RefreshData()
    .then((newData) => {
      this.data = newData
      // 在刷新數(shù)據(jù)完成之后,調(diào)用 finishPullDown 方法,回彈到頂部
      this.scroll.finishPullDown()
  })
})

上拉加載

(1) pullUpLoad ( 選項(xiàng) )

  • threshold: -20 // 在上拉到超過底部 20px 時,觸發(fā) ( pullingUp ) 事件

類型:Boolean | Object
默認(rèn)值:false
作用:這個配置用于做上拉加載功能,默認(rèn)為 false。當(dāng)設(shè)置為 true 或者是一個 Object 的時候,可以開啟上拉加載,可以配置離底部距離閾值(threshold)來決定開始加載的時機(jī)。

(2) pullingDown ( 事件 )

參數(shù):無
( 觸發(fā)時機(jī) ):在一次上拉加載的動作后,這個時機(jī)一般用來去后端請求數(shù)據(jù)。


<template>
  <div class="rank" ref="rank">
    <div class="scrollWrapper" ref="scrollWrapper">
      <ul class="ul">
        <li v-for="item in getData" class="li">
          <div class="dataItem">
            <div class="left">
              ![](item.share_url)
            </div>
            <div class="right">{{item.abs}}</div>
          </div>
        </li>
      </ul>
    </div>
    <Loading v-if="showTime" class="Loading"></Loading>
  </div>
</template>

<script type="text/ecmascript-6">
  import BScroll from 'better-scroll'
  import Loading from 'base/loading/loading.vue'
  import png from './1.png'

  export default {
    data() {
      return {
        getData: [
          {
            share_url: png,
            abs: 'data自己的數(shù)據(jù)'
          }
        ],
        showTime: false
      }
    },
    created() {
      this._initScroll()
    },
    methods: {
      _initScroll() {
        this.$http.get('http://image.baidu.com/channel/listjson?pn=15&rn=3&tag1=%E7%BE%8E%E5%A5%B3&tag2=%E5%85%A8%E9%83%A8&ie=utf8')
          .then((response) => {
            this.getData = response.data.data.concat(this.getData)
            this.$nextTick(() => {
              if (!this.scroll) {
                this.scroll = new BScroll(this.$refs.scrollWrapper, {
                  pullDownRefresh: {
                    threshold: 50, // 當(dāng)下拉到超過頂部 50px 時,觸發(fā) pullingDown 事件
                    stop: 20 // 刷新數(shù)據(jù)的過程中,回彈停留在距離頂部還有 20px 的位置
                  },
                  pullUpLoad: {
                    threshold: -20 // 在上拉到超過底部 20px 時,觸發(fā) pullingUp 事件
                  }
                })
                this.scroll.on('pullingDown', () => {
                  // 刷新數(shù)據(jù)的過程中,回彈停留在距離頂部還有20px的位置
                  // 在刷新數(shù)據(jù)完成之后,調(diào)用 finishPullDown 方法,回彈到頂部
                  this.showTime = true
                  setTimeout(() => {
                    this._initScroll()
                  }, 2000)
                  this.scroll.finishPullDown()
                  this.showTime = false
                  this.scroll.refresh()
                })
                this.scroll.on('pullingUp', () => {
                  // 請求數(shù)據(jù)
                })
              } else {
                this.scroll.refresh()
              }
            })
          })
      }
    },
    components: {
      Loading
    }
  }
</script>



(四) Vue.set 和 this.$set



   selectProducted: function(loop){      // loop是從dom中傳過來的數(shù)據(jù)
                if(typeof loop.checked == "undefined"){

                    // Vue.set(loop,'checked',true);   

                                         //向loop變量里面注冊了checked屬性,值是true;(vue全局注冊);

                    this.$set(loop,'checked',true);  

                                        //向loop變量里面注冊checked屬性,值是true;(vue局部注冊)

                }else{
                    loop.checked = !loop.checked;
                }
                this.calculateTotalPrice();
            },

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

<li v-for="(loop,index) in list">
  <div class="cart-item-check">
      <a href="javascipt:;" 
           class="item-check-btn " 
           v-bind:class="{'check':loop.checked}" 
           @click="selectProducted(loop)>
      </a>
  </div>      
</li> 

                        

(五) v-pre 和 v-once 和 ( v-on:click.once="" )

v-pre


<div class="right" v-pre>{{item.abs}}</div>
輸出結(jié)果: {{item.abs}}   

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

v-once


 <div v-on:click="add" class="add">+</div>
    <div v-once>{{number}}</div>     // 只執(zhí)行一次,輸出1
    <div>{{number}}</div>  // 一直累加

     add() {
        this.number += 1
      },
-----------------------------------------------

v-on:click.once=""


 <div v-on:click.once="add" class="add">+</div>


(六) font-awesome字體圖標(biāo)

  • 安裝

npm install font-awesome --save

  • main.js 中引入
在main.js中

import 'font-awesome/css/font-awesome.css'

  • 使用

<i class="fa fa-battery-full" aria-hidden="true"></i>

.fa-battery-full
     font-size:100px    // 改變大小
     color:red   // 改變顏色

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容