作品集代码初版
This commit is contained in:
parent
1d113e78ed
commit
475e0461e2
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="nav-bar">
|
||||
<van-nav-bar title="标题" left-text="返回" :placeholder="true" :safe-area-inset-top="true" z-index="99">
|
||||
<van-nav-bar title="屿" left-text="" :placeholder="true" :safe-area-inset-top="true" z-index="99">
|
||||
<template #right>
|
||||
<van-icon name="search" size="18" />
|
||||
</template>
|
||||
|
@ -1,17 +1,24 @@
|
||||
import Vue from "vue";
|
||||
import Vuex from 'vuex'
|
||||
import Vuex from "vuex";
|
||||
import App from "./App.vue";
|
||||
import router from "./router";
|
||||
import store from "./store";
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
import { Tabbar, TabbarItem } from "vant";
|
||||
import { NavBar } from "vant";
|
||||
import { Toast } from 'vant';
|
||||
import { Popup } from 'vant';
|
||||
import { Icon } from 'vant';
|
||||
import { Button } from 'vant';
|
||||
import { Toast } from "vant";
|
||||
import { Popup } from "vant";
|
||||
import { Icon } from "vant";
|
||||
import { Button } from "vant";
|
||||
import { Image as VanImage } from "vant";
|
||||
import { Lazyload } from "vant";
|
||||
import { Card } from "vant";
|
||||
import { Tag } from "vant";
|
||||
|
||||
Vue.use(Tag);
|
||||
Vue.use(Card);
|
||||
Vue.use(Lazyload);
|
||||
Vue.use(VanImage);
|
||||
Vue.use(Button);
|
||||
Vue.use(Icon);
|
||||
Vue.use(Popup);
|
||||
@ -22,7 +29,6 @@ Vue.use(TabbarItem);
|
||||
Vue.use(Vuex);
|
||||
|
||||
new Vue({
|
||||
store,
|
||||
router,
|
||||
render: (h) => h(App),
|
||||
}).$mount("#app");
|
||||
|
@ -1,25 +1,284 @@
|
||||
<template>
|
||||
<div class="portfolio-page">
|
||||
<h1>作品集</h1>
|
||||
<div class="container">
|
||||
<div class="card-grid">
|
||||
<!-- 卡片列表 -->
|
||||
<div
|
||||
v-for="(card, index) in cards"
|
||||
:key="index"
|
||||
class="card"
|
||||
:class="{ 'card-active': activeCardIndex === index }"
|
||||
@touchstart="handleTouchStart(index)"
|
||||
@touchend="handleTouchEnd(index)"
|
||||
@click="handleCardClick(card)"
|
||||
>
|
||||
<div class="card-image-container">
|
||||
<img
|
||||
:src="card.image"
|
||||
:alt="card.title"
|
||||
class="card-image"
|
||||
>
|
||||
<div
|
||||
v-if="card.tag"
|
||||
class="card-tag"
|
||||
:style="card.tagStyle"
|
||||
>
|
||||
{{ card.tag }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-content">
|
||||
<h2 class="card-title">{{ card.title }}</h2>
|
||||
<p class="card-description">{{ card.description }}</p>
|
||||
|
||||
<div class="card-footer">
|
||||
<span class="card-meta">
|
||||
<i class="fa fa-calendar-o mr-1"></i> {{ card.duration }}
|
||||
</span>
|
||||
<button
|
||||
class="card-button"
|
||||
@click.stop="handleButtonClick(card)"
|
||||
>
|
||||
了解更多
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "PortfolioPage",
|
||||
components: {},
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
name: 'PortfolioPage',
|
||||
data() {
|
||||
return {
|
||||
cards: [
|
||||
{
|
||||
title: "探索自然之美",
|
||||
description: "深入原始森林,感受大自然的鬼斧神工。这里有清澈的溪流、茂密的树木和各种珍稀野生动物。",
|
||||
image: "https://picsum.photos/seed/card1/600/800",
|
||||
duration: "3天2晚",
|
||||
tag: "热门",
|
||||
tagStyle: {
|
||||
backgroundColor: "#F97316",
|
||||
color: "#fff"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "城市探险之旅",
|
||||
description: "穿梭于现代都市与历史古迹之间,体验城市独特的文化氛围和美食特色。",
|
||||
image: "https://picsum.photos/seed/card2/600/800",
|
||||
duration: "2天1晚",
|
||||
tag: "热门",
|
||||
tagStyle: {
|
||||
backgroundColor: "#F97316",
|
||||
color: "#fff"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "美食文化体验",
|
||||
description: "跟随当地厨师学习传统美食的制作方法,品尝地道佳肴,感受美食背后的文化故事。",
|
||||
image: "https://picsum.photos/seed/card3/600/800",
|
||||
duration: "1天",
|
||||
tag: "新品",
|
||||
tagStyle: {
|
||||
backgroundColor: "#22c55e",
|
||||
color: "#fff"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "海洋生态探索",
|
||||
description: "潜入蔚蓝深海,探索神秘的海底世界,与海龟、珊瑚和热带鱼共舞。",
|
||||
image: "https://picsum.photos/seed/card4/600/800",
|
||||
duration: "4天3晚",
|
||||
tag: "推荐",
|
||||
tagStyle: {
|
||||
backgroundColor: "#3b82f6",
|
||||
color: "#fff"
|
||||
}
|
||||
}
|
||||
],
|
||||
activeCardIndex: -1
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleTouchStart(index) {
|
||||
this.activeCardIndex = index;
|
||||
},
|
||||
watch: {},
|
||||
computed: {
|
||||
|
||||
handleTouchEnd() {
|
||||
setTimeout(() => {
|
||||
this.activeCardIndex = -1;
|
||||
}, 300);
|
||||
},
|
||||
methods: {},
|
||||
created() { },
|
||||
mounted() { }
|
||||
|
||||
handleCardClick(card) {
|
||||
console.log('点击了卡片:', card.title);
|
||||
},
|
||||
|
||||
handleButtonClick(card) {
|
||||
console.log('点击了了解更多:', card.title);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 处理按钮触摸反馈
|
||||
const buttons = document.querySelectorAll('.card-button');
|
||||
buttons.forEach(button => {
|
||||
button.addEventListener('touchstart', () => {
|
||||
button.classList.add('button-active');
|
||||
});
|
||||
|
||||
button.addEventListener('touchend', () => {
|
||||
setTimeout(() => {
|
||||
button.classList.remove('button-active');
|
||||
}, 200);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
<style scoped>
|
||||
/* 基础样式 */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Inter', system-ui, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f9fafb;
|
||||
min-height: 100vh;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
/* 容器样式 - 限制最大宽度为800px(双列布局的合理宽度) */
|
||||
.container {
|
||||
max-width: 800px; /* 双列布局的最佳最大宽度 */
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: clamp(1.5rem, 3vw, 2rem);
|
||||
font-weight: bold;
|
||||
color: #1f2937;
|
||||
margin-bottom: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 卡片网格布局 - 固定双列 */
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr); /* 固定双列布局 */
|
||||
gap: 24px; /* 卡片间距 */
|
||||
}
|
||||
|
||||
/* 移动端适配 - 屏幕小于600px时改为单列 */
|
||||
@media (max-width: 600px) {
|
||||
.card-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* 卡片样式 */
|
||||
.card {
|
||||
background-color: white;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.card-active {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
/* 卡片图片 */
|
||||
.card-image-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-image {
|
||||
width: 100%;
|
||||
display: block;
|
||||
/* 3:4 比例 */
|
||||
aspect-ratio: 3 / 4;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
/* 卡片标签 */
|
||||
.card-tag {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
padding: 4px 12px;
|
||||
border-radius: 9999px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 卡片内容 */
|
||||
.card-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #1f2937;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.card-description {
|
||||
color: #6b7280;
|
||||
text-wrap: balance;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.5;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 卡片底部 */
|
||||
.card-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.card-meta {
|
||||
color: #3b82f6;
|
||||
font-weight: 500;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
.card-button {
|
||||
background-color: #3b82f6;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 6px 12px;
|
||||
border-radius: 8px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.card-button:hover {
|
||||
background-color: #2563eb;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.button-active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
</style>
|
@ -3,7 +3,6 @@ import VueRouter from "vue-router";
|
||||
import HomePage from "@/pages/HomePage.vue";
|
||||
import PortfolioPage from "@/pages/PortfolioPage.vue";
|
||||
import SampleCollectionPage from "@/pages/SampleCollectionPage.vue";
|
||||
import {store} from "@/store";
|
||||
Vue.use(VueRouter);
|
||||
|
||||
const routes = [
|
||||
@ -34,10 +33,6 @@ const router = new VueRouter({
|
||||
|
||||
// 全局前置守卫
|
||||
router.beforeEach((to, from, next) => {
|
||||
// 避免重复记录相同路径(如刷新页面)
|
||||
if (to.path !== from.path) {
|
||||
store.dispatch("routeHistory/pushRoute", to);
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
|
@ -1,52 +0,0 @@
|
||||
|
||||
const state = {
|
||||
history: [], // 存储路由历史
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
// 添加路由到历史记录
|
||||
PUSH_ROUTE(state, route) {
|
||||
state.history.push(route);
|
||||
},
|
||||
|
||||
// 重置历史记录
|
||||
RESET_HISTORY(state) {
|
||||
state.history = [];
|
||||
},
|
||||
};
|
||||
|
||||
const actions = {
|
||||
pushRoute({ commit }, route) {
|
||||
commit("PUSH_ROUTE", route);
|
||||
},
|
||||
|
||||
resetHistory({ commit }) {
|
||||
commit("RESET_HISTORY");
|
||||
},
|
||||
};
|
||||
|
||||
const getters = {
|
||||
// 判断当前是否为后退操作
|
||||
isBack(state) {
|
||||
if (state.history.length < 2) return false;
|
||||
|
||||
const current = state.history[state.history.length - 1];
|
||||
const previous = state.history[state.history.length - 2];
|
||||
|
||||
// 通过比较路径判断是否为后退
|
||||
return previous.path === current.path;
|
||||
},
|
||||
|
||||
// 获取历史记录长度
|
||||
historyLength(state) {
|
||||
return state.history.length;
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true, // 使用命名空间
|
||||
state,
|
||||
mutations,
|
||||
actions,
|
||||
getters,
|
||||
};
|
Loading…
Reference in New Issue
Block a user