实现效果
主要代码
/* 列表部分的代码封装成组件 */
<script setup lang="ts">
import { ref, reactive } from "vue";
const props = defineProps({
hotListData: {
type: Array,
require: true,
},
});
</script>
<template>
<ul>
<li
class="list-item"
v-for="(item, index) in props.hotListData"
:key="item.id"
>
<span>
{{ item.torur }}
</span>
<span>{{ item.count }}</span>
<el-progress
:text-inside="true"
:stroke-width="16"
:percentage="item.percent"
:color="item.color"
class="list-item-progress"
/>
</li>
</ul>
</template>
<style scoped lang="scss">
.list-item {
display: flex;
justify-content: space-around;
margin-top: 10px;
span {
display: inline-block;
width: 100px;
white-space: nowrap; /* 确保文本在一行内显示 */
overflow: hidden; /* 隐藏溢出的内容 */
text-overflow: ellipsis; /* 使用省略号表示溢出的文本 */
}
.list-item-progress {
width: 120px;
}
}
</style>
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from "vue";
/* 将封装好的组件引入 */
import hotList from "@/components/hotList/index.vue";
/* 定义传入的数据 一般此数据是接口返回的,此处我们自己定义了一个数据 */
const hotListData = ref([
{
id: 1,
torur: "峨眉山",
percent: 80,
count: "8.00w",
color: "rgb(51, 133, 234)",
},
{
id: 2,
torur: "稻城亚丁",
percent: 60,
count: "6.00w",
color: "rgb(239, 134, 117)",
},
{
id: 3,
torur: "九寨沟",
percent: 50,
count: "5.00w",
color: "rgb(106, 196, 226)",
},
{
id: 4,
torur: "万里长城",
percent: 40,
count: "4.00w",
color: "rgb(243, 181, 86)",
},
{
id: 5,
torur: "玉泉山",
percent: 37.8,
count: "3777",
color: "rgb(135, 130, 245)",
},
{
id: 6,
torur: "北京故宫",
percent: 30,
count: "3.00w",
color: "rgb(135, 130, 245)",
},
{
id: 7,
torur: "北京故宫1",
percent: 30,
count: "3.00w",
color: "rgb(135, 130, 245)",
},
{
id: 8,
torur: "北京故宫2",
percent: 30,
count: "3.00w",
color: "rgb(135, 130, 245)",
},
{
id: 9,
torur: "北京故宫3",
percent: 30,
count: "3.00w",
color: "rgb(135, 130, 245)",
},
{
id: 10,
torur: "北京故宫4",
percent: 30,
count: "3.00w",
color: "rgb(135, 130, 245)",
},
]);
/* 定义 通过ref获取dom元素的变量 */
const hotlistRef = ref();
/* 定义滚动时间的变量 方便后续计算 */
const scrollTime = ref(10);
/* 通过计算属性进行拼接值(css中animation的持续时间的值) */
const animationTime = computed(() => `${scrollTime.value}ms`);
/* 是否需要第二个列表 */
const isNeedScroll = ref(true);
/* 动态获取列表的高度及计算animation的持续时间*/
const setScroll = () => {
const height = hotlistRef.value.$el.clientHeight;
scrollTime.value = height * 50;
//5000s 5000ms
};
/* 一进入页面调用 setScroll方法*/
onMounted(() => {
setScroll();
});
</script>
<template>
<div class="screen-right-hot-list">
<div :class="{ 'scroll-box': isNeedScroll }">
<hotList :hotListData="hotListData" ref="hotlistRef"></hotList>
<hotList :hotListData="hotListData" v-if="isNeedScroll"></hotList>
</div>
</div>
</template>
<style scoped lang="scss">
.screen-right-hot-list {
height: 200px;
width: 300px;
margin: 100px auto;
overflow: hidden;
background-color: #fff;
padding-right: 10px;
.scroll-box {
/* animation:动画名称 持续时间 匀速 循环 */
/* css中使用v-bind是vue3的语法 */
animation: scrolltop v-bind(animationTime) linear infinite;
}
/* 定义动画怎么动(关键帧)*/
@keyframes scrolltop {
/* 0% 开始位置 */
0% {
transform: translateY(0);
}
/* 100% 结束位置 沿着y轴向上平移50% 正值向下 负值向上 */
100% {
transform: translateY(-50%);
}
}
}
</style>