Commit 03511240 by haojie[

1

parent 7410df5f
<!-- 包含卡片的列表 --> <template>
<div class="carousel">
<div
class="cards"
:style="{ transform: `translateX(-${slideIndex * 100}px)` }"
>
<div class="card" v-for="(card, index) in displayCards" :key="index">
<img :src="card.img" alt="" />
<!-- 在这里放置卡片的内容 -->
</div>
<div
class="card"
v-for="(card, index) in cloneCards.slice(0, displayNum)"
:key="'c' + index"
>
<img :src="card.img" alt="" />
<!-- 在这里放置卡片的内容 -->
</div>
</div>
<div class="nav-buttons">
<button @click="prevCard">上一页</button>
<button @click="nextCard">下一页</button>
</div>
</div>
</template>
<script>
import { ref, onMounted } from "vue";
export default {
setup() {
// 初始卡片数量和选中的卡片索引
const cardNum = 10;
const slideIndex = ref(0);
// 用 ref 保存当前显示的卡片数组和克隆数组
const cards = ref([
{
img: "https://img95.699pic.com/photo/50136/1351.jpg_wh300.jpg",
},
{
img: "https://img95.699pic.com/photo/50136/1351.jpg_wh300.jpg",
},
{
img: "https://img95.699pic.com/photo/50136/1351.jpg_wh300.jpg",
},
{
img: "https://img95.699pic.com/photo/50136/1351.jpg_wh300.jpg",
},
{
img: "https://static.runoob.com/images/demo/demo3.jpg",
},
]);
const cloneCards = ref([]);
const displayNum = ref(4);
const displayCards = ref([]);
// 用 ref 保存是否处于动画状态、是否停止轮播
const isAnimating = ref(false);
const stopPlaying = ref(false);
onMounted(() => {
console.log("我执行了");
// 克隆第一个和最后一个卡片,用于无限滚动
cloneCards.value = cards.value.concat(
cards.value.slice(0, displayNum.value)
);
// 显示指定数量的卡片
displayCards.value = cloneCards.value.slice(
slideIndex.value,
slideIndex.value + displayNum.value
);
// 自动播放
let autoPlay = setInterval(() => {
if (!stopPlaying.value) {
nextCard();
}
}, 3000);
let card_el = document.querySelector(".cards .card");
const cardsEl = document.querySelector(".cards");
if (card_el && cardsEl) {
// 获取卡片宽度和最大索引
const cardWidth = card_el.offsetWidth;
cardsEl.style.width = `${cardWidth * cloneCards.value.length}px`;
// 鼠标悬停停止
cardsEl.addEventListener("mouseenter", () => {
stopPlaying.value = true;
clearInterval(autoPlay);
});
cardsEl.addEventListener("mouseleave", () => {
stopPlaying.value = false;
autoPlay = setInterval(() => {
if (!stopPlaying.value) {
nextCard();
}
}, 3000);
});
}
});
//
const prevCard = () => {
const nextIndex = slideIndex.value - displayNum.value;
if (nextIndex < 0 || isAnimating.value) {
return;
}
isAnimating.value = true;
setTimeout(() => {
slideIndex.value = nextIndex;
isAnimating.value = false;
}, 500);
};
const nextCard = () => {
const nextIndex = slideIndex.value + displayNum.value;
if (
nextIndex > cloneCards.value.length - displayNum.value ||
isAnimating.value
) {
return;
}
isAnimating.value = true;
setTimeout(() => {
slideIndex.value = nextIndex;
isAnimating.value = false;
}, 500);
};
return {
displayCards,
prevCard,
nextCard,
cloneCards,
slideIndex,
displayNum,
};
},
};
</script>
<style lang="less">
.carousel {
width: 800px;
height: 400px;
overflow: hidden;
box-sizing: border-box;
.cards {
display: flex;
transition: all 0.5s ease-in-out;
}
.card {
width: 200px;
height: 200px;
img {
width: 200px;
height: 200px;
}
}
.nav-buttons {
position: absolute;
top: 50%;
transform: translateY(-50%);
display: flex;
button {
margin: 0 10px;
}
}
}
</style>
\ No newline at end of file
...@@ -9,12 +9,12 @@ ...@@ -9,12 +9,12 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Input as TInput, Button as TButton } from 'tdesign-vue-next'; import { Input as TInput, Button as TButton } from "tdesign-vue-next";
import { EventSourcePolyfill } from 'event-source-polyfill'; import { EventSourcePolyfill } from "event-source-polyfill";
import { submitmessage } from '@/utils/api/gpt'; import { submitmessage } from "@/utils/api/gpt";
import { getUserCookie } from '@/utils/api/userApi'; import { getUserCookie } from "@/utils/api/userApi";
import { ref } from 'vue'; import { ref } from "vue";
const gpt_input = ref(''); const gpt_input = ref("");
// 提交消息 // 提交消息
const submit = async () => { const submit = async () => {
try { try {
...@@ -23,7 +23,7 @@ const submit = async () => { ...@@ -23,7 +23,7 @@ const submit = async () => {
regen: false, regen: false,
}); });
if (res.code == 0 && res.data.chat_id) { if (res.code == 0 && res.data.chat_id) {
console.log('发送成功'); console.log("发送成功");
// 发起会话 // 发起会话
const eventSource = new EventSourcePolyfill( const eventSource = new EventSourcePolyfill(
`/api/gpt/stream?chat_id=${res.data.chat_id}`, `/api/gpt/stream?chat_id=${res.data.chat_id}`,
...@@ -34,7 +34,7 @@ const submit = async () => { ...@@ -34,7 +34,7 @@ const submit = async () => {
} }
); );
eventSource.onmessage = function (e: any) { eventSource.onmessage = function (e: any) {
if (e.data == '[DONE]') { if (e.data == "[DONE]") {
eventSource.close(); eventSource.close();
} else { } else {
let word = JSON.parse(e.data).choices[0].delta.content; let word = JSON.parse(e.data).choices[0].delta.content;
...@@ -46,7 +46,7 @@ const submit = async () => { ...@@ -46,7 +46,7 @@ const submit = async () => {
eventSource.onerror = function (e: any) { eventSource.onerror = function (e: any) {
console.log(e); console.log(e);
eventSource.close(); eventSource.close();
console.log('报错了'); console.log("报错了");
}; };
} }
} catch (e) { } catch (e) {
......
<template> <template>
<div class="custom-home-page-login"> <!-- <div class="custom-home-page-login">
<Login></Login> <Login></Login>
</div> -->
<div>
<TestSwiper></TestSwiper>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import Login from './components/login.vue'; import Login from "./components/login.vue";
import TestSwiper from "@/components/custom/swiper/test.vue";
</script> </script>
<style lang="less"> <style lang="less">
@import '@/style/variables.less'; @import "@/style/variables.less";
@import '@/style/flex.less'; @import "@/style/flex.less";
.custom-home-page-login { .custom-home-page-login {
background: #ffffff; background: #ffffff;
height: 100%; height: 100%;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment