「從0到1搭建自己的UI組件庫」-- button組件

寫在前面:

我是「沸羊羊_」,暱稱來自於姓名的縮寫 fyy ,之前嘔心瀝血經營的博客因手殘意外註銷,現經營此賬號。
本人是個小菜,正向着全棧工程師的方向努力着,文章可能並不高產,也很基礎,但每寫一篇都在用心總結,請大佬勿噴。
如果您對編程有興趣,請關注我的動態,一起學習研究。
感謝每位讀者!

前言

作爲本系列專欄第一篇文章,封裝最最常用的 button 組件,話不多說,先來看看 element-UI 組件庫封裝的 button 樣式。整篇文章看完,你就可以擁有屬於自己的 button 組件了。

知識點

  • 組件通訊
  • 插槽
  • props校驗

初始化項目

新建 vue 項目前:

  • 確保安裝 nodeJs ,終端輸入測試命令:node -v 測試是否安裝成功
  • 安裝 vue-cli ,終端輸入安裝命令:npm install -g vue cli ,測試命令: vue --version

確保完成上述步驟,可以新建我們的 vue 項目了,我們使用 webpack 打包工具,所以 終端輸入命令:vue init webpack fyy-ui (項目名稱),根據提示信息選擇我們的項目配置就可以了。

封裝button組件

文件配置

  • 首先,新建 button.vue 文件
  • App.vue 與 main.js 文件 vue-cli 幫我們生成了,我們只要把 App.vue 文件中默認的數據清空即可。
    首先,我們新建 button.vue 文件。
  • 在 main.js 文件中,引入並掛載 button.vue 文件。
//main.js
import FyyButton from './components/button.vue'
Vue.use(ElementUI)

按鈕背景色

效果:
在這裏插入圖片描述

// button.vue

<template>
  //:class="[`fyy-button--${type}`]" :代表樣式爲 "fyy-button--'父組件傳遞過來的type值'"
  <button class="fyy-button" :class="[`fyy-button--${type}`]">
    //使用插槽,供父組件傳遞按鈕名字
    <slot></slot>
  </button>
</template>

export default {
  //設置組件名稱,使用時用此名稱
  name: "FyyButton",
  props: {
    //接收參數:type
    type: {
      //參數類型:String
      type: String,
      //默認值爲 default
      default: "default"
    }
  }
};

<style lang="scss" scoped>
	//button組件封裝,主要是樣式展示,關於項目整體代碼結構會發布到 github 上。
</style>
//父組件--App.vue
<template>
  <div id="app">
    <div class="row">
      //type爲傳遞給子組件樣式類型
      <FyyButton @click="click">按鈕</FyyButton>
      <FyyButton type="primary">按鈕</FyyButton>
      <FyyButton type="success">按鈕</FyyButton>
      <FyyButton type="info">按鈕</FyyButton>
      <FyyButton type="warning">按鈕</FyyButton>
      <FyyButton type="danger">按鈕</FyyButton>
    </div>
  </div>
</template>

樸素按鈕

效果:
在這裏插入圖片描述

//button.vue

<template>
  //樸素按鈕在普通按鈕上添加了 {'is-plain':plain}  class樣式,代表值爲父組件傳遞的 plain 屬性
  <button class="fyy-button" :class="[`fyy-button--${type}`,{'is-plain':plain}]">
    <slot></slot>
  </button>
</template>

export default {
  //設置組件名稱,使用時用此名稱
  name: "FyyButton",
  props: {
    //接收參數:type
    type: {
      //略
    },
    //接收參數:plain
    plain: {
      type: Boolean,
      default: false
    }
  }
};
<style lang="scss" scoped>
	//樣式略。button組件封裝,主要是樣式展示,關於項目整體代碼結構會發布到 github 上。
</style>
//父組件--App.vue

<template>
  <div id="app">
    <div class="row">
      //type爲傳遞給子組件樣式類型
      <FyyButton @click="click">按鈕</FyyButton>
      <FyyButton type="primary">按鈕</FyyButton>
      //其他略
    </div>
    <div class="row">
      <FyyButton plain>按鈕</FyyButton>
      <FyyButton plain type="primary">按鈕</FyyButton>
      //其他略
    </div>
  </div>
</template>

圓角按鈕

效果:
在這裏插入圖片描述

//button.vue

<button class="fyy-button" :class="[`fyy-button--${type}`,{'is-plain':plain,'is-round':round}]">
<script>
export default {
	props: {
		round: {
	      type: Boolean,
	      default: false
	    }
	}
}
//父組件-App.vue

<div class="row">
  <FyyButton plain round>按鈕</FyyButton>
  <FyyButton plain round type="primary">按鈕</FyyButton>
</div>

圓形按鈕

效果:
在這裏插入圖片描述
//代碼略

icon按鈕

效果:
在這裏插入圖片描述
部分代碼略。

// 父組件 App.vue 

<div class="row">
	<FyyButton plain class="fyy-icon-pencil" round>按鈕</FyyButton>
	<FyyButton plain class="fyy-icon-pencil" round type="primary">按鈕</FyyButton>
</div>

icon + 文字 按鈕

如果用戶想要 icon 和 文字 同時存在的 button ,會發現 icon 和 文字緊挨着,如果在中間加個空格是不是會好看些,那如何保證icon 和 文字中間有空格,還能保證只有文字或icon時,沒有空格,如何實現呢?

效果:
在這裏插入圖片描述

//button.vue

<template>
  <button
    class="fyy-button"
    :class="[`fyy-button--${type}`,{'is-plain':plain,'is-round':round,'is-circle':circle}]"
  >
    //如果父組件傳遞 icon
    <i v-if="icon" :class="icon"></i>
    //當父組件沒有傳入插槽的時候,span標籤就不顯示;$slots.default可以獲取所有插槽,用於判斷父組件是否傳遞 slot
    <span v-if="$slots.default">
      <slot></slot>
    </span>
  </button>
</template>

<style lang="scss" scoped>
	// button中icon和文字同時存在,設置margin值
	.fyy-button [class*="fyy-icon-"] + span {
	  margin-left: 5px;
	}
</style>

click 事件

當我們使用 element 或其他組件庫的組件時,會發現除了 button 可以使用 @click 觸發單擊事件外,其他組件的單擊都不可以使用 @click 觸發,這是爲什麼呢?

因爲 element 只給 button 組件的 click 事件封裝了,因爲很常用。而其他組件的click事件都沒有封裝,如果沒封裝,我們使用時候怎麼用 click 事件呢?如果使用封裝的組件的原生事件都需要在 事件後 添加 .native 纔可以觸發。比如: @click.native 可以觸發單擊事件。

我們現在給button封裝一個 click 事件。

//button.vue

<template>
  <button
    class="fyy-button"
    :class="[`fyy-button--${type}`,{'is-plain':plain,'is-round':round,'is-circle':circle}]"
    @click="handleClick()"
  ></button>
</template>
<script>
	methods: {
    handleClick(e) {
      this.$emit("click", e);
    }
  }
</script>

這樣在父組件中使用 @click 就可以觸發單擊事件了。

參數支持

參數名 參數描述 類型 默認值
type 按鈕類型 ( primary / success / warning / danger / info ) string default
plain 是否是樸素按鈕 boolean false
round 是否是圓角按鈕 boolean false
circle 是否是原形按鈕 boolean false
icon 圖標類名 string

事件支持

事件名 事件描述
click 單擊事件

github地址

fyy-ui-button組件 github 地址

關於icon

element-ui 有自己的字體庫,我們可以選擇扒源碼把 element-ui 的字體庫拿下來,由於小編扒下來源碼字體庫報錯,猜測可能由於element-ui字體庫內部有url是相對地址,反正由於小編經過幾個小時的奮鬥沒有解決掉錯誤,如果讀者有扒源碼的字體庫的,可以交流一下。這裏,我下載的是 icomoon 字體庫。小編將 icomoon 字體庫文件也放到 github託管了,需要的可以去clone。

最後

專欄系列文章中難免會出現錯誤,還請大佬們指正!不勝感激。最後,希望此專欄順利誕生!

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