- 项目日期:2024 年 2 月 13 日
- 前言:由于目前个人能力的欠缺,设计颇为简陋,暂时达不到官网实际效果,仅供参考。
一、项目建立
1、脚手架生成
首先 使用 Vue CLi 创建生成脚手架:
接着 自定义选择 Vue 配置:
选择 Vue3.0 :
选择 ESlint 风格:
创建完成。
2、启动项目
3、初始化项目
- 对于 App.vue :
<template>
<div id="app">
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
- 对于 main.js :
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
二、设置网页通用样式
1、创建文件
在项目文件中的 public 文件中创建 css 文件
2、书写 .css 文件
用 CSS 样式设计网页全局的基本样式:
文件 base.css 如下:
/* 去除常见标签默认的 margin 和 padding */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 设置网页统一的字体大小、行高、字体系列相关属性 */
body {
font: 16px/1.5 "Microsoft Yahei", "Hiragino Sans GB", "Heiti SC", "WenQuanYi Micro Hei", sans-serif;
color: #333;
}
/* 去除列表默认样式 */
ul,
ol {
list-style: none;
}
/* 去除默认的倾斜效果 */
em,
i {
font-style: none;
}
/* 去除a标签下划线,并设置默认字体颜色 */
a {
color: #333;
text-decoration: none;
}
/* 设置img的垂直对齐方式,去除img默认下间隙 */
img {
width: 100%;
height: 100%;
vertical-align: middle;
}
/* 去除input默认样式 */
input {
border: none;
outline: none;
color: #333;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 400;
}
/* 设置网页版心 */
.wrapper {
margin: 0 auto;
width: 1220px;
}
3、在 index.html 文件中引入 base.css 文件
注意引入文件路径的形式,其中可以按照 favicon.icon 文件格式书写。
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- 在此处引入 -->
<link rel="stylesheet" href="<%= BASE_URL %>css/base.css">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
三、创建组件(Component)
组件在项目文件中的 src 文件 中的 component 文件创建相应的 .vue 文件。
在 App.vue 中调用组件
我们应该将所创建的组件按照先后顺序引入 app.vue 文件中,如下:
<template>
<div id="app">
<ShortCut/>
<BanNer/>
<HighLight/>
<ARP/>
<CampusLife/>
<BotTom/>
</div>
</template>
<script>
import ShortCut from './components/ShortCut.vue';
import BanNer from './components/banner.vue';
import HighLight from './components/highlight.vue';
import ARP from './components/ARP.vue';
import CampusLife from './components/campusLift.vue'
import BotTom from './components/bottom.vue';
export default {
name: 'App',
components: {
ShortCut,
BanNer,
HighLight,
ARP,
CampusLife,
BotTom
}
}
</script>
这样但我们启动 Vue 视图时就可以获取 Eslint 信息以及网页效果。
四、设计组件(Component)
1、ShortCut 组件
ShortCut 组件用于设计官网顶部导航。
- 首先 将整个顶部导航设计为一整个盒子shortcut,再将左侧 logo 图 与右侧的导航分别划分为 left 盒子 和 right 盒子。
- 在 left 盒子中添加
<a></a>
标签 - 在 right 盒子中添加
ul>li>a
标签
- 在 left 盒子中添加
设计 HTML 结构:
<template> <div class=shortcut> <div class="left"> <a href="#"></a> </div> <div class="right"> <ul> <li><a href="#"></a></li> </ul> </div> </div> </template>
设计 shortcut 盒子 的 CSS 样式:
.shortcut { /* 设计盒子居中 */ position: absolute; top: 0; left: 50%; transform: translateX(-50%); /* 设计内部盒子flex布局 */ display: flex; /* 设计内部盒子之间等间距 */ justify-content: space-between; /* 盒子层叠等级提高 */ z-index: 2; padding: 0 146px; width: 100%; height: 108px; transition: all 0.4s; }
设计 left 盒子 的 CSS 样式:
.shortcut .left { padding: 26px 0; } .shortcut .left a { display: block; width: 244px; height: 55px; background: url(./images/logob.png) no-repeat center; background-size: contain; /* 1 */ transition: all 0.4s; }
设计 right 盒子 的 CSS 样式:
.shortcut .right { padding: 30px 0; } .shortcut .right ul { /* 设计内部盒子flex布局 */ display: flex; width: 100%; height: 100%; } .shortcut .right li { position: relative; padding: 0 7px; } /* 设计盒子伪元素属性 */ .shortcut .right li::before { content: ''; width: 0; height: 4px; /* 盒子居底部 */ position: absolute; left: 0; bottom: 0; background: #f0a700; transition: all 0.4s; } .shortcut .right li a { line-height: 50px; font-weight: 900; color: #fff; transition: all 0.4s; }
- 接着设计 right 盒子 中的 li 标签。
- 从官网看出,使用 li 标签的一共有 13 个,但是其中最后 4 个需要添加 iconfont ,且最后一个还需设计独特的样式属性,故构造类选择器 “menu” ,因此用 vue 可以设计如下结构:
<template> <div class=shortcut> <div class="left"> <a href="#"></a> </div> <div class="right"> <ul> <li v-for="p of Chapper" :key="p.id"><a href="#">{{ p.name }}</a></li> <li><a href="#"><span class="iconfont icon-icon-test"></span></a></li> <li><a href="#">EN</a></li> <li><a href="#">内部网</a></li> <li><a href="#" class="menu"><span class="iconfont icon-menu"></span></a></li> </ul> </div> </div> </template> <script> export default { name: 'ShortCut', data() { return { Chapper: [ {id:1,name:'学校概况'}, {id:2,name:'教育教学'}, {id:3,name:'科研实训'}, {id:4,name:'对外交流'}, {id:5,name:'招生就业'}, {id:6,name:'师资力量'}, {id:7,name:'人才招聘'}, {id:8,name:'校园生活'}, {id:9,name:'图书馆'} ], } }, } </script>
在 index.html 文件中要引入相应的 iconfont.css 文件:
<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="stylesheet" href="<%= BASE_URL %>css/base.css"> <!-- 用同样的方式引入 --> <link rel="stylesheet" href="<%= BASE_URL %>iconfont/iconfont.css"> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
设计接受 iconfont 引入的 span 标签 以及 最后一个 li 标签 的样式:
.shortcut .right li span { font-weight: 900; } .shortcut .right li .menu { display: block; padding-left: 15px; width: 50px; height: 50px; /* 设计圆形边框 */ border: 2px solid rgba(255, 255, 255, 0.4); border-radius: 50%; }
- 可以发现 顶部导航 存在 hover 属性,因此我们可以官网效果来设计 相应盒子的 hover 属性:
我们可以发现当鼠标悬停在 shortcut 盒子上时 ,logo 图、背景颜色、字体颜色发生了变化。即:
.shortcut:hover { background-color: #fff; } .shortcut:hover .left a { background: url(./images/logoh.png) no-repeat center; background-size: contain; /* 1 */ } .shortcut:hover .right li a { color: #909195; }
接着可以发现当鼠标悬停在 li 标签里的 a 标签上时,盒子底部出现移动的颜色条,且字体颜色和最后一个 li 标签的盒子属性值出现变化。即:
.shortcut .right li a:hover { color: #002f93; } .shortcut:hover .right li .menu { border: 2px solid rgba(150, 150, 150, 0.4); } .shortcut .right li .menu:hover { border: 2px solid #002f93; }
- 最后查看效果:
2、BanNer 组件
(注:之所以写成驼峰体,是因为 Eslint 要求 Vue.component 命名要求多个单词)
BanNer 组件用于设计 官网 banner 板块,之所以只有一张版图,是因为先用图片入手,而 video 会放在后面某个组件中设计。
- 简单地将整个 banner 板块设计为一个 a 标签作为一个盒子,并设计用于上传的 img 标签,再用一个 div 设置盒子将图片链接标题进行设计。
<template> <div class="banner"> <a href="#"> <img src="./uploads/mark.png" alt=""> <div class="text"> <span>{{ title }}</span> </div> </a> </div> </template>
设置 .banner 盒子 的 CSS 样式:
.banner { position: relative; overflow: hidden; }
设置 a 标签 、img 标签以及 .text 盒子的 CSS 样式:
.banner a { display: block; } .banner img { background: url(./uploads/mark.png) no-repeat center top; background-size: contain; } .banner .text { position: absolute; bottom: 10%; left: 10%; } .banner .text span { font-size: 34px; font-weight: 900; color: #000; }
- 并设计 script 部分:
<script>
export default {
name: 'BanNer',
data() {
return {
title: 'TITLE'
}
}
}
</script>
- 最后查看效果:
3、HighLight 组件
HighLight 组件用于设计官网上 “技大 · 焦点” 板块。
- 首先 设计一整个大盒子 HL 结合 wrapper 类属性
- 将 HL 分为 top 和 bottom 两个部分
- top 分为 left 和 right 两个部分,并分别设计各自的内容
- 并且 bottom 可以分为 bottom1 和 bottom2
- bottom1 中设置 .pic 盒子 设计轮播图使用用
ul>li
结构,右侧用 .right 盒子设计图片 - bottom2 中同样设置
ul>li
结构
- bottom1 中设置 .pic 盒子 设计轮播图使用用
- 将 HL 分为 top 和 bottom 两个部分
<template> <div class="HL"> <div class="wrapper"> <div class="top"> <div class="left"> <strong>技大</strong><i></i><strong>焦点</strong><span>HIGHLIGHT</span> </div> <div class="right"> <a href="#" class="more"></a> </div> </div> <div class="bottom"> <div class="bottom1"> <div class="pic"> <ul> <li><a href='#'></a></li> <li><a href="#"></a></li> <li><a href="#"></a> </li> </ul> </div> <div class="right"> <ul> <li><a href="#" class="news"></a></li> </ul> </div> </div> <div class="bottom2"> <ul> <li><a href="#"></a></li> </ul> </div> </div> </div> </div> </template>
设计 HL 盒子 的 CSS 样式:
.HL { padding: 91px 0 80px; background-image: url(./images/bg1.jpg); background-size: cover; overflow: hidden; }
设计 HL 中的 top 盒子 的 CSS 样式:
.HL .top { display: flex; justify-content: space-between; height: 44.8px; } .HL .top .left strong { text-align: center; line-height: 44.8px; font-size: 34px; color: #26334d; } .HL .top .left i { display: inline-block; margin: 10px 10px; width: 8px; height: 9px; background: url(./images/d.png) no-repeat center; } .HL .top .left span { margin: 16px 0 0 20px; font-size: 18px; color: #828a99; } .HL .top .right { display: flex; } /* 设置按钮 */ .HL .top .right .more { display: block; margin-left: 6px; width: 140px; height: 45px; border: 1px solid #c2c5c7; border-radius: 100px; text-align: center; line-height: 45px; color: #26334d; transition: all 0.4s; }
设计 HL 中的 bottom 盒子 的 CSS 样式:
.HL .bottom { margin-top: 40px; } .HL .bottom1 { display: flex; justify-content: space-between; overflow: hidden; } .HL .bottom1 .pic { width: 810px; height: 449px; overflow: hidden; } .HL .bottom1 .pic ul { display: flex; } .HL .bottom1 .pic li a { position: relative; display: block; } .HL .bottom1 .right ul { display: flex; flex-direction: column; width: 400px; height: 449px; background: #FFF url(./uploads/SZTU.png) no-repeat 95%; background-size: 27%; } .HL .bottom1 .right li { flex: 1; transition: all 0.4s; } .HL .bottom2 ul { display: flex; justify-content: space-between; margin-top: 8px; height: 296px; } .HL .bottom2 li { background-color: #fff; } .HL .bottom2 ul { display: flex; justify-content: space-between; margin-top: 8px; height: 296px; } .HL .bottom2 li { background-color: #fff; }
- 接着查看一次效果:
- 随后设置 top.right、bottom1 和 bottom2 内容:
<!-- top.right --> <a href="#" v-for="p of Text" :key="p.id" class="more">{{ p.text }}</a>
<!-- bottom1.pic --> <ul> <li> <a href='#'> <img src="./images/纸盒人1.jpg" alt=""> <div class="text"> <p> <strong>01</strong> <span>2024</span>-<span>01</span> </p> <span class="content">focus标题</span> </div> <ol> <li class="current"></li> <li></li> <li></li> </ol> </a> </li> <li> <a href="#"> <img src="./uploads/focus.png" alt=""> <div class="text"> <p> <strong>01</strong> <span>2024</span>-<span>01</span> </p> <span class="content">focus标题</span> </div> <ol> <li></li> <li class="current"></li> <li></li> </ol> </a> </li> <li> <a href="#"> <img src="./uploads/focus.png" alt=""> <div class="text"> <p> <strong>01</strong> <span>2024</span>-<span>01</span> </p> <span class="content">focus标题</span> </div> <ol> <li></li> <li></li> <li class="current"></li> </ol> </a> </li> </ul>
<!-- bottom1.right --> <ul> <li v-for="p of News" :key="p.id"> <a href="#" class="news"> 校园新闻 · <p>{{ p.date }}</p> <strong>{{ p.context }}</strong> <span>查看详情<i class="iconfont icon-icon-test2"></i></span> </a> </li> </ul>
<!-- bottom2 --> <ul> <li v-for="q of Pic" :key="q.id"> <a href="#"> <div class="pic"> <img src="./uploads/focuss.png" alt=""> <span>{{ q.topic }}</span> </div> <div class="text"> <span>{{ q.content }}</span> </div> </a> </li> </ul>
- 以及相应的 vue.js:
<script> export default { name: 'HighLight', data() { return { Text: [ {id:1,text:'校园新闻'}, {id:2,text:'媒体聚焦'} ], News: [ {id:1,date:'2024/01/01',context:'新闻内容'}, {id:2,date:'2024/01/01',context:'新闻内容'}, {id:3,date:'2024/01/01',context:'新闻内容'} ], Pic: [ {id:1,topic:'新闻标题',content:'新闻内容'}, {id:2,topic:'新闻标题',content:'新闻内容'}, {id:3,topic:'新闻标题',content:'新闻内容'} ], } }, } </script>
- 还有各个内容的 CSS 样式:
/* bottom1.pic */
.HL .bottom1 .pic li img {
width: 810px;
height: 449px;
vertical-align: middle;
}
.HL .bottom1 .pic li .text {
position: absolute;
left: 0;
bottom: 0;
display: flex;
padding: 24px 40px;
width: 100%;
height: 117px;
background-color: rgba(0, 47, 147, 0.9);
color: #fff;
}
.HL .bottom1 .pic li .text p strong {
display: block;
height: 50px;
font-size: 42px;
line-height: 50px;
}
.HL .bottom1 .pic li .text p span {
font-size: 12px;
}
.HL .bottom1 .pic li .text .content {
margin-left: 30px;
line-height: 69px;
font-size: 22px;
}
.HL .bottom1 .pic ol {
position: absolute;
bottom: 52px;
right: 24px;
display: flex;
}
.HL .bottom1 .pic li ol li {
display: block;
margin: 3px 10px;
width: 8px;
height: 8px;
background-color: #5677b7;
border-radius: 50%;
cursor: pointer;
}
.HL .bottom1 .pic li .current {
margin: 0 7px;
width: 14px;
height: 14px;
background-color: rgba(0, 47, 147, 1);
border: 3px solid #f0a700;
}
/* bottom1.right */
.HL .bottom1 .right li .news {
display: block;
margin: 0 40px;
padding: 24px 0;
height: 100%;
font-size: 14px;
color: #828A99;
border-top: 1px solid #e7e6e6;
transition: all 0.4s;
}
.HL .bottom1 .right li:first-child .news {
border: none;
}
.HL .bottom1 .right li .news p {
display: inline-block;
margin-bottom: 9px;
}
.HL .bottom1 .right li .news strong {
display: block;
margin-bottom: 25px;
color: #26334d;
transition: all 0.4s;
}
.HL .bottom1 .right li .news span {
font-size: 15px;
color: #828a99;
transition: all 0.4s;
}
.HL .bottom1 .right li .news .iconfont {
margin-left: 4px;
font-weight: 900;
}
/* bottom2 */
.HL .bottom2 li a .pic {
position: relative;
}
.HL .bottom2 li a .pic img {
width: 402px;
background-color: skyblue;
}
.HL .bottom2 li a .pic span {
position: absolute;
left: 0;
bottom: 0;
width: 80px;
height: 33px;
background-color: #002f93;
text-align: center;
line-height: 33px;
font-size: 12px;
color: #fff;
}
.HL .bottom2 li a .pic span::after {
content: '';
position: absolute;
right: -31px;
width: 31px;
height: 33px;
background: url(./uploads/tip02.png) no-repeat;
}
.HL .bottom2 li a .text {
padding: 22px 20px;
}
.HL .bottom2 li a .text span {
font-size: 18px;
color: #26334d;
}
- 最后查看整体效果:
4、ARP 组件
ARP 组件用于设计官网 “教学 科研 实训” 板块。
- 首先一如既往地设置基础的属性:将整个板块设置 .arp 选择器,结合 .wrapper 选择器
- 将板块分为 top、mid1、mid2、bottom
- top 分为 left、right
- mid1 由
ul>li
组成 - mid2 分为 left、right
- 同时由于 mid2.right 的特点,为其再加上一个盒子 .floater
- bottom 分为 left、right
- 而 bottom.left 又分为 title 部分 和 content 部分
- title 由 bottom.left.title.left 和 bottom.left.title.right 组成。
- 而 bottom.left 又分为 title 部分 和 content 部分
- 将板块分为 top、mid1、mid2、bottom
<template> <div class="arp"> <div class="wrapper"> <div class="top"> <div class="left"> <strong>教学</strong><i></i><strong>科研</strong><i></i><strong>实训</strong> <span>ACADEMICS, RESEARCH AND PRACTICE</span> </div> <div class="right"> <a href="#" class="more"></a> </div> </div> <div class="mid1"> <ul> <li></li> <li></li> <li></li> </ul> </div> <div class="mid2"> <div class="left"> <a href="#"></a> </div> <div class="right"> <div class="floater"> <ul> <li v-for="p of Search" :key="p.id"></li> </ul> </div> </div> </div> <div class="bottom"> <div class="left"> <div class="title"> <div class="left1"> <strong>对外交流</strong><span>EXCHANGES AND COMMUNICATION</span> </div> <div class="right1"> <a href="#" class="more"></a> </div> </div> <div class="content"> <div> <a href="#"></a> </div> </div> </div> <div class="right"> <img src="./images/TOM_0988.png" alt=""> </div> </div> </div> </div> </template>
则 .arp 选择器 的 CSS 样式:
.arp { background-color: #e9ecee; padding-bottom: 76px; overflow: hidden; } .arp .wrapper { padding: 50px 0 61px; background: url(./uploads/bg22.jpg) no-repeat; background-size: cover; }
- 设置各部分内容的 CSS 样式:
/* top 盒子 */ .arp .top { display: flex; justify-content: space-between; padding: 0 30px; overflow: hidden; } .arp .top .left strong { text-align: center; line-height: 44.8px; font-size: 34px; color: #fff; } .arp .top .left i { display: inline-block; margin: 10px 10px; width: 8px; height: 9px; background: url(./images/d1.png) no-repeat; font-size: 0; } .arp .top .left span { display: block; margin-top: 11px; font-size: 18px; color: #fff; opacity: 0.4; } /* right */ .arp .top .right { display: flex; margin: 48px 0 30px; } .arp .top .right .more { display: block; margin-left: 6px; width: 140px; height: 45px; border: 1px solid rgba(255, 255, 255, 0.4); border-radius: 100px; text-align: center; line-height: 45px; color: #cbd1e6; transition: all 0.4s; }
/* mid1 盒子 */ .arp .mid1 { background-color: #f3f6fb; height: 418px; overflow: hidden; } .arp .mid1 ul { display: flex; } .arp .mid1 li { position: relative; }
/* mid2 盒子 */ .arp .mid2 { display: flex; justify-content: space-between; } .arp .mid2 .left { display: flex; justify-content: space-between; margin: 15px 0 0 25px; width: 650px; height: 350px; } .arp .mid2 .right { position: relative; width: 527px; height: 447px; background: url(./images/dun.png) no-repeat bottom; background-size: cover; } .arp .mid2 .right .floater { position: absolute; top: -73px; width: 527px; height: 294px; background-color: #fff; } .arp .mid2 .right .floater ul { display: flex; flex-direction: column; width: 100%; height: 100%; } .arp .mid2 .right .floater li { display: block; flex: 1; }
/* bottom 盒子 */ .arp .bottom { display: flex; justify-content: space-between; overflow: hidden; } .arp .bottom .left { margin: 36px 0 0 30px; width: 858px; height: 504px; } /* .bottom .title */ .arp .bottom .title { display: flex; justify-content: space-between; } .arp .bottom .title .left1 strong { text-align: center; line-height: 44.8px; font-size: 34px; color: #FFF; } .arp .bottom .title .left1 span { margin: 11px 0 0 20px; font-size: 18px; color: #FFF; opacity: 0.6; } .arp .bottom .title .right1 { display: flex; margin-top: 12px; } .arp .bottom .title .right1 .more { display: block; margin-left: 6px; width: 140px; height: 45px; border: 1px solid #c2c5c7; border-radius: 100px; text-align: center; line-height: 45px; font-size: 15px; color: #c3c9e2; transition: all 0.4s; } .arp .bottom .content { height: 446px; overflow: hidden; } .arp .bottom .right { position: relative; width: 245px; height: auto; } .arp .bottom .right img { position: absolute; right: 25px; display: block; }
- 随后检查效果:
- 接着给各部分添加内容:
对于 .top.right :
<a href="#" v-for="p of Text" :key="p.id" class="more">{{ p.text }}</a>
对于 .mid1:
<li> <a href="#"> <div class="text"> 科学研究 · <p>2024/01/01</p> <strong>新闻标题</strong> <h2>简介</h2> <span>查看详情<i class="iconfont icon-icon-test2"></i></span> </div> <img src="#" alt="待上传的图片"> </a> <ol> <li class="current"><a href="#"></a></li> <li><a href="#"></a></li> <li><a href="#"></a></li> </ol> </li> <li> <a href="#"> <div class="text"> 科学研究 · <p>2024/01/01</p> <strong>新闻标题</strong> <h2>简介</h2> <span>查看详情<i class="iconfont icon-icon-test2"></i></span> </div> <img src="#" alt="待上传的图片"> </a> <ol> <li><a href="#"></a></li> <li class="current"><a href="#"></a></li> <li><a href="#"></a></li> </ol> </li> <li> <a href="#"> <div class="text"> 科学研究 · <p>2024/01/01</p> <strong>新闻标题</strong> <h2>简介</h2> <span>查看详情<i class="iconfont icon-icon-test2"></i></span> </div> <img src="#" alt="待上传的图片"> </a> <ol> <li><a href="#"></a></li> <li><a href="#"></a></li> <li class="current"><a href="#"></a></li> </ol> </li>
对于 .mid2.left:
<img src="#" alt="待上传的图片"> <div class="text">{{ p.text }}</div> <div class="date">{{ p.date }}<i class="iconfont icon-icon-test2"></i></div>
对于 .mid2.right:
<li v-for="p of Search" :key="p.id"> <a href="#"> 科学研究 · <span>{{ p.date }}</span> <h2>{{ p.msg }}</h2> </a> <hr> </li>
对于 .bottom.left.right1:(同理 == top.right)
对于 .bottom.left.content:
<div v-for="p of Box" :key="p.id" class="msg"> <a href="#" :id="bottom_left_show == true ? 'testenterY' : 'testY'"> <img src="#" alt="待上传的图片"> <div class="text"> <div class="topic">文章标题</div> <span>内容简介</span> <div class="date"> <p>2024/01/01</p> <i class="iconfont icon-icon-test2"></i> </div> </div> </a> </div>
- 然后添加各部分内容的 CSS 样式:
/* mid1 */ .arp .mid1 li a { display: flex; justify-content: space-between; margin: 0 0 73px; width: 1220px; } .arp .mid1 li a .text { position: relative; padding: 49px 0 0 62px; width: 489px; height: 274px; font-size: 14px; color: #26334d; } .arp .mid1 li a .text p { display: inline-block; } .arp .mid1 li a .text strong { display: block; margin-top: 19px; font-size: 28px; } .arp .mid1 li a .text h2 { margin-top: 24px; font-size: 15px; } .arp .mid1 li a .text span { position: absolute; bottom: 0; display: block; padding-left: 21px; width: 140px; height: 40px; border: 1px solid #002f93; border-radius: 100px; line-height: 40px; font-size: 12px; color: #002f93; transition: all 0.4s; } .arp .mid1 li a .text i { position: absolute; top: 4px; right: 4px; width: 30px; height: 30px; background-color: #002f93; border-radius: 50%; text-align: center; line-height: 30px; color: #fff; } .arp .mid1 li a img { display: block; width: 613px; height: 345px; background-color: pink; } .arp .mid1 li ol { position: absolute; bottom: 30px; left: 607px; display: flex; } .arp .mid1 li ol li { margin: 3px 10px; width: 8px; height: 8px; background-color: #a5a7aa; border-radius: 50%; cursor: pointer; } .arp .mid1 li ol .current { margin: 0 7px; width: 14px; height: 14px; background-color: #f3f6fb; border: 3px solid #f0a700; }
/* mid2.left */ .arp .mid2 .left img { display: block; width: 317px; height: 177px; background-color: pink; } .arp .mid2 .left .text { margin-top: 15px; height: 80px; font-size: 18px; font-weight: 900; color: #FFF; transition: all 0.4s; } .arp .mid2 .left .date { position: relative; margin-top: 15px; padding: 19px 0; font-size: 14px; color: #fff; border-bottom: 1px solid rgba(255, 255, 255, 0.2); transition: all 0.4s; } .arp .mid2 .left .date i { position: absolute; right: 0; top: 16px; font-size: 18px; font-weight: 900; opacity: 0.2; }
/* mid2.right */ .arp .mid2 .right .floater a { position: relative; display: block; width: 100%; height: 100%; padding: 22px 26px; font-size: 14px; color: #26334d; transition: all 0.4s; } .arp .mid2 .right .floater h2 { margin-top: 9px; font-size: 16px; color: #26334d; transition: all 0.4s; } .arp .mid2 .right .floater li hr { /* 2 */ position: absolute; left: 26px; width: 475px; /* height: 2px; */ color: #e7e6e6; /* border-width: 0; */ }
/* bottom.left.content */ .arp .bottom .content .msg { position: relative; padding: 25px 0; overflow: hidden; } .arp .bottom .content .msg::before { content: ''; width: 0; height: 1px; position: absolute; left: 0; bottom: 0; background: #f0a700; transition: all 0.4s; } .arp .bottom .content .msg::after { content: ''; width: 100%; height: 1px; position: absolute; left: 0; bottom: 0; background: rgba(255, 255, 255, 0.2); } .arp .bottom .content .msg a { display: flex; justify-content: space-between; } .arp .bottom .content .msg img { display: block; width: 257px; height: 171px; background-color: skyblue; } .arp .bottom .content .msg .text { position: relative; width: 575px; height: 171px; } .arp .bottom .content .msg .text .topic { margin-top: 8px; font-size: 18px; font-weight: 900; color: #FFF; transition: all 0.4s; } .arp .bottom .content .msg .text span { display: block; margin-top: 17px; font-size: 15px; color: #fff; opacity: 0.6; transition: all 0.4s; } .arp .bottom .content .msg a .text .date { position: absolute; bottom: 0; left: 0; display: flex; justify-content: space-between; width: 575px; font-size: 14px; color: #fff; opacity: 0.6; transition: all 0.4s; } .arp .bottom .content .msg .text .date p { display: block; font-size: 14px; color: #fff; transition: all 0.4s; }
- 并且别忘了 vue 的 script:
<script> export default { name: 'ARP', data() { return { Text: [ {id:1,text:'校企合作'}, {id:2,text:'教学研究'}, {id:3,text:'科学实训'}, ], Article: [ {id:1,text:'文章内容',date:'2024/01/01'}, {id:2,text:'文章内容',date:'2024/01/01'}, ], Search: [ {id:1,date:'2024/01/01',msg:'校企合作'}, {id:2,date:'2024/01/01',msg:'教学研究'}, {id:3,date:'2024/01/01',msg:'科学实训'}, ], BOttom: [ {id:1,text:'国际交流'}, {id:2,text:'学生境外交流'}, ], Box: [ {id:1,topic:'文章内容',content:'内容简介',date:'2024/01/01'}, {id:2,topic:'文章内容',content:'内容简介',date:'2024/01/01'}, ], } }, } </script>
- 最后查看效果:
5、CampusLift 组件
CampusLift 组件是用来设计官网中 “活力技大” 板块。
- 首先将整个板块设计为 video 和 life 两个盒子。
- video 在引入 video 标签后可以继续分为 top 和 bottom
- 其中 top 又分为 left 和 right
- 同样 bottom 也分为 left 和 right
- life 结合 wrapper,可以简单地分为 left 和 right 两个部分
- video 在引入 video 标签后可以继续分为 top 和 bottom
<template> <div class="video"> <video src="#">待上传视频</video> <div class="top wrapper"> <div class="left"> <strong>活力技大</strong> <span>CAMPUS LIFE</span> </div> <div class="right"> <a href="#" class="more"></a> </div> </div> <div class="bottom wrapper"> <div class="left"> <span>01 / 01</span> <strong>视频标题</strong> </div> <div class="right"></div> </div> </div> <div class="life"> <div class="wrapper"> <div class="left"> <ul> <li><a href="#"></a></li> </ul> </div> <div class="right"> <a href="#"> <img src="./images/纸盒人1.jpg" alt="待上传的图片"> </a> </div> </div> </div> </template>
- 随后设置各个盒子的样式:
对于 video
.video { position: relative; } .video video { width: 100%; height: 762px; background-color: rosybrown; }
对于 video.top:
.video .top { position: absolute; top: 56px; left: 10%; display: flex; justify-content: space-between; } .video .top .left strong { text-align: center; line-height: 44.8px; font-size: 34px; color: #fff; } .video .top .left span { display: block; margin-top: 6px; font-size: 18px; color: #fff; opacity: 0.4; } .video .top .right { display: flex; vertical-align: middle; } .video .top .right .more { display: block; margin: 14px 0 0 6px; width: 140px; height: 45px; border: 1px solid rgba(255, 255, 255, 1); border-radius: 100px; text-align: center; line-height: 45px; font-size: 15px; color: #fff; transition: all 0.4s; }
对于 video.bottom:
.video .bottom { position: absolute; bottom: 50px; left: 10%; display: flex; justify-content: space-between; } .video .bottom .left strong { margin-top: 10px; text-align: center; line-height: 44.8px; font-size: 34px; color: #fff; } .video .bottom .left span { display: block; font-size: 16px; color: #fff; } .video .bottom .right { display: flex; align-items: center; text-align: center; line-height: 50px; }
对于 life:
.life { background: url(./images/bg1.jpg) no-repeat; block-size: contain; } .life .wrapper { display: flex; justify-content: space-between; padding: 76px 0; } .life .left { position: relative; width: 490px; height: 539px; overflow: hidden; } .life .left li { position: relative; } .life .left li a { position: absolute; display: block; width: 235px; height: 235px; background-color: skyblue; } .life .right { flex: 1; overflow: hidden; } .life .right a { display: block; width: 100%; height: 490px; background-color: orchid; } .life .right img { display: block; width: 100%; height: 100%; }
- 现在查看代码效果:
- 接着给各部分添加内容:
对于 video.top:
<a href="#" v-for="p of Link" :key="p.id" class="more">{{ p.text }}</a>
对于 video.bottom:
<i class="iconfont icon-icon-test1"></i> <i class="iconfont icon-icon-test3"></i> <i class="iconfont icon-icon-test2"></i>
对于 life:
<li v-for="p of Move" :key="p.id"> <a href="#"> <img src="" alt="待上传的图片"> <div class="text"> <span>{{ p.topic }}</span> <i class="iconfont icon-icon-test2"></i> </div> </a> </li>
- 还有 vue.script:
<script> export default { name: 'CampusLife', data() { return { Link: [ {id:1,text:'视觉技大'}, {id:2,text:'学生活动'} ], Move: [ {id:1,topic:'TOPIC'}, {id:2,topic:'TOPIC'}, {id:3,topic:'TOPIC'}, {id:4,topic:'TOPIC'} ], } }, } </script>
- 然后添加剩下的 CSS 元素:
/* video.bottom */ .video .bottom .right i { display: block; margin: 0 5px; width: 50px; height: 50px; border: 1px solid #fff; border-radius: 50%; color: #fff; transition: all 0.4s; } .video .bottom .right i:nth-child(2) { background-color: #fff; font-size: 24px; color: #f0a700; }
/* life */ .life .left li:nth-child(2) a { top: 245px; left: 0; } .life .left li:nth-child(3) a { top: 48px; left: 245px; } .life .left li:nth-child(4) a { top: 293px; left: 245px; } .life .left li img { display: block; width: 100%; height: 100%; } .life .left li .text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; text-align: center; line-height: 31px; } .life .left li .text span { display: block; font-size: 18px; font-weight: 900; color: #fff; } .life .left li .text i { display: block; margin: 9px 10px 0; width: 31px; height: 31px; border: 1px solid #fff; border-radius: 50%; color: #fff; }
- 最最后看效果:
6、BotTom 组件
BotTom 组件是用来设计官网的最后一板块。
- 首先将整个板块设计为 footer 盒子并且与 wrapper 结合。
- 首先用
ul>li
来设置各个小盒子,接着设计 contact 和 copyright 两个盒子- 其中 contact 又分为 left、center 和 right
- 首先用
<template> <div class="footer"> <div class="wrapper"> <ul> <li><a href="#"></a> </li> </ul> <div class="contact"> <div class="left"> <a href="#"><img src="./images/logob.png" alt=""></a> </div> <div class="center"> <dl> <dt></dt> <dd></dd> </dl> </div> <div class="right"> <a href="#"></a> </div> </div> <div class="copyright"> Copyright © 2018深圳技术大学 版权所有 <a href="#">粤ICP备16106131号</a> </div> </div> </div> </template>
- 随后设置各个盒子的样式:
对于 footer:
.footer { padding-top: 30px; background: url(./images/footerbg.jpg) no-repeat center top; background-size: cover; border-top: 5px solid orange; } .footer .wrapper { padding: 18px 0 6px; }
对于 .footer ul:
.footer ul { display: flex; flex-wrap: wrap; justify-content: space-evenly; } .footer li { width: 237px; height: 120px; margin-top: 6px; } .footer li a { position: relative; display: block; background-color: rgba(0, 0, 0, 0.1); padding: 12px 0; border-radius: 4px; transition: all 0.4s; } .footer li a::before { content: ''; width: 0; height: 4px; position: absolute; left: 0; bottom: 0; background: #f0a700; transition: all 0.4s; }
对于 footer.contact:
.footer .contact { display: flex; justify-content: space-between; margin-top: 23px; padding: 30px 0 122px; height: 153px; border-top: 6px solid orange; border-bottom: 1px solid rgba(255, 255, 255, 0.2); } .footer .contact .left { width: 331px; height: 55px; } .footer .contact .left img { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; } .footer .contact .center { display: flex; } .footer .contact .center dl { margin-right: 67px; } .footer .contact .center dt { font-size: 15px; color: #fff; opacity: 0.6; } .footer .contact .center dd { margin-top: 10px; color: #fff; } .footer .contact .right { display: flex; } .footer .contact .right a { display: block; margin: 0 5px; width: 50px; height: 50px; border: 1px solid rgba(255, 255, 255, 0.4); border-radius: 50%; transition: all 0.4s; }
对于 copyright:
.footer .copyright { padding: 18px 0; font-size: 12px; color: #B2BBDA; } .footer .copyright a { font-size: 14px; color: #fff; opacity: 0.6; transition: all 0.4s; }
- 现在查看代码效果:
- 接着给各部分添加内容:
对于 footer.ul:
<li v-for="p of Icon" :key="p.id"> <a href="#"> <div class="pic"><img :src="p.src" alt=""></div> <span>{{ p.name }}</span> </a> </li>
对于 footer.contact:
<dl v-for="p of DL" :key="p.id"> <dt>{{ p.title }}</dt> <dd>{{ p.text }}</dd> </dl> <a href="#" v-for="p of Out" :key="p.id"> <img :src="p.src" alt=""> </a>
- 还有 vue.script:
<script> export default { name: 'BotTom', data() { return { Icon: [ {id:1,src:require("./images/logo00_trim.png"),name:'研究生院'}, {id:2,src:require("./images/logo01.png"),name:'中德智能制造学院'}, {id:3,src:require("./images/logo02-1.png"),name:'大数据与互联网学院'}, {id:4,src:require("./images/logo03.png"),name:'新材料与能源学院'}, {id:5,src:require("./images/logo04.png"),name:'城市交通与物流学院'}, {id:6,src:require("./images/logo05.png"),name:'健康与环境工程学院'}, {id:7,src:require("./images/gcwl.png"),name:'工程物理学院'}, {id:8,src:require("./images/logo07.png"),name:'质量和标准学院'}, {id:9,src:require("./images/logo08.png"),name:'药学院'}, {id:10,src:require("./images/logo09.png"),name:'未来技术学院'}, {id:11,src:require("./images/logo010.png"),name:'创意设计学院'}, {id:12,src:require("./images/logo011.png"),name:'商学院'}, {id:13,src:require("./images/logo012.png"),name:'外国语学院'}, {id:14,src:require("./images/logo020.png"),name:'集成电路与光电芯片学院'}, {id:15,src:require("./images/logo014.png"),name:'马克思主义学院(人文社科学院)'}, {id:16,src:require("./images/logo015.png"),name:'体育与艺术学院'}, {id:17,src:require("./images/musicyyds_logo2.png"),name:'音乐学院'}, {id:18,src:require("./images/fushi.png"),name:'服饰技术学院'} ], DL: [ {id:1,title:'联系方式',text:'0755-23256054'}, {id:2,title:'招生热线',text:'0755-23256666'}, {id:3,title:'地址',text:'广东省深圳市坪山区兰田路3002号'} ], Out: [ {id:1,src:require("./images/f1.svg")}, {id:2,src:require("./images/f2.svg")}, {id:3,src:require("./images/f3.svg")} ], } }, } </script>
- 然后添加剩下的 CSS 元素:
/* footer.ul */ .footer li a .pic { position: relative; height: 65px; vertical-align: middle; } .footer li a .pic img { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; opacity: 0.6; filter: grayscale(1) invert(1); transition: all 0.4s; } .footer li a span { display: block; margin-top: 12px; height: 20px; text-align: center; color: #fff; opacity: 0.6; font-size: 15px; transition: all 0.4s; }
- 最后效果:
五、设计动态样式
1、:hover 样式
根据官网效果可知:当鼠标悬停在某个部件上方时,该部件会产生变化。
接下来我将设置这类变化,或许与官网会有较大差异。
对于 ShortCut:
.shortcut:hover { background-color: #fff; } .shortcut:hover .left a { background: url(./images/logoh.png) no-repeat center; background-size: contain; /* 1 */ } .shortcut .right li:hover::before { width: 100%; } .shortcut .right li:last-child:hover::before { width: 0; } .shortcut:hover .right li a { color: #909195; } .shortcut .right li a:hover { color: #002f93; } .shortcut:hover .right li .menu { border: 2px solid rgba(150, 150, 150, 0.4); } .shortcut .right li .menu:hover { border: 2px solid #002f93; }
对于 HighLight:
.HL .right .more:hover { background-color: #002f93; color: #FFF; } .HL .bottom1 .right li:hover { background-color: orange; } .HL .bottom1 .right li .news:hover { color: #FFF; } .HL .bottom1 .right li .news:hover strong, .HL .bottom1 .right li .news:hover span { color: #FFF; }
对于 ARP:
.arp .top .right .more:hover { background-color: #FFF; color: #26334d; } .arp .mid1 li a .text span:hover { background-color: #002f93; color: #FFF; } .arp .mid2 .left a:hover .text { color: orange; } .arp .mid2 .left a:hover .date { color: orange; border-bottom: 1px solid orange; } .arp .mid2 .left a:hover .date i { opacity: 1; } .arp .mid2 .right .floater a:hover { background-color: orange; color: #FFF; } .arp .mid2 .right .floater a:hover h2 { color: #FFF; } .arp .bottom .title .right1 .more:hover { background-color: #FFF; color: #26334d; } .arp .bottom .content .msg:hover::before { width: 100%; } .arp .bottom .content .msg a:hover .text .topic, .arp .bottom .content .msg a:hover .text span, .arp .bottom .content .msg a:hover .text .date { color: orange; opacity: 1; } .arp .bottom .content .msg a:hover .text .date p { color: orange; }
对于 CampusLift:
.video .top .right .more:hover { background-color: #fff; color: #002f93; } .video .bottom .right i:nth-child(1):hover, .video .bottom .right i:nth-child(3):hover { background-color: orange; border: 1px solid orange; }
对于 BotTom:
.footer li a:hover { background-color: #fff; } .footer li a:hover::before { width: 100%; } .footer li a:hover .pic img { opacity: 1; filter: grayscale(0) invert(0); } .footer li a:hover span { color: #26334d; opacity: 1; } .footer .contact .right a:hover { border: 1px solid #fff; } .footer .copyright a:hover { opacity: 1; }
2、vue.js 控制
我们可以看到当鼠标滚轮(scroll)下滑到一定位置时,web 的页面效果会产生动态变化。
由于本人未精通 vue.js 的特殊控制行为语句,只能用拙劣一般的代码来实现效果。
- 在各个组件几乎都用到了 mounted 命令、unmounted 命令和 methods 命令。
下面我会说明我使用这些命令的用法。
1、mounted 命令:
在 vue.js 中,mounted 可以将编译好的模板,挂载到页面指定的容器中。
我为 mounted 命令中使用了如下一串代码:
window.addEventListener("scroll",this.handleScroll);
这串代码用于在浏览器窗口滚动时触发一个事件,并调用一个名为 handleScroll 的函数。作用是将一个滚动事件(scroll)与一个处理函数 (handleScroll) 绑定在window对象上。当用户在浏览器窗口中滚动时,handleScroll 函数将被调用。
(handleScroll 函数将会在 methods 命令中说明)
2、unmounted 命令:
在 vue3 中,unmounted 可以取消挂载。
在 unmounted 中设置如下一串代码:
window.removeEventListener("scroll",this.handleScroll);
这串代码是用于移除滚事件监听器的方法。当调用 window.removeEventListener() 方法时,它会从window对象中移除指定的事件监听器。
- 注:在 vue2 中用 destroymounted 来实现相同效果。
- error:如果不添加取消挂载的代码,程序会出现一直执行 mounted 绑定的事件,导致程序运行的时候不会反应从而报错。
3、methods 命令:
在 vue.js 中,methods 负责集合定义的函数,程序调用的函数都从这里调用。
对于上面的 handleScroll 函数形式如下:
handleScroll() { let scrollTop = document.documentElement.scrollTop let flag if (scrollTop >= 200) { this.top_show = true flag = 1 } if (flag === 1) { this.top_show = true } }
在这个函数中,我定义了一个 scrollTop 变量,并把它赋值为 web 端与顶部的滚动距离(document.documentElement.scrollTop)。而 top_show 则是一种与绑定 style 样式有关的 boolen 。
使用 flag 变量是为了从函数内部确保变量的更改。
3、vue.js 控制的动态样式
从官网效果上可知滚动鼠标时的效果:
盒子从四面八方移动。
- 首先设置变化后的默认状态:(两个方向)
#testenterY{ transform: translateY(0%); opacity: 1; transition: all 2s; } #testenterX{ transform: translateX(0%); opacity: 1; transition: all 2s; }
- 接着是变化前:(下、左、右)
#testY{ transform: translateY(100%); opacity: 0; } #testXl{ transform: translateX(-100%); opacity: 0; } #testXr{ transform: translateX(100%); opacity: 0; }
- 最后把他们放入 index.css 文件中作为默认样式。
随后是程序判断是否调用函数的代码段:
- 在 ShortCut 中:
<!-- 在 template 中 --> <div :class="top_show == true ? 'shortcutScroll' : 'shortcut'"> <div class="left"> <a href="#"></a> </div> <div class="right"> <ul> <li v-for="p of Chapper" :key="p.id"><a href="#">{{ p.name }}</a></li> <li><a href="#"><span class="iconfont icon-icon-test"></span></a></li> <li><a href="#">EN</a></li> <li><a href="#">内部网</a></li> <li><a href="#" class="menu"><span class="iconfont icon-menu"></span></a></li> </ul> </div> </div> // 在 script 中 data() { return { top_show: false, } },
- 在 HighLight 中:
<!-- 在 template 中 --> <div class="top" :id="top_show == true ? 'testenterY' : 'testY'"></div> <div class="pic" :id="top_show== true ? 'testenterX' : 'testXl'"></div> <div class="right" :id="top_show == true ? 'testenterX' : 'testXr'"></div> <li v-for="q of Pic" :key="q.id" :id="bottom2_li_show == true ? 'testenterY' : 'testY'"></li> // 在 script 中 data() { return { top_show: false, bottom2_li_show: false, } },
- 在 ARP 中:
<!-- 在 template 中 --> <div class="top" :id="top_show == true ? 'testenterY' : 'testY'"></div> <a href="#" v-for="p of Article" :key="p.id" :id="mid2_show == true ? 'testenterY' : 'testY'"></a> <div class="floater" :id="mid2_show == true ? 'testenterY' : 'testY'"></div> <div class="title" :id="bottom_left_show == true ? 'testenterY' : 'testY'"></div> <a href="#" :id="bottom_left_show == true ? 'testenterY' : 'testY'"></a> // 在 script 中 data() { return { top_show: false, mid2_show: false, bottom_left_show: false, } },
- 在 CampusLift 中:
<!-- 在 template 中 --> <div class="top wrapper" :id="top_show == true ? 'testenterY' : 'testY'"></div> <div class="left" :id="bottom_left_show == true ? 'testenterY' : 'testY'"></div> <a href="#" :id="life_left_show == true ? 'testenterY' : 'testY'"></a> <a href="#" :id="life_left_show == true ? 'testenterX' : 'testXr'"></a> // 在 script 中 data() { return { top_show: false, bottom_left_show: false, life_left_show: false, } },
- 在 BotTom 中:
<!-- 在 template 中 --> <li v-for="p of Icon" :key="p.id" :id="top_show == true ? 'testenterY' : 'testY'"></li> // 在 script 中 data() { return { top_show: false, } },
至此项目效果制作完毕。
六、反思与结论
在这次的项目制作过程中,我深刻体会到了知识的不充足。
1、在关于 js 的行为控制过程中,并没有完全掌握 js 的用法,使程序运行较为粗略并复杂。
2、没有掌握轮播图的制作,使得无法更好贴近官网实际效果。
3、代码并没有结构化,使得部分代码较为糅杂或多余。
4、对于 vue 的使用不熟练,没法将 JavaScript 与 Vue 实现完美结合,例如对于 v-for 对于各个 li 的单独控制。
5、各种自身原因使得项目制作时长过长并简陋。
–
对于这次的反思,我将会针对性与计划性地学习前端基础知识。
以上代码均有 git 上传至 gitee。