Vue Rating Component

Rating

CoreUI PRO
This component is part of CoreUI PRO – a powerful UI library with over 250 components and 25+ templates, designed to help you build modern, responsive apps faster. Fully compatible with Angular, Bootstrap, React.js, and Vue.js.

A Vue star rating component allows users to rate and provide feedback on content or products by selecting a specified number of stars, typically ranging from one to five, representing their level of satisfaction or preference.

Available in Other JavaScript Frameworks

CoreUI Vue Rating Component is also available for Angular, Bootstrap, and React. Explore framework-specific implementations below:

How to use Vue Rating Component.

Embed the Rating component in your Vue application like this:

vue
<template>
  <CRating :value="3" />
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

vModel

vue
<template>
  <CRating v-model="selected" />
  <div class="mt-3">Selected value: {{ selected }}</div>
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

Allow clear

Enable users to clear their selected rating by clicking on the current rating again. This functionality is activated by setting allowClear boolean property.

vue
<template>
  <CRating allowClear :value="3" />
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

Resettable

This allows the selected rating to be deselected, effectively resetting the rating to a state where no value is selected.

vue
<template>
  <div class="d-flex align-items-center">
    <CRating @change="(value) => setCurrentValue(value)" :value="currentValue" />
    <CButton class="ms-3" color="primary" @click="setCurrentValue(null)">reset</CButton>
  </div>
</template>

<script setup>
import { CRating, CButton } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

Read only

Set the Vue rating component to read-only by adding readOnly property. This disables interaction, preventing users from changing the displayed rating value.

vue
<template>
  <CRating readOnly :value="3" />
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

Disabled

Add the disabled boolean property to give it a grayed out appearance, remove pointer events, and prevent focusing.

vue
<template>
  <CRating disabled :value="3" />
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

Tooltips

Enable descriptive text on hover by adding tooltips prop. This provides immediate feedback or guidance as the user interacts with the rating items.

vue
<template>
  <CRating tooltips :value="3" />
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

For custom messages, provide an array of labels corresponding to each rating value to enhance the user’s understanding of each rating level.

vue
<template>
  <CRating :tooltips="['Very bad', 'Bad', 'Meh', 'Good', 'Very good']" :value="3" />
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

Sizes

Larger or smaller vue rating component? Add size="lg" or size="sm" for additional sizes.

vue
<template>
  <CRating size="sm" :value="3" />
  <CRating :value="3" />
  <CRating size="lg" :value="3" />
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

Precision

Adjust the granularity of the Rating component by setting precision prop. This attribute allows for fractional ratings, such as quarter values, to provide more precise feedback.

vue
<template>
  <CRating :precision="0.25" :value="3" />
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

Number of items

Control the total number of rating items displayed by using itemCount property. You can create a Vue rating component with a custom scale, be it larger for detailed assessments or smaller for simplicity.

vue
<template>
  <CRating :itemCount="20" :value="5" />
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>
vue
<template>
  <CRating :itemCount="3" :value="1" />
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

Custom icons

Customize the Vue rating component with your choice of SVG icons by assigning new values to the activeIcon and icon properties in the JavaScript options. This allows for a unique look tailored to the design language of your site or application.

The Rating component can be customized with either SVG or font icons, allowing for visual alignment with your application’s design. You can specify different icons for each rating value to enhance user interaction.

In the example below, we demonstrate how to set custom icons using SVG, allowing for detailed customization of the visual elements within the Rating component.

vue
<template>
  <CRating :value="3">
    <template #activeIcon>
      <CIcon :icon="cisStar" customClassName=" " />
    </template>
    <template #icon>
      <CIcon :icon="cilStar" customClassName=" " />
    </template>
  </CRating>
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { CIcon } from '@coreui/icons-vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

In the example below, we use font icons from the CoreUI Icons set. In the activeIcon configuration, we also apply the utility class text-danger to change the icon’s color to red when it is active.

vue
<template>
  <CRating :value="3">
    <template #activeIcon>
      <CIcon :icon="cilHeart" customClassName="text-danger" />
    </template>
    <template #icon>
      <CIcon :icon="cilHeart" customClassName=" " />
    </template>
  </CRating>
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { CIcon } from '@coreui/icons-vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

For a more dynamic experience, define different icons for each rating value, enhancing the visual feedback:

vue
<template>
  <CRating
    highlightOnlySelected
    :tooltips="['Very bad', 'Bad', 'Meh', 'Good', 'Very good']"
    :value="3"
  >
    <template #icon="{ value }">
      <CIcon :icon="icons[value].icon" :customClassName="icons[value].customClassName" />
    </template>
    <template #activeIcon="{ value }">
      <CIcon
        :icon="activeIcons[value].icon"
        :customClassName="activeIcons[value].customClassName"
      />
    </template>
  </CRating>
</template>

<script setup>
import { CRating } from '@coreui/vue'
import { CIcon } from '@coreui/icons-vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>

Custom feedback

The Vue Rating component integrates interactive star ratings with dynamic textual feedback using other components from CoreUI. It enables users to select a rating that updates the display and label in real-time, enhancing the interactive experience. Hover effects provide immediate feedback on potential ratings before selection, ensuring an intuitive user interface.

vue
<template>
  <div class="d-flex align-items-center">
    <div class="text-body-secondary me-3">{{ currentValue }} / 5</div>
    <CRating
      class="d-inline-flex"
      :value="currentValue"
      @change="(value) => setCurrentValue(value)"
      @hover="(value) => setLabel(value ? labels[value] : labels[currentValue])"
    />
    <CBadge v-if="label" class="ms-3" color="dark">{{ label }}</CBadge>
  </div>
</template>

<script setup>
import { CRating, CBadge } from '@coreui/vue'
import { ref } from 'vue'
import {
  cilStar,
  cisStar,
  cilHeart,
  cilMoodVeryBad,
  cilMoodBad,
  cilMoodGood,
  cilMoodVeryGood,
  cilMeh,
} from '@coreui/icons-pro'
const selected = ref(2)
const currentValue = ref(3)
const setCurrentValue = (value) => {
  currentValue.value = value
}
const icons = {
  1: { icon: cilMoodVeryBad, customClassName: ' ' },
  2: { icon: cilMoodBad, customClassName: ' ' },
  3: { icon: cilMeh, customClassName: ' ' },
  4: { icon: cilMoodGood, customClassName: ' ' },
  5: { icon: cilMoodVeryGood, customClassName: ' ' },
}
const activeIcons = {
  1: { icon: cilMoodVeryBad, customClassName: 'text-danger-emphasis' },
  2: { icon: cilMoodBad, customClassName: 'text-danger' },
  3: { icon: cilMeh, customClassName: 'text-warning' },
  4: { icon: cilMoodGood, customClassName: 'text-success' },
  5: { icon: cilMoodVeryGood, customClassName: 'text-success-emphasis' },
}
const labels = {
  1: 'Very bad',
  2: 'Bad',
  3: 'Meh',
  4: 'Good',
  5: 'Very good',
}
const label = ref(labels[3])
const setLabel = (_label) => {
  label.value = _label
}
</script>