1. 程式人生 > >Vue元件定義

Vue元件定義

簡介

元件是可複用的 Vue 例項。

本質上是一個物件,該物件包含datacomputedwatchmethodsfilters以及生命週期鉤子等成員屬性。

元件結構:


{
  data(){
    return {
      //
    }
  },
  computed:{
    displayName(){
      return '';
    }
  },
  methods:{
    onClickHandler(params){
      // do something
    }
  }
}

基礎知識

data屬性

  • data屬性維護一個元件內部狀態,其餘元件正常情況下不可見。

    • 可以通過props傳遞給子元件;
    • 可以通過$emit的方式傳遞給父元件;
    • 可以通過this.$refs.ref.$datamounted生命週期內獲取子元件的內部狀態;

      • 目前不知道如何監聽其變化;
      • 因為計算屬性computed和偵聽屬性watch只能監聽 響應式依賴 的變化,而$refs非響應式
  • 一個元件的 data 選項必須是一個函式

    ``` data選項有兩種定義方式: 一、物件形式: ``` data:{ //引用該元件的地方,共用一個狀態的引用,以至於,只要有一處修改了$data中的某一屬性值,其它引用該元件的地方也跟隨著改變該屬性值(其實,不是跟隨,本來就是同一個指向)。 } ``` 二、函式形式: ``` data(){ return { //引用該元件的地方,每一個元件都會獲得獨立的引用,互不干擾。 } } ``` ```

computed屬性 VS methods屬性 VS filter

區別 method computed filter
型別 函式 資料變數 函式
用途 作事件處理函式 作資料 作管道符
作用範圍 組建內 組建內 組建內(區域性註冊)、全域性(全域性註冊)
引數 可以帶參 不帶參(非函) 帶參
返回值 不要求 必須有 必須有
觸發 互動時觸發 在它的相關依賴發生改變時才會重新求值 傳入的資料變化時執行

注意:


元件構建的主要區別在於模板的生成方式

模板定義方式

template選項

字串模板

  • 以HTML標籤結構組成的字串;
  • 示例:

{
  template: '<h1 v-if="level === 1">簡單示例</h1>',
  props: {
    level: {
      type: Number,
      required: true
    }
  }
}

id選擇器指定的模板

  • id標識的一段script標籤包裹的HTML片段;
  • 示例:

<script type="text/x-template" id="anchored-heading-template">
  <h1 v-if="level === 1">
    簡單示例
  </h1>
</script>
{
  template: '#anchored-heading-template',
  props: {
    level: {
      type: Number,
      required: true
    }
  }
}

render

  • 發揮JavaScript最大的程式設計能力,該函式接收一個createElement方法作為第一個引數用來建立VNode
  • createElement接收三個引數:元件根節點型別、元件配置物件、子節點(官方關於元件配置物件的說明);
  • 示例:

{
  render: function (createElement) {
    return createElement(
      'h' + this.level,   // tag name 標籤名稱
      this.$slots.default // 子元件中的陣列
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
}

單檔案元件

單檔案元件將模板、邏輯、樣式在結構上分離,儲存在同一個檔案中。


<template>
  <div>
    ...
  </div>
</template>
<script>
...
export default{
  ...
}
...
</script>
<style>
...
</style>

方案選擇

template 單檔案 render
一行的簡單結構 常規的選擇 前邊兩種方案解決不了時候的選擇(靈活性高)

注意:

  • 不論選擇哪一種方案,定義模板時,一定要有一個非template標籤元素作根DOM,有且僅有一個。

元件註冊方式

區域性註冊

以上幾種方案定義的元件本質上都是一個物件,獲取該物件(假設變數名為TabBar),要求只在另一個元件(假設變數名為App)內使用:

App元件的配置物件:


{
  components:{
    'tab-bar': TabBar,
  }
}

這樣就是區域性註冊,該元件TabBar只能在App模板中使用<tab-bar></tab-bar>,其它元件對TabBar不可見。

全域性註冊

以上幾種方案定義的元件本質上都是一個物件,獲取該物件(假設變數名為TabBar),要求專案內任何元件可使用:

一般在專案的入口檔案(如:腳手架搭建專案的main.js)中:


Vue.component('tab-bar',TabBar);

這樣就是全域性註冊,該元件TabBar能在整個專案內使用<tab-bar></tab-bar>,所有元件對TabBar可見。

生命週期鉤子

以下用自己的語言將生命週期鉤子表述一下,如果有不對的地方,請校正:

beforeCreate

在這個時候,生命週期函式已經準備好。

  • 元件例項已經構建,但本元件例項的資料、方法還沒有注入;
  • 可以在各個生命週期內通過元件例項this呼叫根例項上注入的$router$store等物件。
  • 可以在本生命週期內進行資料初始化;

created

在這個時候,當前元件例項this上的屬性($dataprops$methods...)已經注入繫結,可以呼叫本例項上的成員屬性;

beforeMount

在進入本生命週期之前,會進行以下判斷:

  • 是否有el選項(指定掛載目標):

    • el選項的是根例項;
    • 沒有el選項的是非根例項(預設掛載元素為元件呼叫的位置);
  • 是否有template選項:

    • template選項的是內聯模板;
    • 沒有template選項的是單檔案元件;
    • 個人覺得,還有render選項的判斷;

最終這些模板都會轉換為render函式進行渲染!!!

  • 這個生命週期在解析模板,不知道有什麼實際用途。

mounted

在本生命週期之前,已經將模板渲染為真實DOM,其中vm.$el元件例項的根DOM元素

  • 本生命週期是初始化第三方外掛的場所;
  • 必要時候,可以在本生命週期內對DOM進行操作;
  • 本生命週期是獲取this.$refs.ref的場所;

來源:https://segmentfault.com/a/1190000015882730