Vue組件知識詳解

組件概念

一個完整的網頁是複雜的,如果將其作爲一個整體來進行開發,將會遇到下面的困難

  • 代碼凌亂臃腫
  • 不易協作
  • 難以複用

vue推薦使用一種更加精細的控制方案——組件化開發

所謂組件化,即把一個頁面中區域功能細分,每一個區域成爲一個組件,每個組件包含:

  • 功能(JS代碼)
  • 內容(模板代碼)
  • 樣式(CSS代碼)

由於沒有構建工具的支撐,CSS代碼暫時無法放到組件中

組件開發

創建組件

組件是根據一個普通的配置對象創建的,所以要開發一個組件,只需要寫一個配置對象即可

該配置對象和vue實例的配置是幾乎一樣

//組件配置對象
var myTest = {
  data(){
    return {
      // ...
    }
  },
  computed:{
    //...
  },
  methods:{
    //...
  },
  template: `....`
}

值得注意的是,組件配置對象和vue實例有以下幾點差異:

  • el
  • data必須是一個函數,該函數返回的對象作爲數據
  • 由於沒有el配置,組件的模板必須定義在template

使用組件

使用組件分爲兩步:註冊組件應用組件

註冊組件:讓組件可以在模板中使用

應用組件:具體的在模板中使用組件

註冊組件

註冊組件分爲兩種方式,一種是全局註冊,一種是局部註冊

  1. 全局註冊

一旦全局註冊了一個組件,整個應用中任何地方都可以使用該組件

全局註冊的方式是:

// 參數1:組件名稱,將來在模板中使用組件時,會使用該名稱
// 參數2:組件配置對象
// 該代碼運行後,即可在模板中使用組件
Vue.component('my-test', myTest)

在模板中,可以使用組件了

<my-test />
<!-- 或 -->
<my-test></my-test>

但在一些工程化的大型項目中,很多組件都不需要全局使用。
比如一個登錄組件,只有在登錄的相關頁面中使用,如果全局註冊,將導致構建工具無法優化打包
因此,除非組件特別通用,否則不建議使用全局註冊

  1. 局部註冊

局部註冊就是哪裏要用到組件,就在哪裏註冊

局部註冊的方式是,在要使用組件的組件或實例中加入一個配置:

// 這是另一個要使用my-test的組件
var otherTest = {
  components:{
    // 屬性名爲組件名稱,模板中將使用該名稱
    // 屬性值爲組件配置對象
    "my-test": myTest
  },
  template: `
    <div>
      <!-- 該組件的其他內容 -->
      <my-test></my-test>
    </div>
  `;
}

應用組件

在模板中使用組件特別簡單,把組件名當作HTML元素名使用即可。

但要注意以下幾點:

  1. 組件必須有結束

組件可以自結束,也可以用結束標記結束,但必須要有結束

下面的組件使用是錯誤的:

<my-test>
  1. 組件的命名

無論你使用哪種方式註冊組件,組件的命名需要遵循規範。

組件可以使用kebab-case 短橫線命名法,也可以使用PascalCase 大駝峯命名法

下面兩種命名均是可以的

var otherTest = {
  components:{
    "my-test": myTest,  // 方式1
    MyTest: myTest //方式2
  }
}

使用PascalCase方式命名還有一個額外的好處,即可以在模板中使用兩種組件名

var otherTest = {
  components:{
    MyTest: myTest
  }
}

模板中:

<!-- 可用 -->
<my-test />
<MyTest />

因此,在使用組件時,爲了方便,往往使用以下代碼:

var MyTest = {
  //組件配置
}

var OtherTest = {
  components:{
    MyTest// ES6速寫屬性
  }
}

組件樹

一個組件創建好後,往往會在各種地方使用它。它可能多次出現在vue實例中,也可能出現在其他組件中。

於是就形成了一個組件樹

向組件傳遞數據

大部分組件要完成自身的功能,都需要一些額外的信息

比如一個頭像組件,需要告訴它頭像的地址,這就需要在使用組件時向組件傳遞數據

傳遞數據的方式有很多種,最常見的一種是使用組件屬性 component props

首先在組件中申明可以接收哪些屬性:

var MyTest = {
  props:["p1", "p2", "p3"],
  // 和vue實例一樣,使用組件時也會創建組件的實例
  // 而組件的屬性會被提取到組件實例中,因此可以在模板中使用
  template: `
    <div>
      {{p1}}, {{p2}}, {{p3}}
    </div>
  `
}

在使用組件時,向其傳遞屬性:

var OtherTest = {
  components: {
    MyTest
  },
  data(){
    return {
      a:1
    }
  },
  template: `
    <my-test :p1="a" :p2="2" p3="3"/>
  `
}

注意:在組件中,屬性是隻讀的,絕不可以更改,這叫做單向數據流

組件實例的生命週期

當我們使用組件時<my-test />,會創建一個組件的實例,類似於vue實例,每個實例都有明確的生命週期
在這裏插入圖片描述

在生命週期的各個階段,會觸發調用一些函數,這些函數被稱爲生命週期鉤子函數

最常用的兩個鉤子函數:createdmounted

  1. created

created函數發生在注入之後、模板編譯之前,此時,組件還沒有呈現界面

如果有些數據需要經過某些計算得到,可以在這裏進行更改,屆時,在編譯中就會直接應用新的數據

但要注意,由於還未呈現界面,如果在這裏使用了特別耗時的計算,將導致長時間的白屏

  1. mounted

mounted函數發生在掛載之後,此時頁面已經呈現,在這裏,可以用傳統方案獲取到dom,儘管不太常見

如果某些數據在一開始就需要更新,同時又特別耗時,建議放到mounted中

關於異步代碼

如果某些組件一開始時要執行一些異步代碼(如ajax),createdmounted均可,效果差別不大

因爲由於事件循環的機制,會導致異步代碼最終都會在掛載完後調用

但如果異步代碼需要特別長時間的準備(與很多因素有關),則建議放置到mounted中

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