给你的文章打个星星
前言
在很多的视频网站和电影网站上,我们都会关注到一个元素——评分,有的时候,我们会在观影和观看后给予评分,而这些评分方式就是让我们评星级,这篇文章就教你怎么用星星去点击评分。
vue的星星组件
- HTML 结构与样式
- 首先,我们创建一个包含两个嵌套
<span>
元素的<div>
,分别代表实心星星和空心星星。当用户将鼠标悬停在星星上时,会触发相应的事件处理器(@mouseover
),改变星星的样式。此外,我们还添加了一些基本的样式,如.rate
的相对定位和.rate > span.hollow
的绝对定位,以便于实现星星的交互效果。
<template>
<div :style="fontStyle">
<div class="rate" @mouseout="mouseOut">
<span @mouseover="mouseOver(num)" v-for="num in 5" :key="num">☆</span>
<span class="hollow" :style="fontwidth">
<span @click="onRate(num)" @mouseover="mouseOver(num)" v-for="num in 5" :key="num">★</span>
</span>
</div>
</div>
<div>{{ width }}分</div>
</template>
<style>
.rate {
position: relative;
display: inline-block;
}
.rate span {
display: inline-block;
width: 1rem;
height: 22px;
overflow: hidden;
}
.rate > span.hollow {
position: absolute;
display: inline-block;
top: 0;
left: 0;
width: 0;
overflow: hidden;
}
</style>
- 数据处理与计算属性
- 接下来,我们处理数据并设置计算属性以获取当前评分的颜色和宽度:
<script setup>
import { ref, defineProps, computed } from 'vue';
let props = defineProps({
value: Number,
theme: { type: String, default: 'orange' },
});
let width = ref(props.value);
let fontwidth = computed(() => `width: ${width.value}em;`);
let themeObj = {
orange: '#fa541c',
blue: '#40a9ff',
green: '#73d13d',
black: '#000',
red: '#f5222d',
yellow: '#fadb14',
};
const fontStyle = computed(() => {
return `color: ${themeObj[props.theme]}`;
});
这里,我们使用 ref()
创建了一个名为 width
的响应式变量,用于存储当前评分的宽度。然后,我们定义了一个计算属性 fontwidth
来获取星星的宽度。另外,我们还创建了一个对象 themeObj
,其中包含了各种颜色主题对应的十六进制颜色码。接着,我们定义了一个计算属性 fontStyle
,用于返回当前颜色主题所对应的颜色。
- 事件处理
- 在组件中,我们需要处理鼠标悬停和点击事件,并更新评分:
const onRate = (num) => {
// 更新评分
width.value = num;
};
function mouseOver(i) {
// 鼠标悬停时改变宽度
width.value = i;
}
function mouseOut() {
// 鼠标移开时恢复原评分
width.value = props.value;
}
这些函数负责处理鼠标悬停和离开星星时的事件。onRate
函数用于更新评分,而 mouseOver
和 mouseOut
函数则用于更改或恢复星星的宽度。
- 父子组件通信
- 为了实现父子组件间的通信,我们需要定义一个自定义事件并在子组件中触发它:
import { defineEmits } from 'vue';
let emits = defineEmits(["update-rate"]);
const onRate = (num) => {
// 触发自定义事件
emits("update-rate", num);
};
在这里,我们导入了 defineEmits
并将其赋值给 emits
变量。这样,在 onRate
函数中,我们就可以调用 emits("update-rate", num)
来触发一个名为 update-rate
的自定义事件,并传入新的评分值。
- 完整组件代码
- 现在,我们将所有的代码整合在一起:
<template>
<div :style="fontStyle">
<div class="rate" @mouseout="mouseOut">
<span @mouseover="mouseOver(num)" v-for="num in 5" :key="num">☆</span>
<span class="hollow" :style="fontwidth">
<span @click="onRate(num)" @mouseover="mouseOver(num)" v-for="num in 5" :key="num">★</span>
</span>
</div>
</div>
<div>{{ width }}分</div>
</template>
<script setup>
import { ref, defineProps, computed, defineEmits } from 'vue';
let props = defineProps({
value: Number,
theme: { type: String, default: 'orange' },
});
let width = ref(props.value);
let fontwidth = computed(() => `width: ${width.value}em;`);
let themeObj = {
orange: '#fa541c',
blue: '#40a9ff',
green: '#73d13d',
black: '#000',
red: '#f5222d',
yellow: '#fadb14',
};
const fontStyle = computed(() => {
return `color: ${themeObj[props.theme]}`;
});
const emits = defineEmits(["update-rate"]);
const onRate = (num) => {
emits("update-rate", num);
};
function mouseOver(i) {
width.value = i;
}
function mouseOut() {
width.value = props.value;
}
</script>
<style>
.rate {
position: relative;
display: inline-block;
}
.rate span {
display: inline-block;
width: 1rem;
height: 22px;
overflow: hidden;
}
.rate > span.hollow {
position: absolute;
display: inline-block;
top: 0;
left: 0;
width: 0;
overflow: hidden;
}
</style>
- 使用组件
- 最后,我们可以将这个组件引入到我们的应用中,并设置不同的颜色主题和初始评分:
<template>
<div>
<Rate :value="score" theme="yellow" @update-rate="update" />
</div>
</template>
<script setup>
import Rate from './components/Rate1.vue';
let score = ref(3);
function update(num) {
score.value = num;
}
</script>
- 这是实现的效果
总结
- 在这个示例中,我们展示了如何使用Vue.js创建一个具有颜色主题定制功能的动态评分星星组件。通过计算属性和事件处理,我们可以轻松地控制组件的行为和外观。同时,我们也实现了父子组件之间的通信,使得组件更加灵活和易于扩展。
转载自:https://juejin.cn/post/7389633157500354600