Vue重點學習經驗(1)MvvM,Vue生命週期,父子組件通信

1.對於MVVM的理解

  • MVVM圖示
    在這裏插入圖片描述
    Mvvm定義MVVM是Model-View-ViewModel的簡寫。即模型-視圖-視圖模型。
  • (1) 模型Model層:也是數據層。
    • 數據可能是我們固定的模擬數據,更多的是來自我們的服務器,從網絡上請求下來的數據。
    • 實際處理中,數據會比較複雜
  • (2) 視圖View層:也是視圖層。
    • 在我們的前端開發中,通常就是DOM層。
    • 主要作用是給用戶展示各種信息。
  • (3) 視圖模型層VueModel:也是視圖模型層。
    • 視圖模型層是View和Model溝通的橋樑。
    • 一方面它實現了Data Binding,也就是數據綁定,將Model的改變實時的反應到View中。
    • 另外一方面它實現了DOM Listener,也就是DOM監聽,在一些必要條件下改變對應的Data。
  • (4) 總結:在MVVM的框架下視圖和模型是不能直接通信的。它們通過ViewModel來通信,ViewModel通常要實現一個observer觀察者,當數據發生變化,ViewModel能夠監聽到數據的這種變化,然後通知到對應的視圖做自動更新,而當用戶操作視圖,ViewModel也能監聽到視圖的變化,然後通知數據做改動,這實際上就實現了數據的雙向綁定。並且MVVM中的View 和 ViewModel可以互相通信。

2.Vue生命週期

VUE生命週期圖示
在這裏插入圖片描述

  • (1)什麼是Vue生命週期?
    Vue 實例從創建到銷燬的過程,就是生命週期。從開始創建、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、銷燬等一系列過程,稱之爲 Vue 的生命週期。
  • (2)vue生命週期的作用是什麼?
    它的生命週期中有多個事件鉤子,讓我們在控制整個Vue實例的過程時更容易形成好的邏輯。
  • (3)vue生命週期總共有幾個階段?
    它可以總共分爲8個階段:創建前/後, 載入前/後,更新前/後,銷燬前/銷燬後。
  • 下面是一個大佬對vue生命週期的總結,我覺得非常不錯,這裏引用一下。
    大佬的測試代碼:
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script>
</head>
<body>

<div id="app">
     <p>{{ message }}</p>
</div>

<script type="text/javascript">
    
  var app = new Vue({
      el: '#app',
      data: {
          message : "xuxiao is boy" 
      },
       beforeCreate: function () {
                console.group('beforeCreate 創建前狀態===============》');
               console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined
               console.log("%c%s", "color:red","data   : " + this.$data); //undefined 
               console.log("%c%s", "color:red","message: " + this.message)  
        },
        created: function () {
            console.group('created 創建完畢狀態===============》');
            console.log("%c%s", "color:red","el     : " + this.$el); //undefined
               console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化 
               console.log("%c%s", "color:red","message: " + this.message); //已被初始化
        },
        beforeMount: function () {
            console.group('beforeMount 掛載前狀態===============》');
            console.log("%c%s", "color:red","el     : " + (this.$el)); //已被初始化
            console.log(this.$el);
               console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化  
               console.log("%c%s", "color:red","message: " + this.message); //已被初始化  
        },
        mounted: function () {
            console.group('mounted 掛載結束狀態===============》');
            console.log("%c%s", "color:red","el     : " + this.$el); //已被初始化
            console.log(this.$el);    
               console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
               console.log("%c%s", "color:red","message: " + this.message); //已被初始化 
        },
        beforeUpdate: function () {
            console.group('beforeUpdate 更新前狀態===============》');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);   
               console.log("%c%s", "color:red","data   : " + this.$data); 
               console.log("%c%s", "color:red","message: " + this.message); 
        },
        updated: function () {
            console.group('updated 更新完成狀態===============》');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el); 
               console.log("%c%s", "color:red","data   : " + this.$data); 
               console.log("%c%s", "color:red","message: " + this.message); 
        },
        beforeDestroy: function () {
            console.group('beforeDestroy 銷燬前狀態===============》');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);    
               console.log("%c%s", "color:red","data   : " + this.$data); 
               console.log("%c%s", "color:red","message: " + this.message); 
        },
        destroyed: function () {
            console.group('destroyed 銷燬完成狀態===============》');
            console.log("%c%s", "color:red","el     : " + this.$el);
            console.log(this.$el);  
               console.log("%c%s", "color:red","data   : " + this.$data); 
               console.log("%c%s", "color:red","message: " + this.message)
        }
    })
</script>
</body>
</html>

當我們在頁面上打開F12的時候,可以看到當前打印結果。
在這裏插入圖片描述

首先這裏有兩個已經解決了的問題。

  • 頁面在第一次加載時會觸發哪幾個鉤子函數?
    很明顯我們可以看到beforeCreate,create,beforeMounted,mounted。
  • DOM 渲染在 哪個週期中就已經完成?
    +很明顯是在mounted中完成了掛載,DOM渲染。
    繼續往下看:

第一次加載頁面的鉤子函數

  • beforeCreate:數據觀測和初始化事件還沒有開始。也就是el和data還沒有初始化。
  • create:完成了data數據的初始化以及屬性和方法的運算,初始化事件,此時$el屬性還沒有顯示出來。(個人一般較多的在這裏請求後端數據)。
  • beforeMounted:完成了el和data的初始化,實例編譯模板,將data裏面的數據和模板生成html,但此時還沒有掛在html到頁面上。
  • mounted:用新創建的$el替換el,將編譯好的html替換el屬性掛載到頁面上去。

更新數據時的鉤子函數

當我們在F12裏面修改app.message數據的時候,上述代碼執行以下結果。
在這裏插入圖片描述

  • beforeUpdata:在數據更新前調用。
  • Updata:數據更新後調用,虛擬dom修改數據並且渲染。
  • 可以看到數據更新後兩個生命週期函數中的data時同步的。

頁面銷燬時的鉤子函數

當我們執行app.$destory()的時候執行。
在這裏插入圖片描述

  • beforeDestroy(銷燬前) 在實例銷燬之前調用。實例仍然完全可用。
  • 銷燬後) 在實例銷燬之後調用。調用後,所有的事件監聽器會被移除,所有的子實例也會被銷燬。

3.父子組件傳值。

父組件通過 props (properties 屬性的意思)向子組件傳遞數據

  • 父組件裏面將要傳遞的數據以變量的形式傳遞給子組件
<home-swiper :banners="banners" @swiperImageLoad="swiperImage"></home-swiper>
  • 子組件裏面定義props
props: {
      banners: {
        type: Array,
        required: true
      }
    },
  • 子組件使用數據
<swiper-item v-for="(item, index) in banners" :key="index">
  • props 數據驗證
    // 1.通過數組傳值
    props:[‘cmessage’,‘cmovies’],

     //2.類型限制傳值
     props:{
         //類型限制
         cmovies:Array,
         cmessage:String
     },
    
     //3.類型限制+ 提供默認值 + required : 必須傳入的值
     //如果類型是對象或者數組的時候,默認值必須是一個函數
     props:{
         cmovies:{
             type:Array,
             default(){
                 return ['寶雞市','西安市','玉玲市','四川市']
             }
         },
         cmessage:{
             type:String,
             default:'北京歡迎你'
         }
     },
    
  • props 中的駝峯標識問題
    v-bind 綁定的時候 不支持駝峯標識 如果是 cMovies 需要寫成 c-movies 這樣纔可以達到我們想要的效果.

子組件通過事件向父組件發送消息

  • 子組件傳給父組件:$emit方法傳遞參數
  • 代碼實例
<!-- 子組件定義事件change(item)並且將要傳遞的數據當作參數傳遞過去-->
<button v-for='item in shopList' @click='change(item)'>{{ item.name }}</button>

<!--子組件發射自定義的函數,並且傳遞參數item-->
 change(item){
                    this.$emit('itemclick',item)
                }
<!-- 父組件監聽子組件發送的事件-->
<cpn @itemclick='shopclick'></cpn>

<!-- 父組件定義函數拿到數據-->
 shopclick(item){
                    console.log(item.id + item.name)
                }

下一篇:Vue重點學習經驗2

  • Vue雙向綁定原理,以及簡單雙向綁定的實現
  • Vue定義路由以及Vue的路由實現:hash模式 和 history模式
  • 對keep-alive 的瞭解?

文章參考1:https://segmentfault.com/a/1190000016344599?utm_source=tag-newest

作者:沉靜的閃光

文章參考2:https://segmentfault.com/a/1190000008010666
作者:城南

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章