點燈坊

失くすものさえない今が強くなるチャンスよ

Tailwind CSS 與 Class Binding

Sam Xiao's Avatar 2021-01-05

Tailwind 的 Utility 其實就是一堆預先定義好的 CSS Class,若要能根據 State 動態改變 Utility 使其 Reactive,就要使用 Vue 的 Class Binding。

Version

Vue 2.6.11
Tailwind 1.9.0

String

class000

Tailwind Rocks 使用 Tailwind 的 text-3xltext-red-600 utility。

<template>
  <div :class="title">Tailwind Rocks</div>
</template>

<script>
export default {
  data: () => ({
    title: 'text-3xl text-red-600'
  })
}
</script>

第 2 行

<div :class="title">Tailwind Rocks</div>

並沒有在 class attribute 直接使用 text-red-600,而是綁定到 title state。

第 7 行

data: () => ({
  title: 'text-3xl text-red-600'
})

title state 以 text-3xltext-red-600 組合成 String。

Object

class000

也可將 class attribute 綁定到 Object。

<template>
  <div :class="title">Tailwind Rocks</div>
</template>

<script>
export default {
  data: () => ({
    title: {
      'text-3xl': true,
      'text-red-600': true
    }
  })
}
</script>

第 7 行

data: () => ({
  title: {
    'text-3xl': true,
    'text-red-600': true
  }
})

title state 改用 Object,將 utility 寫在 key,若 value 為 true 則啟用該 utility,可藉由此控制 utility 的 enable 與 disable。

Object Computed

class000

若要最靈活,可將直接將 class attribute 綁定到 computed。

<template>
  <div :class="title">Tailwind Rocks</div>
</template>

<script>
let title = () => ({
  'text-3xl': true,
  'text-red-600': true
})

export default {
  computed: {
    title
  }
}
</script>

第 6 行

let title = () => ({
  'text-3xl': true,
  'text-red-600': true
})

title() 直接回傳 Object 即可。

Point-free

class000

也可將 title computed 以 Function Pipeline 組合。

<template>
  <div :class="title">Tailwind Rocks</div>
</template>

<script>
import { pipe, always, zipObj } from 'ramda'

let title = pipe(
  always([true, true]),
  zipObj(['text-3xl', 'text-red-600'])
)

export default {
  computed: {
    title
  }
}
</script>

第 8 行

let title = pipe(
  always([true, true]),
  zipObj(['text-3xl', 'text-red-600'])
)

使用 pipe() 組合 utility:

  • always() 組合 value 部分,也就是 enable 與 disable
  • zipObj() 組合 utility 部分

Array

class001

也可將 class 綁定到 Array。

<template>
  <div :class="title">Tailwind Rocks</div>
</template>

<script>
export default {
  data: () => ({
    title: ['text-3xl', 'text-red-600']
  }),
}
</script>

第 7 行

data: () => ({
  title: ['text-3xl', 'text-red-600']
}),

title state 以 Array 提供 utility。

Object Array

class000

也可將 class 綁定到 Object Array。

<template>
  <div :class="title">Tailwind Rocks</div>
</template>

<script>
export default {
  data: () => ({
    title: [
      { 'text-3xl': true },
      { 'text-red-600': true }
    ]
  }),
}
</script>

第 7 行

data: () => ({
  title: [
    { 'text-3xl': true },
    { 'text-red-600': true }
  ]
}),

title state 改用 Object Array,將 utility 寫在 Object 的 key,若 value 為 true 則啟用該 utility,可藉由此控制 utility 的 enable 與 disable。

Array Computed

class001

也可將 class attribute 綁定到 computed,如此可用 function 更加靈活。

<template>
  <div :class="title">Tailwind Rocks</div>
</template>

<script>
let title = () => [
  'text-3xl', 
  'text-red-600'
]

export default {
  computed: {
    title
  }
}
</script>

第 6 行

let title = () => [
  'text-3xl',
  'text-red-600'
]

title() 直接回傳 Array 即可。

Point-free

class001

也可將 title computed 以 Function Pipeline 組合。

<template>
  <div :class="title">Tailwind Rocks</div>
</template>

<script>
import { always } from 'ramda'

let title = always([
  'text-3xl',
  'text-red-600'
])

export default {
  computed: {
    title
  }
}
</script>

第 8 行

let title = always([
  'text-3xl',
  'text-red-600'
])

既然 title computed 為 function,就可使用 Ramda 組合使其 Point-free。

Conclusion

  • 可將 utility 組合成 String、Object、Array 或 Object Array,搭配 computed 後更可以 Ramda 之 function 組合之,可視需求靈活運用

Reference

Vue, Class and Style Binding