iT邦幫忙

2024 iThome 鐵人賽

DAY 8
0
Modern Web

蓋一個自己的 Nuxt 3 UI Module系列 第 8

元件製作 switch

  • 分享至 

  • xImage
  •  

今天來說說 switch 這個開關~

沒想到一個表單的勾選狀態可以有三種不同的情境 :P

switch 的基底其實就是前兩天所說的 <input type=”checkbox”>或是 <input type=”radio”>

一般用於使用者開關狀態使用,適用於當選項只有二擇一,且兩者性質迥異的狀態 ( 比如 ture 或 false )

在視覺上的意象相對明確,跟 checkbox 和 radio 不同的是 switch 點擊後會立即有動作回饋。

但不像 checkbox 和 radio 選項跟敘述是連結在一起的,能呈現更多元的資訊,switch 在處理選項並非開或關、是或否的狀態時會比較苦手

開始實作前一樣先想想 switch 會有哪些狀態吧 🤔

  1. 關閉
  2. 開啟
  3. 禁止選取

實作

  • 這裡我將 switch 定義為 true 或 false 兩種狀態

<script lang="ts" setup>
export interface SwitchPropsType {
  /** 標籤文字 */
  label?: string
  /** 預設是否開啟 */
  active?: boolean
  /** 是否禁用 */
  disabled?: boolean
  /** name 連動 name 與 id */
  name?: string
  /** 響應式傳值 */
  modelValue?: boolean
}

type EmitsEvent = (e: 'update:modelValue', value: boolean) => void

const emits = defineEmits<EmitsEvent>()

const props = withDefaults(defineProps<SwitchPropsType>(), {
  label: '',
  name: ''
})

const ck = ref<boolean>(props.modelValue)

const onChange = (): void => {
  ck.value = !ck.value
}

const localValue = computed({
  get: () => props.modelValue,
  set: (newValue) => {
    emits('update:modelValue', newValue)
  }
})

</script>

<template>
  <div>
    <label
      class="flex items-start"
      :class="disabled ? ' cursor-not-allowed opacity-40' : 'cursor-pointer'"
    >
      <input
        v-model="localValue"
        type="checkbox"
        class="hidden"
        :disabled="disabled"
        @change="onChange"
      >
      <div
        :class="ck ? 'bg-primary-600' : 'bg-slate-500'"
        class="relative inline-flex h-6 w-[46px] items-center rounded-full transition-all duration-150 mr-3"
      >
        <span
          :class="
            ck
              ? 'translate-x-6 '
              : 'translate-x-[2px]'
          "
          class="inline-block size-5 rounded-full bg-white transition-all duration-150"
        />
      </div>

      <span
        v-if="label"
        class="text-sm leading-6 text-slate-500"
      >
        {{ label }}
      </span>
    </label>
  </div>
</template>
  • 最後出來的樣子如下~
<script setup lang="ts">

const switch1 = ref(true)
const switch2 = ref(false)
const switch3 = ref(true)
const switch4 = ref(false)

</script>

<template>
  <div class="relative">
    <div class="flex flex-col text-xl gap-4 mb-4">
      <h3>SWitch 狀態</h3>
      <div class="flex flex-wrap gap-4">
          <Switch
            v-model="switch1"
            label="Active Switch"
            class="mb-5"
          />
          <Switch
            v-model="switch2"
            label="Inactive Switch"
            class="mb-5"
          />
          <Switch
            v-model="switch3"
            label="Disabled Active Switch"
            disabled
            class="mb-5"
          />
          <Switch
            v-model="switch4"
            label="Disabled Active Switch"
            disabled
            class="mb-5"
          />
      </div>
    </div>
  </div>
</template>


上一篇
元件製作 radio
下一篇
元件製作 tab
系列文
蓋一個自己的 Nuxt 3 UI Module30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言