本集定位:
爲何要叫1那, 由於我感受這個組件細節比較多, 應該會講不少內容, 因此先把基礎功能在這一集實現, 下集去作拓展.
button組件
這是一個基本上每一個工程都會用到的組件, 傳統的button千篇一概的樣式, 彷彿按鈕不作的同樣就無法用似的, 我偏要加一些別人沒加過的樣式來玩, 作過項目的小夥伴都會遇到一個問題, 防抖與節流, 而這麼主要的功能居然沒有ui組件庫的按鈕來集成, 此次我就把這兩個功能集成到按鈕式搞一搞, 😁開始行動吧.
建立組件基本結構
繼續秉承bem的思想, button整體結構以下:
css
index.js文件 仍是老套路, 組件的name屬性很重要.vue
import Button from './main/button.vue' Button.install = function(Vue) { Vue.component(Button.name, Button); }; export default Button
button.vuegit
<template> <button class="cc-button"> <slot /> </button> </template>
載體選用button原生標籤, 不選擇div標籤去模擬, 由於button自己有不少原生屬性, 並且語義化也要好過div. slot標籤固然是爲了接到用戶在button中間輸入的信息.github
按鈕第一條, 固然是先分個類型開開胃數組
<template> <button class="cc-button" :class="[ type ? 'cc-button--' + type : '' ]" :type="nativeType" <slot /> </button> </template> <script> export default { name: "ccButton", props: { type: String, // 類型 nativeType: String, // 原生的類型仍是要給的 } }; </script>
1: vue的class屬性很強大的, 他能夠數組的形式, 字符串的形式, 對象的形式, 而我採用的是 數組套一切的形式, 接下來對象類型也會在這個class數組裏面使用.
2: 原生的type也要接受, 由於用戶會有這樣的需求的, 我把它命名爲nativeType,跟element同樣.
3: 定義幾種相應的type樣式, 這個type屬性沒作校驗, 由於就算用戶不按照我給出的範圍傳值, 無非就是樣式沒變化, 沒有其餘影響的, 接下來就是定義按鈕的type樣式了.sass
Button.scss框架
@import './common/var.scss'; // 引入定義的全部變量 @import './common/mixin.scss'; // 引入全部的函數 @import './common/extend.scss'; // 引入公共樣式 @include b(button) { cursor: pointer; // 鼠標變小手 align-items: center; // 軸對齊 display: inline-flex; // 開啓flex模式, 因爲還要保持行的特性, 因此是inline-flex vertical-align: middle; // 中對齊, 爲了之後的icon準備的 justify-content: center; // 居中 background-color: white; // 白色 outline: 0; // 去掉聚焦時的輪廓 border-radius: 6px; // 感受圓角6仍是挺友好的, 沒有作成可配置 transition: all 0.1s; // 動畫固然要有, 交互體驗很重要 &:active { // 點擊的時候 box-shadow: none; // 嘿嘿這個是個人ui組件獨有的風格 opacity: 0.7; // 微微一暗, 以示點擊到了 transform: translateX(2px) translateY(2px) scale(0.9); // 會有個小小的位移 } &:hover { // 懸停變色 background-color:rgba(0,0,0,0.06) } @include commonShadow($--color-black); // 這個下面會說👇 @at-root { @include commonType(cc-button--) // 這個下面會說👇 }; }
var.scss文件,本項目採用的基本配色, 畢竟不是專業的你們見諒😁函數
// 基本色 $--color-black:#000000 !default; $--color-white:#FFFFFF !default; // 基本色鮮豔 $--color-nomal:#409EFF !default; $--color-success:#7CCD7C !default; $--color-warning:#FFB90F !default; $--color-danger: #FF0000 !default; $--color-disabled: #bbbbbb !default; $--color-difference: #F5F7FA !default; // 字體 $--size-big: 16px; $--size-nomal: 15px; $--size-small: 14px; // 輸入框 $--color-input-placeholder:#aaa
!default;這個東西的意思是優先級最低, 能夠被其餘的頂掉.字體
mixin.scssflex
@mixin commonShadow($color) { @if $color== 'success' { $color: $--color-success; } @if $color== 'warning' { $color: $--color-warning; } @if $color== 'danger' { $color: $--color-danger; } @if $color== 'disabled' { cursor: not-allowed; $color: $--color-disabled; } color: $color; border: 1px solid $color; box-shadow: 2px 2px $color; } @mixin commonType($name) { @each $type in (success, warning, danger) { .#{$name}#{$type} { @include commonShadow($type); } } }
1: 先說commonShadow這個函數吧, 這個是本套ui框架的特點樣式(慘不忍睹) , 就是想作點樣子不同的, 這個函數很簡單, 會根據傳進來的不一樣$color值來進行樣式的返回, 只要使用這個函數就會爲元素加上陰影效果, 注意@if後面不要習慣性的協商小括號
2: 因爲樣式不止一個, commonType函數應運而生, 他把我定義的幾種樣式類型以數組的形式進行循環,@each後面接的是每次循環出來的item, in 後面的()裏面的是要被循環的量
3: .#{$name}#{$type}就是傳進來的量與item的拼接, #{}就能夠在sass裏面進行拼接, 並非id的意思, 我傳入的是 'cc-button--' 因此這個函數定義了 'cc-button--success', 'cc-button--warning','cc-button--danger' 三種樣式加上了對應顏色的陰影效果, 如圖
點擊等更多效果能夠來個人博客查看 哈哈😁;
@at-root
這個關鍵詞沒有使用過的小夥伴注意了
1: 這個關鍵詞做用是, 使樣式跳出{}大括號範圍, 好比我在 cc-button這個class名下寫的樣式, 而後我用以下寫法:
.cc-button{ .cc-button--success{} }
以上寫法的意思是, .cc-button裏面有個class爲.cc-button--success的元素, 爲這個元素賦予相應屬性, 這顯然不是我想要的,
.cc-button{ @at-root { .cc-button--success{} } }
至關於
.cc-button{ } .cc-button--success{ }
因此我說他至關與跳出{}大括號.
點擊與disabled禁用屬性
我把這個屬性排在第二位來寫, 由於有點擊就有不可點擊與其相對, 這屬於的最基本的功能.
<button class="cc-button" @touchstart='touchstart($event)' :class="[ type ? 'cc-button--' + type : '', { 'is-disabled':disabled, }]" :type="nativeType" @click="$emit("click")"> <slot /> </button>
disabled: Boolean
禁用樣式的屬性Button.scss改裝
&:not(.is-disabled) { &:active { box-shadow: none; opacity: 0.7; transform: translateX(2px) translateY(2px) scale(0.9); } &:hover { background-color:rgba(0,0,0,0.06) } } @include when(disabled) { @include commonShadow(disabled); }
1: 只有在不是禁用狀態的時候, 纔有點擊效果, 懸停效果
2: 當disabled時, 才顯示disabled的專屬皮膚
when函數
@mixin when($state) { @at-root { &.#{$state-prefix + $state} { @content; } } }
1: 見名知意, 當什麼什麼的時候, 用到了@at-root 屬性, 忘了的去上面看下, @content;表示的是類裏面的樣式內容,很神奇吧!
.box{ color:red; }
1: 上面的color:red; 就是@content;
2: 因此說這個函數就是一個命名函數, 能夠抽象出前綴, 並且是在{}外的平級樣式.
3: 禁用狀態有cursor: not-allowed;屬性, 讓鼠標呈現禁用狀態
左中右按鈕 (文章字數寫多了好卡)
<template> <button class="cc-button" @touchstart='touchstart($event)' :class="[ type ? 'cc-button--' + type : '', { 'is-left':left, 'is-right':right, 'is-centre':centre, 'is-disabled':disabled, }]" :type="nativeType" @click="click"> <slot /> </button> </template>
樣式:
@include when(left) { border-radius: 16px 0 0 16px; } ; @include when(right) { border-radius: 0 16px 16px 0; } ; @include when(centre) { border-radius: 0; }
無非是調了一下圓角, 可是特別好玩
效果以下⬇️
按鈕大小
這個不少ui庫都有時間, 那我也實現一下吧, 感受通常般.
:class="[ sizeType, // 新加一個屬性 type ? 'cc-button--' + type : '', { 'is-left':left, 'is-right':right, 'is-centre':centre, 'is-disabled':disabled, }]" props: { size: { typr: String, default: "normal" } } computed: { sizeType() { let sizeList = ["big", "small"]; if (sizeList.includes(this.size)) return "size-" + this.size; return "size-normal"; } }
&.size-big { font-size: $--size-big; padding: 6px 11px; } &.size-normal { font-size: $--size-nomal; padding: 4px 8px; } &.size-small { font-size: $--size-small; padding: 2px 6px; }
未完待續