如何在 JS switch 语句中使用动态 tailwind 类并在 Vue 中正确传递它们?

问题描述 投票:0回答:3

我是 Vue JS 的初学者,我正在尝试创建一个函数来为订单状态分配相应的颜色。我想使用 switch 语句来实现这一点,它将获取订单状态的值并将其传递给 getStatusColour 函数(),如下所示:

const getStatusColour = (orderStatus) => {
    let statusColour = "";
    switch (orderStatus) {
        case "new": 
            statusColour = "bg-green-100 text-green-900";
            break;
        case "preparing": 
            statusColour =  "bg-yellow-400 text-yellow-900";
            break;
        case "ready":
            statusColour = "bg-blue-200 text-blue-800";
            break;
        case "delivered":
            statusColour = "bg-green-300 text-green-800";
            break;
        case "failed": 
            statusColour = "bg-red-400 text-red-900";
            break;
        default:
            statusColour = "bg-gray-100 text-gray-800"
    }
    return statusColour;
}

然后在

Index.vue
文件中我有
export default { getStatusColour }
,我想这应该是一个错误。

然后在模板中我这样称呼它:

<span :class="getStatusColour(order.status)">{{ order.status }}</span>

但我不断收到

Uncaught (in promise) TypeError: _ctx.getStatusColour is not a function
错误。我将不胜感激这里的任何帮助。

javascript vue.js switch-statement tailwind-css
3个回答
6
投票

如 MDN 文档所示:https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export#using_named_exports


这是整个 github 代码库。

utils/test.js

const getStatusColour = (orderStatus) => {
  let statusColour = ''
  switch (orderStatus) {
    case 'new':
      statusColour = 'bg-green-100 text-green-900'
      break
    case 'preparing':
      statusColour = 'bg-yellow-400 text-yellow-900'
      break
    case 'ready':
      statusColour = 'bg-blue-200 text-blue-800'
      break
    case 'delivered':
      statusColour = 'bg-green-300 text-green-800'
      break
    case 'failed':
      statusColour = 'bg-red-400 text-red-900'
      break
    default:
      statusColour = 'bg-gray-100 text-gray-800'
  }
  return statusColour
}

export { getStatusColour }

App.vue

<template>
  <div>
    <div :class="getStatusColour(order.status)">
      This div do have the correct: `bg-green-100 text-green-900` on it
    </div>
  </div>
</template>

<script>
import { getStatusColour } from './utils/test'

export default {
  data() {
    return {
      order: {
        status: 'new',
      },
    }
  },
  methods: {
    getStatusColour,
  },
}
</script>

这里有一个 github 存储库,表明您的代码到目前为止运行良好:https://github.com/kissu/so-compute-exported-function


我个人是如何处理这种流程的

callToAction.vue

<button
  class="flex items-center w-auto p-4 text-center ..."
  :class="[
    callToAction.types[color][variant],
    { 'opacity-50 cursor-not-allowed shadow-none': disabled },
  ]"
>
  Nice flexible button
</button>

<script>
export default {
props: {
  color: {
    type: String,
    default: 'primary',
  },
  variant: {
    type: String,
    default: 'enabled',
  },
  disabled: {
    type: Boolean,
    default: false,
  },
},

data() {
  return {
    callToAction: {
      types: {
        primary: {
          enabled: 'disabled:bg-primary-500 hover:bg-primary-700 bg-primary-500 text-primary-500',
          outlined: 'hover:bg-primary-a12 text-primary-500',
          reversed: 'text-primary-500',
        },
        secondary: {
          enabled: 'disabled:bg-secondary-500 hover:bg-secondary-700 bg-secondary-500 text-secondary-500',
          outlined: 'hover:bg-secondary-a12 text-secondary-500',
          reversed: 'text-secondary-500',
        },
        tertiary: {
          enabled: 'disabled:bg-tertiary-500 hover:bg-tertiary-700 bg-tertiary-500 text-tertiary-500',
          outlined: 'hover:bg-tertiary-a12 text-tertiary-500',
          reversed: 'text-tertiary-500',
        },
        bluegray: {
          enabled: 'disabled:bg-bluegray-500 hover:bg-bluegray-700 bg-bluegray-500 text-bluegray-500',
          outlined: 'hover:bg-bluegray-a12 text-bluegray-500',
          reversed: 'text-bluegray-500',
        },
        error: {
          enabled: 'disabled:bg-error-500 hover:bg-error-700 bg-error-500 text-error-500',
          outlined: 'hover:bg-error-a12 text-error-500',
          reversed: 'text-error-500',
        },
      },
    },
  }
}
</script>

然后,在其他页面/组件中调用它,例如:

<call-to-action color="tertiary" variant="reversed"></call-to-action>

或者让默认值完成

color="primary"
variant="enabled"
等的工作...

PS:在 props 中添加 validators 可能会很好,对于从事该项目的其他开发人员来说会更加友好,找出可以传递的所有可能的值。


0
投票

kisu 的答案应该可以解决您的问题,但我建议使用计算属性。 这样您可以编写更少的代码,还可以创建一个默认状态,当

color
variant
的输入无效时进行处理。

<button
  class="flex items-center w-auto p-4 text-center ..."
  :class="[
    class_type,
    { 'opacity-50 cursor-not-allowed shadow-none': disabled },
  ]"
>

<script>
export default {
props: {
  color: {
    type: String,
    default: 'primary',
  },
  variant: {
    type: String,
    default: 'enabled',
  },
  disabled: {
    type: Boolean,
    default: false,
  },
},
computed: {
  class_type: function(){
    switch(this.variant)
    case "enabled": 
      return `disabled:bg-${this.color}-500 hover:bg-${this.color}-700 bg-${this.color}-500 text-${this.color}-500`
    case "outlined":
      return `hover:bg-${this.color}-a12 text-${this.color}-500`
    case "reversed": 
      return `text-${this.color}-500`
    default: 
      console.error("you didn't put a proper variant to this component")
  }
}
</script>

0
投票

我认为使用这种方法将帮助您获得在 vue 中将基于状态的动态类添加到 tailwind 所需的结果:

首先,你应该从组件内的 props 获取状态,然后根据状态加载不同的样式:

<script setup>
   const orderStatus = {
      default: 'bg-gray-100 text-gray-800'
      new: 'bg-green-100 text-green-90',
      preparing: 'bg-yellow-400 text-yellow-900',
      ready: 'bg-blue-200 text-blue-800'
   }

   defineProps({
      status: {
         type: String,
         default: orderStatus['default'],
         required: true
      }
   })
</script>

<template>
   <span :class="orderStatus[status]">
      {{ status }}
   </span>
</template>
© www.soinside.com 2019 - 2024. All rights reserved.