使用mpvue開發小程序教程(四)

在上一章節中,咱們將vue-cli命令行工具生成的代碼骨架中的src目錄清理了一遍,而後從頭開始配置和編寫了一個能夠運行的小程序頁面,算是正真走上了使用mpvue開發小程序的第一步。今天咱們將進一步來了解和學習mpvue / Vue的其餘重要功能。html

 

既然mpvue是基於Vue的,那麼就沒有理由不進一步學習一下Vue最核心的東西:組件。組件系統是Vue應用開發中最具價值的特性之一,在前文中其實咱們就已經有在使用組件了,好比App.vue和首頁index.vue就是兩個Vue組件。vue

組件是一種抽象,容許咱們使用小型、獨立和一般可複用的組件構建大型應用。仔細想一想,幾乎任意類型的應用界面均可以抽象爲一個組件樹,若干的小組件能夠聚合成一個完整的界面:vue-cli


一個好的組件系統必定會有這些特色:封裝性、複用性、擴展性。對於Vue的組件來講,這幾點都算是實現的比較的優秀的。npm

組件的封裝性

Vue組件的寫法能夠避免將屬於一個獨立邏輯單位的代碼散落在各處,能夠將界面(DOM)、樣式(CSS)、行爲(JS)三部分的代碼很好的組織在一塊兒(推薦的實踐是使用.vue文件)。在設計編寫一個組件時,咱們要記住的原則就是:編程

避免向外部暴露過多的東西,只暴露必要的外部交互接口(組件屬性、事件、方法等)。小程序

下面咱們來在原先的代碼基礎上,建立一個簡單的按鈕點擊計數器組件,它將實現的功能是:點擊按鈕並展現已點擊按鈕次數、點擊清零按鈕實現點擊次數的歸零。在src/components目錄下,新建一個click-counter.vue組件文件,並編寫以下代碼:微信

<template>
  <div class="click-counter">
    <div class="counter-num">次數:{{num}}</div>
    <button class="counter-btn" @click="handleClick">點我呀!</button>
    <button class="counter-reset-btn" @click="handleResetClick">清零</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      num: 0
    };
  },

  methods: {
    handleClick() {
      this.num += 1;
    },
    handleResetClick() {
      this.num = 0;
    }
  }
};
</script>

<style>
.click-counter {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid red;
  background-color: #ffffff;
  padding: 10px;
}

.counter-num,
.counter-btn,
.counter-reset-btn {
  flex: 1;
  margin: 3px;
}
</style>

編寫完這個組件後,咱們來嘗試在首頁組件src/pages/index/index.vue文件中使用它:微信開發

<template>
  <div class="container" @click="clickHandle">
    <div class="message">{{msg}}</div>
    <!-- 使用 click-counter 組件 -->
    <click-counter />
  </div>
</template>

<script>
// 導入 click-counter 組件
import ClickCounter from "@/components/click-counter";

export default {
  // 聲明在當前組件下使用 counter-click 組件
  components: { ClickCounter },

  data() {
    return {
      msg: "Hello"
    };
  },

  methods: {
    clickHandle() {
      this.msg = "Clicked!!!!!!";
    }
  }
};
</script>

<style scoped>
.message {
  color: red;
  padding: 10px;
  text-align: center;
}
</style>

完成上面兩個步驟後,記得從新運行一下命令行npm run dev(注意點:新增文件必須從新運行該命令,編譯器不會自動檢測新加入的文件)。成功後經過微信開發者工具的模擬器查看,結果界面將會是這樣的:函數

點擊「點我呀!」按鈕,計數器就會累加點擊次數並更新界面上的數字;而點擊「清零」按鈕,則會將統計數字歸零。工具

回到代碼上來看,對於click-counter.vue的使用者index.vue來講,它並不關心太多click-counter.vue的實現細節,引入該組件文件並進行聲明,就能夠經過標籤的形式來使用它了,很是簡單明瞭。並且,這樣一個click-counter.vue組件也能夠被拿到其餘的Vue/mpvue代碼中使用,其餘使用者也並不須要關注它的實現細節,而只須要關心它能實現什麼功能就好了。這就是組件封裝帶來的好處。

不過,目前的這個click-counter組件尚未跟它的父組件之間有什麼交互或通訊,沒有體現出「暴露接口」的特性,那讓咱們來增長點代碼,瞭解下這一特性。首先解釋一下咱們要實現的功能:組件能夠接收一個外部設置的初始點擊次數值,在點擊「點我呀!」按鈕的時候,從這個初始值開始進行累加;而且點擊按鈕後,能夠通知組件的使用者(即父組件)當前的點擊統計值。

修改click-counter.vue的代碼:

<template>
  <div class="click-counter">
    <div class="counter-num">次數:{{num}}</div>
    <button class="counter-btn" @click="handleClick">點我呀!</button>
    <button class="counter-reset-btn" @click="handleResetClick">清零</button>
  </div>
</template>

<script>
export default {
  // 增長一個可從外部傳入的屬性initNum
  props: {
    initNum: {
      type: Number,
      default: 0
    }
  },

  data() {
    return {
      num: this.initNum //使用傳入的initNum值做爲初始的點擊數
    };
  },

  methods: {
    handleClick() {
      this.num += 1;
      this.notifyNum();
    },
    handleResetClick() {
      this.num = 0;
      this.notifyNum();
    },
    notifyNum() {
      //觸發自定義事件 clicknum
      this.$emit("clicknum", {
        num: this.num
      });
    }
  }
};
</script>

<style scoped>
.click-counter {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid red;
  background-color: #ffffff;
  padding: 10px;
}

.counter-num,
.counter-btn,
.counter-reset-btn {
  flex: 1;
  margin: 3px;
}
</style>

修改index.vue的代碼:

<template>
  <div class="container" @click="clickHandle">
    <div class="message">{{msg}}</div>
    <!-- 使用 click-counter 組件 -->
    <click-counter :init-num="10" @clicknum="handleClickNum" />
  </div>
</template>

<script>
// 導入 click-counter 組件
import ClickCounter from "@/components/click-counter";

export default {
  // 聲明在當前組件下使用 counter-click 組件
  components: { ClickCounter },

  data() {
    return {
      msg: "Hello"
    };
  },

  methods: {
    clickHandle() {
      this.msg = "Clicked!!!!!!";
    },
    handleClickNum(data) {
      console.log(">>>>>>", data.num);
    }
  }
};
</script>

<style scoped>
.message {
  color: red;
  padding: 10px;
  text-align: center;
}
</style>

觀察以上修改後的代碼能夠發現,在click-couter.vue中的主要變化是:

  1. 使用props定義了一個名爲initNum的數字型組件屬性(且初始值爲0)。它可用於接收使用組件外部傳入的值。而後,這個initNum值被賦值到data中的屬性num上做爲它的初始值。

  2. 在兩個按鈕的click事件處理方法中,額外調用了一個notifyNum()方法,它向組件觸發了一個自定義事件clicknum並攜帶了當前點擊次數值。

而在index.vue中的主要變化是實例化click-counter組件的這行代碼:

<click-counter :init-num="10" @clicknum="handleClickNum" />

實例化組件的時候,爲組件傳入了initNum屬性值10;而且添加了一個對自定義事件clicknum的監聽方法。

這樣一個結構實現了數據進入組件/數據傳出組件的機制,父子組件之間就能實現數據通訊。經過有限的通訊點進行數據互換,而不是直接進行函數調用,可使得代碼結構更優雅、更易維護。

組件的複用性

組件的複用性就好理解的多了,建立組件的目的,大多數時候就是但願這個組件能夠被多個地方、屢次使用,避免編寫重複的代碼。好比咱們前面的計數器組件,有可能一個項目中的多個頁面會用到,也可能一個頁面就會使用屢次。

Vue組件的複用也是很容易的,好比咱們要在前面例子中的index.vue中複用計數器組件,建立3個計數器,那麼直接在模板部分編寫3個標籤就好了:


<template>
  <div class="container" @click="clickHandle">
    <div class="message">{{msg}}</div>
    <!-- 建立 3個 click-counter 組件 -->
    <click-counter :init-num="10" @clicknum="handleClickNum" />
    <click-counter :init-num="20" @clicknum="handleClickNum" />
    <click-counter :init-num="30" @clicknum="handleClickNum" />
  </div>
</template>

運行後的效果以下圖所示,這三個計數器都能獨立統計各自的點擊數量:

組件的擴展性

談到擴展性,有面向對象編程經驗的開發者就會想到「繼承(extends)」。繼承是一種比較有效的擴展機制,不過隨着繼承的層次變深,代碼也會變得難以理解。在Vue組件中,沒有采用繼承的機制,而是推薦使用「組合」的方式。

在組合理念下,咱們儘可能將想複用性高的組件設計到最小可拆分單位,好比按鈕、輸入框、單選框等等,而後再將這些低層組件放入更高層組件中,一層一層,慢慢拼裝出知足需求的業務界面。

除了組合,Vue組件還提供了插槽(Slot)功能,至關於在一個組件中挖出了一個或多個坑,在具體使用這些具備插槽的組件時,能夠選擇往坑裏面填什麼內容(其餘組件)。

舉個例子,在計數器組件中,咱們在清零按鈕後面用<slot></slot>挖了一個坑:

<template>
  <div class="click-counter">
    <div class="counter-num">次數:{{num}}</div>
    <button class="counter-btn" @click="handleClick">點我呀!</button>
    <button class="counter-reset-btn" @click="handleResetClick">清零</button>
    <slot></slot>
  </div>
</template>

然後,在index.vue中使用計數器組件時,在<click-counter>標籤體中放入了額外的內容,會被傳入該組件中去用於填坑:

<template>
  <div class="container" @click="clickHandle">
    <div class="message">{{msg}}</div>
    <!-- 使用 click-counter 組件 -->
    <click-counter :init-num="10" @clicknum="handleClickNum">
      <!-- 填坑用... -->
      <input type="checkbox" /> 禁用
    </click-counter>
  </div>
</template>

從運行結果能夠看到,清零按鈕後面已經多出了咱們傳入的複選框和文字內容:

插槽其實能夠理解爲是另外一種形式的組件屬性:普通組件屬性傳入的是比較簡單類型的數據;而插槽傳入的能夠是更復雜的界面組件而已。

小結

本文咱們初步學習了一下Vue組件的相關理念和特性,但願你們花點時間去熟悉和掌握這些比較核心的知識點,相信無論在以後使用Vue進行Web應用開發,仍是mpvue小程序開發,都會更加駕輕就熟、事半功倍的!

使用mpvue開發小程序教程(五)
相關文章
相關標籤/搜索