07- Vue3 UI Framework - Switch 元件

Jeremy.Wu發表於2021-12-15

為了更好的提升使用者體驗,我們這裡再做一個很常用的開關元件 switch

返回閱讀列表點選 這裡

需求分析

開始之前我們先做一個簡單的需求分析

  1. switch 元件應分為選中/未被選中,兩種狀態
  2. 可以通過點選變更選中狀態
  3. 不同的選中狀態有不同的顏色,且有滑塊處於不同的端
  4. 可以指定不同的尺寸
  5. 可以自定義顏色
  6. 可以設定為禁用

那麼可以整理出以下參數列格

引數 含義 型別 可選值 預設值
value 預設選擇狀態 boolean false / true false
size 尺寸 string middle / small / large middle
color 顏色 string 任意合法顏色值 #8c6fef
disabled 是否禁用 boolean false / true false

骨架

這裡我們可以參考 button 元件,因為 switch 元件具有和 button 元件一樣的”點選”之功能,所以這裡可以直接使用 button 標籤來實現,然後再用一個 div 來充當滑塊,很容易得到如下骨架:

<template>
  <button
    @click="toggle"
    class="jeremy-swicth"
    :class="{ active: value }"
    :size="size"
    :style="{ '--color': color }"
    :disabled="disabled"
  >
    <div></div>
  </button>
</template>

功能

首先,我們再 Typescript 中宣告一些需求分析中的屬性:

declare const props: {
  value: boolean;
  size?: "middle" | "small" | "large";
  color: string;
  disabled: boolean;
};
declare const context: SetupContext;

然後,再在 export default 中寫入宣告的引數:

export default {
  install: function (Vue) {
    Vue.component(this.name, this);
  },
  name: "JeremySwitch",
  props: {
    value: {
      type: Boolean,
      default: false,
    },
    size: {
      type: String,
      default: "middle",
    },
    color: {
      type: String,
      default: "#8c6fef",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
};

最後,再補全 setup 方法:

  setup(props, context) {
    const toggle = () => {
      context.emit("update:value", !props.value);
    };
    return { toggle };
  },

樣式表

補全層疊樣式表:

<style lang="scss">
@mixin layout($r, $d) {
  $r2: $r - $d;
  display: inline-block;
  position: relative;
  border: none;
  background: #adadad;
  outline: none;
  transition: background-color 250ms;
  cursor: pointer;
  :focus {
    outline: none;
  }
  > div {
    position: absolute;
    background: white;
    border-radius: 50%;
    transition: left 250ms;
    height: $r2;
    width: $r2;
    top: $d/2;
    left: $d/2;
  }
  height: $r;
  width: $r * 2;
  border-radius: $r / 2;
  &.active {
    background: var(--color);
    > div {
      left: calc(100% - #{$r2} - #{$d/2});
    }
  }
}
$r: 20px;
$d: 4px;
.jeremy-swicth[size="small"] {
  @include layout($r, $d);
}
.jeremy-swicth[size="middle"] {
  @include layout($r * 1.5, $d * 1.5);
}
.jeremy-swicth[size="large"] {
  @include layout($r * 2, $d * 2);
}
.jeremy-swicth[disabled] {
  cursor: not-allowed;
}
</style>

測試

建立一個測試頁,匯入 JeremySwitch 元件,看一下效果:

switch

專案地址 ?

GitHub: https://github.com/JeremyWu917/jeremy-ui

官網地址 ?

JeremyUI: https://ui.jeremywu.top

感謝閱讀 ☕

相關文章