1. 程式人生 > 實用技巧 >Potato家族本地提權分析

Potato家族本地提權分析

VUE的那些狀態翻譯過來就是

建立前,
建立完成,
裝載前,
裝載完成,
更新資料時,
銷燬前,
銷燬完成。

如下:

beforeCreate

在這個鉤子函式裡,只是剛開始初始化例項,你拿不到例項裡的任何東西,比如data和methods和事件監聽等。

data: {
    msg: 'linlin'
  },
  methods: {
    getLists(){
      return 'aaa'
    }
  },
  beforeCreate() {
    console.log('beforeCreate',this.msg,this.getLists())
  }

執行上面程式碼,控制檯報錯

因為就像前面說的這個鉤子函式裡拿不到data和methods

created

在例項建立完成後被立即呼叫。在這一步,例項已完成以下的配置:資料觀測 (data observer),屬性和方法的運算,watch/event 事件回撥。然而,掛載階段還沒開始,$el屬性目前不可見。

這是最早能拿到例項裡面的資料和方法的一個鉤子函式。應用場景:非同步資料的獲取和對例項資料的初始化操作都在這裡面進行

data: {
    msg: 'linlin',
    imgs: null
  },
methods: {
    getLists(){
      this.$http.get(url).then(res=>{
        
this.imgs = res.data.lists console.log(this.imgs) }) } }, created() { this.getLists() }

beforeMount

在掛載開始之前被呼叫:相關的render函式首次被呼叫

不論是created還是beforeMount在它們裡面都拿不到真實的dom元素,如果我們需要拿到dom元素就需要在mounted裡操作

<div id="app">
      <ul>
        <li v-for="(item,index) in arr
" :key="index">{{item}}</li> </ul> </div> <script> let app = new Vue({ data: { arr: [1,2,3] }, created() { console.log('created',document.querySelectorAll('li').length) }, beforeMount() { console.log('beforeMount',document.querySelectorAll('li').length) }, mounted() { console.log('mounted',document.querySelectorAll('li').length) }, }) </script>

mounted

上面的案例mounted可以拿到dom元素,但也只是能拿到初始化資料裡的dom元素,如果是存在非同步對dom元素資料進行更改我們就只能在updated裡獲取,應用場景:初始資料(在data中有的)的dom渲染完畢,可以獲取dom

<div id="app">
      <ul>
        <li v-for="(item,index) in arr" :key="index">{{item}}</li>
      </ul>
    </div>

created() {
    setTimeout(()=>{
      this.arr = [4,5,6,7]
      console.log('created',document.querySelectorAll('li').length)
    })   
  },
  mounted() {
    console.log('mounted',document.querySelectorAll('li').length)
  }

執行上面程式碼,發現不管是mounted還是created裡拿到的都是3,而不是4

這裡之所以先打印出mounted是因為created裡面的是非同步操作所以最後才執行完,而我們如果想要拿到正確的dom元素的個數就需要在updated裡面獲取

updated(){
  console.log('updated',document.querySelectorAll('li').length)
}

另外$children子元件的獲取也需要在mounted裡

beforeUpdate

當資料更新後出發的鉤子函式,這個鉤子函式裡拿到的是更改之前的資料,虛擬DOM重新渲染和打補丁之前被呼叫。

你可以在這個鉤子中進一步地修改data,這不會觸發附加的重渲染過程。

updated

上面雖然能在update裡拿到更改後的資料,但是並不建議在這裡面進行對非同步資料得到的dom操作,因為有可能你當前的資料不止更改一次,而update只要相關的資料更改一次就會執行一次,注意:updated是指mouted鉤子後(包括mounted)的資料更改,在created裡的資料更改不叫更改叫做初始化,所以我們下面在created裡修改資料是通過一個非同步來確保updated可以執行的。我們一般都是在事件方法裡更改資料,然後通過updated對其操作。應用場景:如果dom操作依賴的資料是在非同步操作中獲取,並且只有一次資料的更改 ,也可以說是資料更新完畢:如果對資料更新做一些統一處理在updated鉤子中處理即可。

注意:當這個鉤子被呼叫時,元件DOM的data已經更新,所以你現在可以執行依賴於DOM的操作。但是不要在當前鉤子裡修改當前元件中的data,否則會繼續觸發beforeUpdate、updated這兩個生命週期,進入死迴圈!

created() {
    setTimeout(()=>{
      this.arr = [4,5,6,7]
      console.log('created',document.querySelectorAll('li').length)
    })
    setTimeout(()=>{
      this.arr = [10,11,12,13,14]
      console.log('created',document.querySelectorAll('li').length)
    },1000)    
  },
beforeUpdate() {
    console.log('beforeUpdate',document.querySelectorAll('li').length)
  },
  updated() {
    console.log('updated',document.querySelectorAll('li').length)
  },

上面updated執行了兩遍,之所以一開始created是3是因為上面我們說的他是在一個非同步裡,也是在mouted後獲取的所以是3。

在事件方法裡更改資料

<div id="app">
      <ul>
        <li v-for="(item,index) in arr" :key="index" @click="getAdd">{{item}}</li>
      </ul>
      <div>{{msg}}</div>
    </div>

data: {
    arr: [1,2,3],
  },
  methods: {
    getAdd(){
      this.arr = [4,5,6,7]
    }
  },
  updated() {
    console.log(this.arr)
  }

如果想分別區別不同的資料更新,同時要對dom進行操作那麼需要使用nextTick函式處理

created() {
    setTimeout(()=>{
      this.arr = [4,5,6,7]
      this.$nextTick(()=>{
        console.log('nextTick',document.querySelectorAll('li').length)
      })
    })
    setTimeout(()=>{
      this.arr = [10,11,12,13,14]
      this.$nextTick(()=>{
        console.log('nextTick',document.querySelectorAll('li').length)
      })
    },1000)
        
  },

這樣我們想對哪一次的資料進行操作就直接在this.$nextTick裡面寫就行

在updated中修改資料陷入死迴圈

<div id="app">
    {{a}}
    <button @click="a=2">點我</button>
  </div>
  <script>
    new Vue({
      el: '#app',
      data: {
        a: [1]
      },
      beforeUpdate() {
        console.log('beforeUpdate')
      },
      updated() {
        console.log(this.a)
        console.log('updated')
        this.a = [2]

      },
    })
  </script>

updated,watch和nextTick區別

updated對所有資料的變化進行統一處理

watch對具體某個資料變化做統一處理

nextTick是對某個資料的某一次變化進行處理

如果例項裡面沒寫el掛載點你就需要在例項後面通過.$mount('#app')來手動觸發

beforeDestroy

例項銷燬之前呼叫。在這一步,例項仍然完全可用

destroyed

Vue 例項銷燬後呼叫。呼叫後,Vue 例項指示的所有東西都會解繫結,所有的事件監聽器會被移除,所有的子例項也會被銷燬。

beforeDestroy和destroyed只能通過手動觸發$destroy來呼叫

let app = new Vue({
  beforeDestroy() {
    console.log('beforeDestroy')
  },
  destroyed() {
    console.log('destroyed')
  }

})
app.$destroy()
@轉發至知乎:https://zhuanlan.zhihu.com/p/53039906