浏览代码

style: --

chenlei 1 年之前
父节点
当前提交
cba31782c1

+ 4 - 0
components.d.ts

@@ -8,12 +8,16 @@ export {}
 declare module 'vue' {
   export interface GlobalComponents {
     Accessibility: typeof import('./src/components/Accessibility/index.vue')['default']
+    Breadcrumb: typeof import('./src/components/Breadcrumb/index.vue')['default']
     ElButton: typeof import('element-plus/es')['ElButton']
     ElCollapse: typeof import('element-plus/es')['ElCollapse']
     ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
     ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
+    ElDialog: typeof import('element-plus/es')['ElDialog']
     ElImage: typeof import('element-plus/es')['ElImage']
+    ElPagination: typeof import('element-plus/es')['ElPagination']
     Layout: typeof import('./src/components/Layout/index.vue')['default']
+    Pagination: typeof import('./src/components/Pagination/index.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
     SvgIcon: typeof import('./src/components/SvgIcon/index.vue')['default']

+ 2 - 1
package.json

@@ -18,7 +18,8 @@
     "pinia": "^2.1.7",
     "vant": "^4.9.0",
     "vue": "^3.4.21",
-    "vue-router": "^4.3.0"
+    "vue-router": "^4.3.0",
+    "vue-waterfall-plugin-next": "^2.4.3"
   },
   "devDependencies": {
     "@tsconfig/node20": "^20.1.4",

+ 95 - 0
pnpm-lock.yaml

@@ -29,6 +29,9 @@ dependencies:
   vue-router:
     specifier: ^4.3.0
     version: 4.3.2(vue@3.4.27)
+  vue-waterfall-plugin-next:
+    specifier: ^2.4.3
+    version: 2.4.3(@types/lodash-es@4.17.12)(vue@3.4.27)
 
 devDependencies:
   '@tsconfig/node20':
@@ -397,6 +400,14 @@ packages:
       query-string: 8.2.0
     dev: false
 
+  /@element-plus/icons-vue@1.1.4(vue@3.4.27):
+    resolution: {integrity: sha512-Iz/nHqdp1sFPmdzRwHkEQQA3lKvoObk8azgABZ81QUOpW9s/lUyQVUSh0tNtEPZXQlKwlSh7SPgoVxzrE0uuVQ==}
+    peerDependencies:
+      vue: ^3.2.0
+    dependencies:
+      vue: 3.4.27(typescript@5.4.5)
+    dev: false
+
   /@element-plus/icons-vue@2.3.1(vue@3.4.27):
     resolution: {integrity: sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==}
     peerDependencies:
@@ -679,6 +690,10 @@ packages:
       fastq: 1.17.1
     dev: true
 
+  /@popperjs/core@2.11.8:
+    resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
+    dev: false
+
   /@rollup/pluginutils@5.1.0:
     resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
     engines: {node: '>=14.0.0'}
@@ -869,6 +884,10 @@ packages:
       '@types/node': 20.12.13
     dev: true
 
+  /@types/web-bluetooth@0.0.14:
+    resolution: {integrity: sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==}
+    dev: false
+
   /@types/web-bluetooth@0.0.16:
     resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
     dev: false
@@ -1062,6 +1081,24 @@ packages:
     resolution: {integrity: sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==}
     dev: true
 
+  /@vueuse/core@8.9.4(vue@3.4.27):
+    resolution: {integrity: sha512-B/Mdj9TK1peFyWaPof+Zf/mP9XuGAngaJZBwPaXBvU3aCTZlx3ltlrFFFyMV4iGBwsjSCeUCgZrtkEj9dS2Y3Q==}
+    peerDependencies:
+      '@vue/composition-api': ^1.1.0
+      vue: ^2.6.0 || ^3.2.0
+    peerDependenciesMeta:
+      '@vue/composition-api':
+        optional: true
+      vue:
+        optional: true
+    dependencies:
+      '@types/web-bluetooth': 0.0.14
+      '@vueuse/metadata': 8.9.4
+      '@vueuse/shared': 8.9.4(vue@3.4.27)
+      vue: 3.4.27(typescript@5.4.5)
+      vue-demi: 0.14.8(vue@3.4.27)
+    dev: false
+
   /@vueuse/core@9.13.0(vue@3.4.27):
     resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==}
     dependencies:
@@ -1074,10 +1111,29 @@ packages:
       - vue
     dev: false
 
+  /@vueuse/metadata@8.9.4:
+    resolution: {integrity: sha512-IwSfzH80bnJMzqhaapqJl9JRIiyQU0zsRGEgnxN6jhq7992cPUJIRfV+JHRIZXjYqbwt07E1gTEp0R0zPJ1aqw==}
+    dev: false
+
   /@vueuse/metadata@9.13.0:
     resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==}
     dev: false
 
+  /@vueuse/shared@8.9.4(vue@3.4.27):
+    resolution: {integrity: sha512-wt+T30c4K6dGRMVqPddexEVLa28YwxW5OFIPmzUHICjphfAuBFTTdDoyqREZNDOFJZ44ARH1WWQNCUK8koJ+Ag==}
+    peerDependencies:
+      '@vue/composition-api': ^1.1.0
+      vue: ^2.6.0 || ^3.2.0
+    peerDependenciesMeta:
+      '@vue/composition-api':
+        optional: true
+      vue:
+        optional: true
+    dependencies:
+      vue: 3.4.27(typescript@5.4.5)
+      vue-demi: 0.14.8(vue@3.4.27)
+    dev: false
+
   /@vueuse/shared@9.13.0(vue@3.4.27):
     resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
     dependencies:
@@ -1093,6 +1149,10 @@ packages:
     hasBin: true
     dev: true
 
+  /animate.css@4.1.1:
+    resolution: {integrity: sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==}
+    dev: false
+
   /ansi-regex@2.1.1:
     resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==}
     engines: {node: '>=0.10.0'}
@@ -1605,6 +1665,29 @@ packages:
     resolution: {integrity: sha512-d0EFmtLPjctczO3LogReyM2pbBiiZbnsKnGF+cdZhsYzHm/A0GV7W94kqzLD8SN4O3f3iHlgLUChqghgyznvCQ==}
     dev: true
 
+  /element-plus@2.1.4(@types/lodash-es@4.17.12)(vue@3.4.27):
+    resolution: {integrity: sha512-pcwgDbKUrzyWbixYB/zIbLPLBQ/NPGPJnGXJ+jYozUSthPW4SuriaUGJKgbAE6PDBAtw3IodiT2E2GbiaZLxww==}
+    peerDependencies:
+      vue: ^3.2.0
+    dependencies:
+      '@ctrl/tinycolor': 3.6.1
+      '@element-plus/icons-vue': 1.1.4(vue@3.4.27)
+      '@popperjs/core': 2.11.8
+      '@vueuse/core': 8.9.4(vue@3.4.27)
+      async-validator: 4.2.5
+      dayjs: 1.11.11
+      escape-html: 1.0.3
+      lodash: 4.17.21
+      lodash-es: 4.17.21
+      lodash-unified: 1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21)
+      memoize-one: 6.0.0
+      normalize-wheel-es: 1.2.0
+      vue: 3.4.27(typescript@5.4.5)
+    transitivePeerDependencies:
+      - '@types/lodash-es'
+      - '@vue/composition-api'
+    dev: false
+
   /element-plus@2.7.3(vue@3.4.27):
     resolution: {integrity: sha512-OaqY1kQ2xzNyRFyge3fzM7jqMwux+464RBEqd+ybRV9xPiGxtgnj/sVK4iEbnKnzQIa9XK03DOIFzoToUhu1DA==}
     peerDependencies:
@@ -3629,6 +3712,18 @@ packages:
       typescript: 5.4.5
     dev: true
 
+  /vue-waterfall-plugin-next@2.4.3(@types/lodash-es@4.17.12)(vue@3.4.27):
+    resolution: {integrity: sha512-L2mH8wOn+ZuddPhaYHKljfukNM0iQd3vhjesvBK4ck+D5swS8c34VdlOED2w53QZvUrXQpEg9ASDHzLlLkzztg==}
+    dependencies:
+      animate.css: 4.1.1
+      element-plus: 2.1.4(@types/lodash-es@4.17.12)(vue@3.4.27)
+      vue-router: 4.3.2(vue@3.4.27)
+    transitivePeerDependencies:
+      - '@types/lodash-es'
+      - '@vue/composition-api'
+      - vue
+    dev: false
+
   /vue@3.4.27(typescript@5.4.5):
     resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==}
     peerDependencies:

+ 1 - 1
src/App.vue

@@ -37,6 +37,6 @@ body.aria-active {
 .container {
   margin: 0 auto;
   width: 100%;
-  max-width: 1300px;
+  max-width: 1200px;
 }
 </style>

+ 58 - 0
src/components/Breadcrumb/index.vue

@@ -0,0 +1,58 @@
+<template>
+  <div
+    class="breadcrumb"
+    data-aria-viewport-area
+    aria-description="You've reached the path area; this area contains three URLs; please use the tab key to go through the content."
+  >
+    <span
+      tabindex="0"
+      aria-description="Your Position"
+      style="color: var(--van-primary-color)"
+      >Your Position:&nbsp;</span
+    >
+
+    <RouterLink
+      replace
+      :to="{ name: 'Home' }"
+      tabindex="0"
+      aria-description="Home"
+    >
+      Home>
+    </RouterLink>
+    <RouterLink
+      replace
+      tabindex="0"
+      :to="{ name: parent.pathName }"
+      :aria-description="parent.label"
+    >
+      {{ parent.label }}>
+    </RouterLink>
+    <span tabindex="0" :aria-description="curRoute?.name">
+      {{ curRoute?.name }}
+    </span>
+  </div>
+</template>
+
+<script lang="ts" setup>
+defineProps<{
+  parent: {
+    label: string;
+    pathName: string;
+  };
+
+  curRoute?: {
+    name: string;
+    [attr: string]: any;
+  };
+}>();
+</script>
+
+<style lang="scss" scoped>
+.breadcrumb {
+  max-width: 1180px;
+  height: 28px;
+  line-height: 28px;
+  font-size: 12px;
+  margin: 10px auto;
+}
+</style>

+ 8 - 1
src/components/Layout/data.ts

@@ -1,8 +1,9 @@
 export const topData = [
-  { id: 1, name: "Home", url: "home" },
+  { id: 1, name: "Home", pathName: "Home", url: "home" },
   {
     id: 2,
     name: "Visit",
+    pathName: "Visit",
     url: "Visit",
     children: [
       { url: "/Layout/Visit/8", id: 2.8, name: "Calendar" },
@@ -18,6 +19,7 @@ export const topData = [
   {
     id: 3,
     name: "Exhibitions",
+    pathName: "Exhibitions",
     url: "Exhibitions/1",
     children: [
       { url: "/Layout/Exhibitions/1", id: 3.1, name: "Current Exhibitions" },
@@ -29,6 +31,7 @@ export const topData = [
   {
     id: 4,
     name: "Collections",
+    pathName: "Collections",
     url: "Collections/Bronzes",
     children: [
       { url: "/Layout/Collections/Bronzes", id: 4.1, name: "Bronzes" },
@@ -67,6 +70,7 @@ export const topData = [
   {
     id: 5,
     name: "Learn & Engage",
+    pathName: "LearnEngage",
     url: "LearnEngage/Students",
     children: [
       { url: "/Layout/LearnEngage/Students", id: 5.1, name: "For Students" },
@@ -81,6 +85,7 @@ export const topData = [
   {
     id: 6,
     name: "Publications",
+    pathName: "Publications",
     url: "Publications",
     children: [
       { url: "/Layout/Publications/1", id: 6.1, name: "Magazines" },
@@ -91,6 +96,7 @@ export const topData = [
   {
     id: 7,
     name: "Join & Support",
+    pathName: "JoinSupport",
     url: "JoinSupport/Volunteer",
     children: [
       {
@@ -104,6 +110,7 @@ export const topData = [
   {
     id: 8,
     name: "About",
+    pathName: "About",
     url: "About",
     about: true,
     children: [

+ 8 - 2
src/components/Layout/index.vue

@@ -37,8 +37,9 @@
                 :aria-description="item.name"
                 :class="{
                   active:
-                    $route.path.toLowerCase().indexOf(item.name.toLowerCase()) >
-                    -1,
+                    $route.path
+                      .toLowerCase()
+                      .indexOf(item.pathName.toLowerCase()) > -1,
                 }"
                 @click="skipOne(item.url)"
                 @keydown.enter.passive="skipOne(item.url)"
@@ -248,6 +249,7 @@ const handleSearch = () => {
   --topnav-bg-color: rgba(0, 0, 0, 0.8);
   --primary-hover-bg: rgba(204, 0, 3, 0.8);
   --black-text-color: black;
+  --gray-text-color: #666;
   --white-bg: white;
   --white-text-color: white;
 
@@ -256,6 +258,7 @@ const handleSearch = () => {
     --van-white: black;
     --primary-hover-bg: white;
     --black-text-color: black;
+    --gray-text-color: #666;
     --white-bg: white;
     --white-text-color: black;
   }
@@ -264,6 +267,7 @@ const handleSearch = () => {
     --van-white: #ff0;
     --primary-hover-bg: #00f;
     --black-text-color: #ff0;
+    --gray-text-color: #ff0;
     --white-bg: #00f;
     --white-text-color: #ff0;
   }
@@ -272,6 +276,7 @@ const handleSearch = () => {
     --van-white: black;
     --primary-hover-bg: #ff0;
     --black-text-color: black;
+    --gray-text-color: black;
     --white-bg: #ff0;
     --white-text-color: black;
   }
@@ -280,6 +285,7 @@ const handleSearch = () => {
     --van-white: #ff0;
     --primary-hover-bg: black;
     --black-text-color: #ff0;
+    --gray-text-color: #ff0;
     --white-bg: black;
     --white-text-color: #ff0;
   }

+ 26 - 0
src/components/Pagination/index.vue

@@ -0,0 +1,26 @@
+<template>
+  <ElPagination v-bind="props" class="pagination" layout="prev, pager, next" />
+</template>
+
+<script lang="ts" setup>
+import type { PaginationProps } from "element-plus";
+
+const props = defineProps<Partial<PaginationProps>>();
+</script>
+
+<style lang="scss">
+.pagination {
+  --el-pagination-font-size: 16px;
+
+  .el-pager {
+    gap: 7px;
+
+    .is-active {
+      background-color: var(--van-primary-color);
+      color: var(--white-bg);
+      border-radius: 50%;
+      pointer-events: none;
+    }
+  }
+}
+</style>

+ 10 - 0
src/router/index.ts

@@ -68,6 +68,16 @@ const router = createRouter({
           name: "Exhibitions",
           component: () => import("../views/Exhibitions/index.vue"),
         },
+        {
+          path: "/Layout/Collections/:type",
+          name: "Collections",
+          component: () => import("../views/Collections/index.vue"),
+        },
+        {
+          path: "/Layout/LearnEngage/:type",
+          name: "LearnEngage",
+          component: () => import("../views/LearnEngage/index.vue"),
+        },
       ],
     },
   ],

+ 65 - 0
src/views/Collections/components/DetailDialog/index.scss

@@ -0,0 +1,65 @@
+.collection-detail {
+  --el-dialog-margin-top: 8vh;
+  --el-dialog-bg-color: transparent;
+  --el-dialog-box-shadow: none;
+
+  .el-dialog__body {
+    display: flex;
+    align-items: flex-start;
+    gap: 30px;
+  }
+  .el-dialog__close {
+    --el-color-info: white;
+    width: 40px;
+    height: 40px;
+    border-radius: 50%;
+    background: var(--van-primary-color);
+
+    svg {
+      width: 22px;
+      height: 22px;
+    }
+  }
+  .el-dialog__headerbtn {
+    top: 26px;
+    right: -40px;
+
+    &:hover .el-dialog__close {
+      color: white;
+    }
+  }
+  &-preview,
+  &-info {
+    padding: 20px;
+    background: var(--white-bg);
+    box-shadow: 0 0 10px #000;
+  }
+  &-preview {
+    width: 540px;
+    color: var(--black-text-color);
+
+    h3 {
+      font-weight: 700;
+      font-size: 36px;
+      line-height: 100%;
+    }
+    .el-image {
+      margin: 20px 0;
+      width: 100%;
+    }
+    &__btn {
+      margin: 0 auto;
+      width: 160px;
+      height: 40px;
+      font-size: 16px;
+      line-height: 40px;
+      text-align: center;
+      border: 1px solid var(--black-text-color);
+      cursor: pointer;
+    }
+  }
+  &-info {
+    flex: 1;
+    width: 440px;
+  }
+}

+ 48 - 0
src/views/Collections/components/DetailDialog/index.vue

@@ -0,0 +1,48 @@
+<template>
+  <ElDialog v-model="show" class="collection-detail" :width="1010 + 32">
+    <div class="collection-detail-preview">
+      <h3 tabindex="0" aria-description="">
+        Gold-inlaid Incense Burner with Cord-shaped Ears and Persian Inscription
+      </h3>
+
+      <ElImage
+        tabindex="0"
+        aria-label="Image"
+        aria-description=""
+        src="http://localhost:8080/data/Collections/Bronzes/big25.png"
+      />
+
+      <div
+        class="collection-detail-preview__btn"
+        tabindex="0"
+        aria-label="Button"
+      >
+        Enlarge
+      </div>
+    </div>
+
+    <div class="collection-detail-info"></div>
+  </ElDialog>
+</template>
+
+<script lang="ts" setup>
+import { computed } from "vue";
+
+const props = defineProps<{
+  visible: boolean;
+}>();
+const emits = defineEmits(["update:visible"]);
+
+const show = computed({
+  get() {
+    return props.visible;
+  },
+  set(v: boolean) {
+    emits("update:visible", v);
+  },
+});
+</script>
+
+<style lang="scss">
+@import "./index.scss";
+</style>

+ 43 - 0
src/views/Collections/components/Menu.vue

@@ -0,0 +1,43 @@
+<template>
+  <ul class="collection-menu">
+    <li
+      v-for="item in NAV_LIST"
+      :key="item.type"
+      tabindex="0"
+      :aria-description="item.name"
+    >
+      <p>{{ item.name }}</p>
+    </li>
+  </ul>
+</template>
+
+<script lang="ts" setup>
+import { NAV_LIST } from "../constants";
+</script>
+
+<style lang="scss" scoped>
+.collection-menu {
+  li {
+    position: relative;
+    border-bottom: 1px solid #fff;
+
+    &:last-child {
+      border: none;
+    }
+    &:hover {
+      p {
+        background: rgba(254, 24, 24, 0.7);
+      }
+    }
+    p {
+      height: 47px;
+      line-height: 47px;
+      text-indent: 10px;
+      font-size: 14px;
+      color: white;
+      background: #181818 no-repeat right center;
+      cursor: pointer;
+    }
+  }
+}
+</style>

+ 16 - 0
src/views/Collections/constants.ts

@@ -0,0 +1,16 @@
+export const NAV_LIST = [
+  {
+    name: "Bronzes",
+    type: "Bronzes",
+  },
+  { name: "Ceramics", type: "Ceramics" },
+  { name: "Buddhist Statues", type: "Buddhist" },
+  { name: "Jadewares", type: "Jadewares" },
+  { name: "Calligraphies", type: "Calligraphies" },
+  { name: "Paintings", type: "Paintings" },
+  { name: "Gold & Silverwares", type: "Gold" },
+  { name: "Coins & Banknotes", type: "Coins" },
+  { name: "Brocades & Embroideries", type: "Brocades" },
+  { name: "Cultural Supplies", type: "Cultural" },
+  { name: "Miscellaneous", type: "Miscellaneous" },
+];

二进制
src/views/Collections/images/banner.jpg


+ 79 - 0
src/views/Collections/index.scss

@@ -0,0 +1,79 @@
+.collections {
+  background-color: var(--white-bg);
+
+  &-banner {
+    margin-top: -60px;
+    display: block;
+    width: 100%;
+    height: 300px;
+    object-fit: cover;
+  }
+
+  &-main {
+    display: flex;
+    gap: 10px;
+    padding-bottom: 20px;
+
+    .collection-menu {
+      flex-shrink: 0;
+      width: 210px;
+    }
+    &__right {
+      flex: 1;
+      padding-left: 10px;
+      overflow: hidden;
+      border-left: 1px solid #d8d8d8;
+    }
+  }
+
+  .waterfall-list {
+    background-color: var(--white-bg);
+  }
+
+  &-item {
+    width: 100%;
+    cursor: pointer;
+
+    img {
+      display: block;
+      width: 100%;
+    }
+    &__inner {
+      position: relative;
+      padding: 20px 15px;
+
+      p:first-child {
+        font-size: 18px;
+        color: var(--black-text-color);
+        line-height: 22px;
+        padding-bottom: 5px;
+        font-weight: 700;
+      }
+      p:last-child {
+        font-size: 14px;
+        color: var(--gray-text-color);
+      }
+    }
+    &:hover {
+      box-shadow: 0 0 10px #000;
+
+      .collections-item__inner {
+        background: var(--van-primary-color);
+
+        &::before {
+          content: "";
+          position: absolute;
+          top: -59px;
+          left: 30px;
+          border-top: 30px solid transparent;
+          border-left: 18px solid transparent;
+          border-right: 18px solid transparent;
+          border-bottom: 30px solid var(--van-primary-color);
+        }
+        p {
+          color: white !important;
+        }
+      }
+    }
+  }
+}

+ 95 - 0
src/views/Collections/index.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="collections">
+    <img
+      class="collections-banner"
+      tabindex="0"
+      aria-description="You've reached the banner area of the Collections section; this section has one image; please use the tab key to go through the content."
+      src="./images/banner.jpg"
+    />
+
+    <div class="container">
+      <Breadcrumb
+        :parent="{
+          label: 'Collections',
+          pathName: 'Collections',
+        }"
+        :cur-route="curRoute"
+      />
+
+      <div class="collections-main">
+        <Menu />
+
+        <div class="collections-main__right">
+          <Waterfall :list="list" :gutter="30" :hasAroundGutter="false">
+            <template #item="{ item, url, index }">
+              <div
+                class="collections-item"
+                aria-label="Link"
+                @click="handleItemClick(item)"
+              >
+                <img alt="" :src="url" aria-label="Image link" />
+                <div class="collections-item__inner">
+                  <p tabindex="0" aria-description="">
+                    Bronze He Wine Vessel Inscribed by Ke
+                  </p>
+                  <p tabindex="0" aria-description="">
+                    This vessel has a domed lid with a loop handle that has tiny
+                    animal faces (eyes and horns) at its ends. A smaller loop at
+                    one side of the lid is connected by a link to another loop
+                    at the top of the handle.
+                  </p>
+                </div>
+              </div>
+            </template>
+          </Waterfall>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <DetailDialog v-model:visible="visible" />
+</template>
+
+<script lang="ts" setup>
+import { Waterfall } from "vue-waterfall-plugin-next";
+import type { ViewCard } from "vue-waterfall-plugin-next/dist/types/types/waterfall";
+import { useRoute } from "vue-router";
+import { computed, ref } from "vue";
+import Breadcrumb from "@/components/Breadcrumb/index.vue";
+import { NAV_LIST } from "./constants";
+import Menu from "./components/Menu.vue";
+import DetailDialog from "./components/DetailDialog/index.vue";
+import "vue-waterfall-plugin-next/dist/style.css";
+
+const route = useRoute();
+const curRoute = computed(() =>
+  NAV_LIST.find((i) => i.type === (route.params.type as string))
+);
+const list = ref<ViewCard[]>([
+  {
+    id: "1",
+    src: "http://localhost:8080/data/Collections/Bronzes/big1.png",
+  },
+  {
+    id: "2",
+    src: "http://localhost:8080/data/Collections/Bronzes/12.png",
+  },
+  {
+    id: "3",
+    src: "http://localhost:8080/data/Collections/Bronzes/22.png",
+  },
+  {
+    id: "4",
+    src: "http://localhost:8080/data/Collections/Bronzes/2.png",
+  },
+]);
+const visible = ref(false);
+
+const handleItemClick = (item: any) => {
+  visible.value = true;
+};
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 2 - 1
src/views/Exhibitions/components/ListItem/index.vue

@@ -21,6 +21,7 @@
   display: flex;
   height: 240px;
   background: var(--white-bg);
+  color: var(--black-text-color);
   cursor: pointer;
 
   > img {
@@ -43,7 +44,7 @@
   &__content {
     font-size: 14px;
     line-height: 20px;
-    color: #666;
+    color: var(--gray-text-color);
   }
 }
 </style>

+ 1 - 5
src/views/Exhibitions/index.scss

@@ -46,11 +46,7 @@
   }
 
   .breadcrumb {
-    max-width: 1180px;
-    height: 28px;
-    line-height: 28px;
-    font-size: 12px;
-    margin: 0 auto 10px;
+    margin-top: 0;
   }
 
   &-title {

+ 8 - 23
src/views/Exhibitions/index.vue

@@ -37,29 +37,13 @@
     </div>
 
     <div class="container">
-      <div
-        class="breadcrumb"
-        data-aria-viewport-area
-        aria-description="You've reached the path area; this area contains three URLs; please use the tab key to go through the content."
-      >
-        <span style="color: var(--van-primary-color)"
-          >Your Position:&nbsp;</span
-        >
-
-        <RouterLink replace :to="{ name: 'Home' }" aria-description="Home">
-          Home>
-        </RouterLink>
-        <RouterLink
-          replace
-          :to="{ name: 'Exhibitions', params: { type: 1 } }"
-          aria-description="Exhibitions"
-        >
-          Exhibitions>
-        </RouterLink>
-        <span>
-          {{ curRoute?.name }}
-        </span>
-      </div>
+      <Breadcrumb
+        :parent="{
+          label: 'Exhibitions',
+          pathName: 'Exhibitions',
+        }"
+        :cur-route="curRoute"
+      />
 
       <div class="exhibitions-title">
         <img src="@/assets/images/Visit/pLeft.jpg" alt="" />
@@ -149,6 +133,7 @@ import ListModeIcon from "@/assets/images/Exhibitions/cut1.png";
 import ActListModeIcon from "@/assets/images/Exhibitions/cut1Ac.png";
 import ImgModeIcon from "@/assets/images/Exhibitions/cut2.png";
 import ActImgModeIcon from "@/assets/images/Exhibitions/cut2Ac.png";
+import Breadcrumb from "@/components/Breadcrumb/index.vue";
 import ListItem from "./components/ListItem/index.vue";
 import ImgItem from "./components/ImgItem/index.vue";
 

二进制
src/views/LearnEngage/images/1.png


二进制
src/views/LearnEngage/images/2.png


二进制
src/views/LearnEngage/images/3.png


二进制
src/views/LearnEngage/images/topBan.jpg


+ 9 - 0
src/views/LearnEngage/index.scss

@@ -0,0 +1,9 @@
+.learn-engage {
+  &-banner {
+    margin-top: -60px;
+    display: block;
+    width: 100%;
+    height: 300px;
+    object-fit: cover;
+  }
+}

+ 58 - 0
src/views/LearnEngage/index.vue

@@ -0,0 +1,58 @@
+<template>
+  <div class="learn-engage">
+    <img
+      class="learn-engage-banner"
+      tabindex="0"
+      aria-description="You've reached the banner area of the Learn & Engage section; this section has one image; please use the tab key to go through the content."
+      src="./images/topBan.jpg"
+    />
+
+    <div class="container">
+      <ul class="visit-nav"></ul>
+
+      <Breadcrumb
+        :parent="{
+          label: 'Learn & Engage',
+          pathName: 'LearnEngage',
+        }"
+        :cur-route="curRoute"
+      />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useRoute } from "vue-router";
+import { computed } from "vue";
+import Breadcrumb from "@/components/Breadcrumb/index.vue";
+import StudentsIcon from "./images/1.png";
+import AdultsIcon from "./images/2.png";
+import FamiliesIcon from "./images/3.png";
+
+const NAV_LIST = [
+  {
+    name: "For Students",
+    img: StudentsIcon,
+    type: "Students",
+  },
+  {
+    name: "For Adults",
+    img: AdultsIcon,
+    type: "Adults",
+  },
+  {
+    name: "For Families & Children",
+    img: FamiliesIcon,
+    type: "Families",
+  },
+];
+
+const route = useRoute();
+const curRoute = computed(() =>
+  NAV_LIST.find((i) => i.type === (route.params.type as string))
+);
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 0 - 14
src/views/Visit/Calendar/index.scss

@@ -205,20 +205,6 @@
   display: flex;
   justify-content: center;
   padding-top: 30px;
-  & > span {
-    width: 30px;
-    height: 30px;
-    text-align: center;
-    line-height: 30px;
-    margin-right: 15px;
-    border-radius: 50%;
-    cursor: pointer;
-  }
-  .active {
-    background-color: var(--van-primary-color);
-    color: var(--white-bg);
-    pointer-events: none;
-  }
 }
 .empty {
   text-align: center;

+ 4 - 14
src/views/Visit/Calendar/index.vue

@@ -119,18 +119,7 @@
 
       <!-- 分页 -->
       <div class="page">
-        <span
-          v-for="i in pageNum"
-          :key="i"
-          :class="{ active: pageSize === i }"
-          tabindex="0"
-          aria-label="Link"
-          :aria-description="`page ${i}`"
-          @click="handlePage(i)"
-          @keydown.enter.passive="handlePage(i)"
-        >
-          {{ i }}
-        </span>
+        <Pagination :total="50" />
       </div>
     </div>
   </div>
@@ -138,9 +127,10 @@
 
 <script setup lang="ts">
 import { ref } from "vue";
-import Calendar from "./components/Calendar.vue";
 import type { SwipeInstance } from "vant";
 import { useRouter } from "vue-router";
+import Pagination from "@/components/Pagination/index.vue";
+import Calendar from "./components/Calendar.vue";
 
 const router = useRouter();
 
@@ -172,7 +162,7 @@ const allList = ref<any[]>([
     h4: "",
   },
 ]);
-const pageNum = ref(0);
+const pageNum = ref(3);
 const pageSize = ref(1);
 
 const handleClick = (item: any) => {

+ 8 - 27
src/views/Visit/index.vue

@@ -26,25 +26,13 @@
         </li>
       </ul>
 
-      <div
-        class="breadcrumb"
-        data-aria-viewport-area
-        aria-description="You've reached the path area; this area contains three URLs; please use the tab key to go through the content."
-      >
-        <span style="color: var(--van-primary-color)"
-          >Your Position:&nbsp;</span
-        >
-
-        <RouterLink replace :to="{ name: 'Home' }" aria-description="Home">
-          Home>
-        </RouterLink>
-        <RouterLink replace :to="{ name: 'Visit' }" aria-description="Visit">
-          Visit>
-        </RouterLink>
-        <span>
-          {{ curRoute?.name }}
-        </span>
-      </div>
+      <Breadcrumb
+        :parent="{
+          label: 'Visit',
+          pathName: 'Visit',
+        }"
+        :cur-route="curRoute"
+      />
 
       <RouterView />
     </div>
@@ -52,6 +40,7 @@
 </template>
 
 <script lang="ts" setup>
+import Breadcrumb from "@/components/Breadcrumb/index.vue";
 import CalendarIcon from "@/assets/images/Visit/m-16.png";
 import DirectionIcon from "@/assets/images/Visit/m-9.png";
 import ReservationIcon from "@/assets/images/Visit/m-10.png";
@@ -158,13 +147,5 @@ const curRoute = computed(() =>
       }
     }
   }
-
-  .breadcrumb {
-    max-width: 1180px;
-    height: 28px;
-    line-height: 28px;
-    font-size: 12px;
-    margin: 10px auto;
-  }
 }
 </style>