name: n-rate description: A rating component for collecting user feedback with customizable icons, colors, and half-star support in Naive UI. Ideal for product reviews, feedback forms, and rating systems. metadata: author: jiaiyan version: 1.0.0
n-rate Component
The n-rate component allows users to provide ratings, typically represented as stars or custom icons. It supports half-star ratings, custom colors, and various sizes.
When to Use
Use n-rate when you need to:
- Product Reviews: Allow users to rate products or services
- Feedback Collection: Gather user satisfaction ratings
- Content Rating: Rate articles, videos, or other content
- Skill Assessment: Display or collect skill level ratings
- Quick Evaluation: Provide a simple, intuitive rating interface
Basic Usage
Basic Rate
A simple 5-star rating component.
<template>
<n-rate v-model:value="rating" />
<p>Rating: {{ rating }}</p>
</template>
<script setup>
import { ref } from 'vue'
const rating = ref(0)
</script>
Different Sizes
Rate supports small, medium, large sizes, or custom numeric sizes.
<template>
<n-space align="center">
<n-rate size="small" v-model:value="small" />
<n-rate size="medium" v-model:value="medium" />
<n-rate size="large" v-model:value="large" />
<n-rate :size="30" v-model:value="custom" />
</n-space>
</template>
<script setup>
import { ref } from 'vue'
const small = ref(3)
const medium = ref(3)
const large = ref(3)
const custom = ref(3)
</script>
Custom Color
Customize the color of active icons.
<template>
<n-space vertical>
<n-rate color="#4fb233" v-model:value="rating1" />
<n-rate color="#f0a020" v-model:value="rating2" />
<n-rate color="rgb(255, 0, 100)" v-model:value="rating3" />
</n-space>
</template>
<script setup>
import { ref } from 'vue'
const rating1 = ref(4)
const rating2 = ref(3)
const rating3 = ref(5)
</script>
Custom Icon
Use custom icons via the default slot.
<template>
<n-rate v-model:value="rating">
<template #default>
<n-icon size="20">
<CashIcon />
</n-icon>
</template>
</n-rate>
</template>
<script setup>
import { ref } from 'vue'
import { CashOutline as CashIcon } from '@vicons/ionicons5'
const rating = ref(3)
</script>
Half Star Rating
Enable half-star precision with allow-half.
<template>
<n-rate allow-half v-model:value="rating" />
<p>Rating: {{ rating }}</p>
</template>
<script setup>
import { ref } from 'vue'
const rating = ref(3.5)
</script>
Readonly Mode
Display rating without user interaction.
<template>
<n-space vertical>
<n-rate readonly :value="3" />
<n-rate readonly :value="4.5" allow-half />
<n-rate readonly :value="2" color="#ff6b6b" />
</n-space>
</template>
Clearable
Allow users to clear the rating by clicking on the current value.
<template>
<n-rate clearable allow-half v-model:value="rating" @clear="handleClear" />
<p>Rating: {{ rating }}</p>
</template>
<script setup>
import { ref } from 'vue'
const rating = ref(3.5)
const handleClear = () => {
console.log('Rating cleared')
}
</script>
Custom Count
Set a custom maximum rating value.
<template>
<n-rate :count="10" v-model:value="rating" />
<p>Rating: {{ rating }} / 10</p>
</template>
<script setup>
import { ref } from 'vue'
const rating = ref(7)
</script>
API Reference
n-rate Props
| Name | Type | Default | Description |
|------|------|---------|-------------|
| allow-half | boolean | false | Allow activating half of the icon |
| clearable | boolean | false | Whether the rate is clearable. Clicking on current value resets to null |
| color | string | undefined | Activated icon color. Supports #FFF, #FFFFFF, yellow, rgb(0, 0, 0) formats |
| count | number | 5 | Number of icons (maximum rating) |
| default-value | number \| null | null | Default value of activated icons |
| readonly | boolean | false | Readonly state |
| size | 'small' \| 'medium' \| 'large' \| number | 'medium' | Icon size |
| value | number \| null | undefined | Value of activated icons (controlled mode) |
Events
| Name | Parameters | Description |
|------|------------|-------------|
| on-clear | () => void | Callback when value is cleared |
| on-update:value | (value: number) => void | Callback when the value (rating) changes |
Slots
| Name | Parameters | Description |
|------|------------|-------------|
| default | (info: { index: number }) | Custom icon for the rating. index is the position (0-based) |
Common Patterns
Rate in Form
<template>
<n-form ref="formRef" :model="formData" :rules="rules">
<n-form-item label="Overall Rating" path="rating">
<n-rate allow-half clearable v-model:value="formData.rating" />
<span style="margin-left: 12px">{{ formData.rating || 0 }} / 5</span>
</n-form-item>
<n-form-item label="Service Quality" path="serviceRating">
<n-rate v-model:value="formData.serviceRating" />
</n-form-item>
<n-form-item>
<n-button type="primary" @click="handleSubmit">Submit Review</n-button>
</n-form-item>
</n-form>
</template>
<script setup>
import { ref } from 'vue'
const formData = ref({
rating: null,
serviceRating: 0
})
const rules = {
rating: {
required: true,
type: 'number',
min: 1,
message: 'Please provide a rating',
trigger: 'change'
}
}
const handleSubmit = () => {
console.log('Review submitted:', formData.value)
}
</script>
Display Rating with Text
<template>
<n-space align="center">
<n-rate readonly :value="productRating" allow-half />
<span>{{ productRating.toFixed(1) }}</span>
<span style="color: #999">({{ reviewCount }} reviews)</span>
</n-space>
</template>
<script setup>
const productRating = 4.5
const reviewCount = 128
</script>
Emoji Rating
<template>
<n-rate :count="5" v-model:value="emojiRating">
<template #default="{ index }">
<span style="font-size: 24px">{{ getEmoji(index) }}</span>
</template>
</n-rate>
<p>Selected: {{ getEmojiLabel(emojiRating) }}</p>
</template>
<script setup>
import { ref } from 'vue'
const emojiRating = ref(3)
const emojis = ['😠', '😕', '😐', '😊', '😄']
const labels = ['Very Bad', 'Bad', 'Okay', 'Good', 'Excellent']
const getEmoji = (index) => emojis[index] || '😐'
const getEmojiLabel = (value) => labels[Math.floor(value) - 1] || 'Not rated'
</script>
Rating with Feedback
<template>
<n-space vertical>
<n-rate v-model:value="rating" @update:value="handleRatingChange" />
<n-tag v-if="feedbackText" :type="feedbackType">
{{ feedbackText }}
</n-tag>
</n-space>
</template>
<script setup>
import { ref, computed } from 'vue'
const rating = ref(0)
const feedbackMap = {
1: { text: 'Very Dissatisfied', type: 'error' },
2: { text: 'Dissatisfied', type: 'warning' },
3: { text: 'Neutral', type: 'default' },
4: { text: 'Satisfied', type: 'success' },
5: { text: 'Very Satisfied', type: 'success' }
}
const feedbackText = computed(() => feedbackMap[rating.value]?.text || '')
const feedbackType = computed(() => feedbackMap[rating.value]?.type || 'default')
const handleRatingChange = (value) => {
console.log('Rating changed to:', value)
}
</script>
Best Practices
1. Use Half-Star for Precise Ratings
Enable allow-half when users need to provide more precise ratings:
<template>
<n-rate allow-half v-model:value="rating" />
</template>
2. Provide Clear Feedback
Show the current rating value alongside the component:
<template>
<n-space align="center">
<n-rate v-model:value="rating" />
<span>{{ rating }} / 5</span>
</n-space>
</template>
3. Use Readonly for Display
When displaying existing ratings, use readonly mode:
<template>
<n-rate readonly :value="averageRating" allow-half />
</template>
4. Consider Clearable Option
Allow users to reset their rating when appropriate:
<template>
<n-rate clearable v-model:value="rating" />
</template>
5. Use Custom Colors Wisely
Choose colors that match your design system and are accessible:
<template>
<n-rate color="#18a058" v-model:value="rating" />
</template>
6. Match Size with Context
Use appropriate sizes based on the context:
<template>
<n-space vertical>
<n-rate size="small" v-model:value="compact" />
<n-rate size="medium" v-model:value="standard" />
<n-rate size="large" v-model:value="prominent" />
</n-space>
</template>
7. Validate in Forms
Add validation rules when using in forms:
const rules = {
rating: {
required: true,
type: 'number',
min: 1,
message: 'Please provide a rating',
trigger: 'change'
}
}
Expert Next.js App Router
Developpement
Un skill qui transforme Claude en expert Next.js App Router.
Générateur de README
Developpement
Crée des README.md professionnels et complets pour vos projets.
Rédacteur de Documentation API
Developpement
Génère de la documentation API complète au format OpenAPI/Swagger.