创业分析平台Web端-三大前端核心语言详解-首页index
目录
web端目录
首页页组件结构标注
基础文档结构
头部元数据
应用根容器
导航栏区域
主要内容区
页脚区域
脚本区域
1.DOC TYPE类型声明
什么是W3C规范
HTML:定义网页结构和内容标签
CSS:定义网页样式和布局
DOM:定义如何通过脚本操作网页
Web API:定义各种浏览器API功能
2.定义语言
为什么设置lang
3.头部元素
什么是元数据
CSS文件引入
什么是 Element UI
4.body开始
什么是Vue
页面顶部导航栏
5
这体现了 CSS 设计中一个常见模式
6
7
8
首页主体内容部分
9 横幅区域
设计意图
10 统计数字区
11 功能特色区
这体现了前端开发中的“关注点分离”原则
12 最新动态区
核心开发理念
13 热门分析区
14 页脚部分
15 引入JS库和脚本文件
为什么CSS样式在一开始就导入,而JS脚本在最后才引入
本文是项目全栈实战-基于智能体、工作流、API模块化Docker集成的创业分析平台-CSDN博客项目web端中html文件的详细解析
源码在startup-analysis-platform/web端 at master · ceilf6/startup-analysis-platform · GitHub
web端目录
web端/
├── index.html # 网站首页
├── css/ # 样式文件夹
│ ├── common.css # 公共样式
│ └── index.css # 特定样式-首页
│
├── js/ # 脚本文件夹
│ ├── config.js # 配置文件
│ ├── common.js # 公共函数
│ ├── index.js # 首页特定逻辑
│ └── image-preload.js # 图片预加载
│
├── images/ # 图片资源文件夹
│ ├── logo.jpg # 网站logo
│ ├── logo-white.jpg # 白色版logo(页脚使用)
│ ├── avatar-default.jpg # 默认头像
│ └── banner-illustration.jpg # 首页横幅图片
│
└── pages/ # 子页面文件夹├── startup/ # 创业信息页面│ └── index.html├── analysis/ # 分析页面│ └── index.html├── ai-insights/ # AI洞察页面│ └── index.html├── user/ # 用户中心│ └── index.html├── login/ # 登录相关页面│ ├── index.html # 登录页│ └── register.html # 注册页├── news/ # 新闻页面│ └── index.html└── insights/ # 洞察页面└── index.html
下面我们就以web端目录下的首页index.html文件为例子进行解析
首页页组件结构标注
基础文档结构
<!DOCTYPE html>
- HTML5文档类型声明<html lang="zh-CN">
- HTML根元素,指定中文语言<head>...</head>
- 文档头部,包含元数据<body>...</body>
- 文档主体
头部元数据
<meta>
- 元数据标签,设置字符集和视口<title>
- 页面标题<link>
- 引入外部CSS文件
应用根容器
<div id="app">
- Vue.js应用的挂载点
导航栏区域
<header class="header">
- 语义化页头标签<div class="container">
- 内容居中容器<div class="logo">
- Logo区域容器<img>
- Logo图片<span>
- Logo文字
<nav class="nav">
- 导航菜单区域<a>
- 导航链接
<div class="user-info">
- 用户信息区(登录状态)<span>
- 欢迎文字<el-dropdown>
- Element UI下拉菜单组件<span>
- 下拉菜单触发元素<img>
- 用户头像<i>
- 下拉箭头图标
<el-dropdown-menu>
- 下拉菜单内容<el-dropdown-item>
- 下拉菜单选项
<div class="login-btns">
- 登录按钮区(未登录状态)<a>
- 登录/注册链接
主要内容区
-
<div class="main">
- 主内容区容器-
<section class="banner">
- 横幅区域<div class="container">
- 内容容器<div class="banner-content">
- 横幅文本内容<h1>
- 主标题<p>
- 描述文本<div class="banner-actions">
- 按钮区域<a>
- 按钮链接
<div class="banner-image">
- 横幅图片区域<img>
- 横幅插图
-
<section class="stats-section">
- 统计数字区域<div class="stats-grid">
- 统计数字网格<div class="stats-item">
- 单个统计项<div class="stats-number">
- 数字显示<div class="stats-label">
- 数字标签
-
<section id="features">
- 功能特点区域<h2>
- 区域标题<div class="features-grid">
- 功能卡片网格<div class="feature-card">
- 功能卡片<div class="feature-icon">
- 功能图标<h3>
- 功能标题<p>
- 功能描述
-
<section class="news-section">
- 新闻区域<div class="section-header">
- 区域标题栏<h2>
- 区域标题<a>
- "查看更多"链接
<div class="news-list">
- 新闻列表<div v-for>
- Vue循环渲染的新闻项
-
<section class="insights-section">
- 洞察分析区域- 结构类似新闻区域
-
页脚区域
<footer class="footer">
- 语义化页脚标签<div class="footer-content">
- 页脚内容区<div class="footer-logo">
- 页脚Logo<div class="footer-links">
- 页脚链接组<div class="link-group">
- 链接分组<h4>
- 链接组标题<a>
- 链接项
<div class="footer-contact">
- 联系方式区域
<div class="footer-bottom">
- 页脚底部区域<p class="copyright">
- 版权信息<div class="terms">
- 使用条款链接组
脚本区域
<script>
- 内联JavaScript和外部脚本引入
下面我们逐字逐句进行解析
1.DOC TYPE类型声明
<!DOCTYPE html>
告知浏览器引擎这是使用 HTML5 标准来解析文件,从而确保浏览器使用的是最新的渲染模式(按照W3C规范),而不是为了兼容旧网页的“怪异模式”
什么是W3C规范
W3C(World Wide Web Consortium,万维网联盟)是制定Web标准的国际组织,从而保证标准化、兼容性、可访问性,它包括:
HTML:定义网页结构和内容标签
CSS:定义网页样式和布局
DOM:定义如何通过脚本操作网页
DOM( Document Object Model 文件对象模型)是HTML、XML文档的编程接口和表现形式,它在浏览器中创建,将HTML页面转换为一个对象树,而 <div> 、<p> 等等标签划分出树上的一个个节点,这些标签的嵌套投射到树上就是父子关系
DOM和BOM(浏览器对象模型)以及JavaScript共同组成完整的JS生态
Web API:定义各种浏览器API功能
2.定义语言
<html lang="zh-CN">
其中的lang就是language的缩写
zh是中文的语言代码
CN是国家/地区代码 那么zh-CN就是中国大陆的简体中文的意思
其他常见的还有en英语、zh-TW台湾繁体
为什么设置lang
对于视障用户:帮助屏幕阅览器能正确使用发音规则
SEO搜索引擎优化:提高暴露率、浏览量
3.头部元素
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>创业分析平台</title><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-ui@2.15.10/lib/theme-chalk/index.css"><link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/index.css">
</head>
头部元素不会在浏览器里面显示,他的作用是保存元数据
什么是元数据
元数据是描述数据的数据,包含了网页的基本设置、资源引入
一般元数据用<meta >标签,meta时自闭合标签(因为它本身不包含内容,只用来定义属性和行为)
第一句定义了网页使用 UTF-8 作为字符编码,确保编码形式和解码形式一致、防止乱码
第二句 <meta name="viewport" 设置了页面在移动设备上的显示方式,content="width=device
-width 设置了页面宽度跟随设备屏幕宽度, initial-scale=1.0" 初始缩放比例为1(不缩放)
第三句 <title>创业分析平台</title> 设置了网页标签,显示在浏览器标签页、收藏夹、搜索引擎结果页,对SEO有重要作用
CSS文件引入
<link rel="stylesheet" href="https://cdn.jsdlivr.net/npm/element-ui@2.15.10/lib/theme-chalk/index.css">
引入 Element UI 组件库的样式,通过CDN(内容分发网络)加载
什么是 Element UI
Element UI是一个基于Vue.js框架的UI用户界面组件库,由饿了么前端团队开发和维护,专为网页开发提供现成的界面元素
特点有
统一的设计风格:所有组件库遵循相同的视觉设计规范和原则(简洁风),保证了应用界面风格的一致
丰富的组件:提供了大量常用的组件,比如:按钮、输入框,表格、表单,下拉菜单(比如我代码中的 <ek-dropdown> ),对话框、通知,导航、分页器等
响应设计:组件可以自适应不同屏幕的大小
由于我在前端算是个浅学者,所以我还是比较喜欢这种可以减少自己开发、专业的设计、有技术支持的组件库
<link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/index.css">
那么我在下面接着用 <link 导入了我自己在 CSS 文件夹下面的 common.css 和 index.css 文件
4.body开始
<div id="app"><!--页面顶部导航栏-->
< div >( division 分割、区块)是一个块级容器元素,主要用于划分页面结构、组合内容以及实现样式和交互控制
这句话划分了一个叫做 "app" 的区域,在 JS 代码里面会有对应的操作进行管理(这里的app区域是被被 Vue.js 管理,所以内部会有很多Vue特有的语法)
new Vue({el: '#app', // 这行代码将Vue实例与id="app"的div关联起来
什么是Vue
Vue是一款用于构建用户界面的渐进式 JavaScript 框架,通过组件化、响应式数据绑定等特性简化前端开发流程
有如下特征:
渐进式框架,无论从小型项目到大型项目都可以满足扩展功能
Vue将页面拆分为独立可复用的组件( .vue文件 ),复用率高
无需手动DOM
页面顶部导航栏
5
<header class="header">
<header 告诉了搜索引擎、辅助阅读等这是网页的头部区域,class="header"> 为这个标签添加了CSS类名,允许了CSS文件中使用 .header 选择器来为头部区域设置样式
还记得上面的<link rel="stylesheet" href="css/common.css">吗?是不是有点像导入头文件?在 common.css 文件中有对 类 的定义
/* 顶部导航栏样式 */
.header {background-color: #fff;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);position: sticky;top: 0;z-index: 100;
}.header .container {display: flex;align-items: center;height: 60px;justify-content: space-between;
}
backgroud-color: #fff 设置背景颜色为白色
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); 轻微阴影效果,轻微立体感
position: sticky; 粘性定位
top: 0; 粘附在顶部 用户滚动页面时导航栏会固定在顶部不动
z-index:100; 高层级确保导航栏不会被其他元素遮挡
下面的 .header .container 表示选择应用在 header类 中的 container类 元素
display: flex; 一维、简化、弹性布局
align-items: center; 所有元素垂直居中
height: 60px; 导航栏高度固定为60像素
justify-content:space-between; 水平方向均匀分布
在下一句就是定义了container类,对应了上面的 .header .container
<div class="container">
<div class="logo"><img src="images/logo.jpg" alt="创业分析平台" class="logo-img"><span class="logo-text">创业分析平台</span></div>
在此之下定义了一个叫做 logo 的类,<img scr="images/logo.jpg" 定义了图片的文件路径, alt="创业分析平台" 在图片无法显示时的替代文本,有利于SEO和无障碍访问,class="logo-img" 定义logo类,用于应用对应的样式,<span 和 <div 一样都是容器元素,但是 <div 默认会占据整行宽度,前后会自动换行,<span 只会占据内容需要元素、不会自动换行,适合用于行内元素,由于需要限定行范围,所以它和 <div 不一样,它有结束标签
可以看到在 logo 类下面有 logo-img 类和 logo-text 类,common.css 中有
.logo {display: flex; /* 使用Flex布局 */align-items: center; /* 子元素垂直居中对齐 */
}.logo-img {height: 32px; /* 固定图片高度 */margin-right: 10px; /* 图片右侧添加间距,与文字分开 */
}.logo-text {font-size: 18px; /* 文字大小设置 */
}
也许你会好奇,为什么不像 .header .container 一样写 .logo .logo-img,首先,浏览器解析CSS选择器是从右到左,那么我们定义少嵌套就能提高性能,减少对HTML结构的依赖,而为什么要在 .container 前面加 .header 是因为 container 定义是非常常见的,而每一处的 container 都不尽相同,所以我们得特定写
这体现了 CSS 设计中一个常见模式
通用类提供基础样式,嵌套选择器提供特定样式
回到我们的 css :在 .logo-img类 中height 定义了图片高度,margin-right 在图片右边添加了间距,和文字分开,.logo-text 中 font-size 设置了 文字font 大小
6
<nav class="nav"><a href="index.html" class="nav-item active">首页</a><a href="pages/startup/index.html" class="nav-item">创业信息</a><a href="pages/analysis/index.html" class="nav-item">分析</a><a href="pages/ai-insights/index.html" class="nav-item">AI洞察</a><a href="pages/user/index.html" class="nav-item">我的</a>
</nav>
<nav> 是HTML5的一个语义化标签,明确表示这是一个导航区域,提高了代码的可读性和辅助障碍,接着我们在 nav 类里面写了五个 <a> ,<a> 是HTML里面用于创建超链接的标签(anchor锚点),它能用于链接到其他网页(href写网页绝对路径-完整URL,如 href=“https://github.com/ceilf6"),跳转到同一页面的不同部分(在href中使用 # 号开头,后面跟目标元素的id属性,如 href="#features"),链接到文件下载( href指向文件资源的路径,如 href="files/report.pds" download="创业分析报告.pdf" ),触发JS事件(如 <a href="javascript:showLoginModal()">登录</a> 、 <a href="#" οnclick="showLoginModal(); return false;">登录</a> 、
<a href="javascript:void(0);" class="delete-btn">删除项目</a><!-- 在JavaScript中添加事件监听 -->
<script>
document.querySelector('.delete-btn').addEventListener('click', function(e) {e.preventDefault();deleteProject(123);
});
</script>
(在现代Web开发中,对于纯粹触发JS事件更加推荐 <button> 而非 <a> )
OK解析完 <a> 中的 href ,现在我们再来看看 class ,可以看到在 nav 类里面我们有两个类,一个是 nav-item 一个是 nav-item active,我们通过设置两个类区分了当前页面是在导航页中的哪一个,那么我们就可以对应的做出特殊的渲染,,比如用不同的颜色、边框等进行视觉区分,从而帮助用户一目了然地知道他身处何处
7
<div class="user-info" v-show="isLogin"><span class="welcome">欢迎,{{ userInfo.name || userInfo.username }}</span><el-dropdown @command="handleUserAction"><span class="el-dropdown-link"><img :src="userInfo.avatar || 'images/avatar-default.jpg'" alt="头像" class="avatar"><i class="el-icon-arrow-down el-icon--right"></i></span><el-dropdown-menu slot="dropdown"><el-dropdown-item command="profile">个人资料</el-dropdown-item><el-dropdown-item command="settings">设置</el-dropdown-item><el-dropdown-item divided command="logout">退出登录</el-dropdown-item></el-dropdown-menu></el-dropdown></div>
<div class="user-info" v-show="isLogin">
接着我们定义了 user-info 类,并且 v-show="isLogin" 明确了只有登录状态才会显示这个区域,当 isLogin 为 false 时不会显示 user-info(会显示注册按钮)
<span class="welcome">欢迎,{{ userInfo.name || userInfo.username }}</span>
接着用 span 写了一行欢迎语,其中 {{ }} 是不是看着有点像格式化输出,这双花括号是 Vue.js 中的特殊语法(Mustache语法,因为看着像胡子),它是 Vue 的数据绑定机制:动态数据渲染(JS表达式的结果输出到HTML里面)、响应式更新(数据变化时,页面自动更新而无需手动操作DOM),其中 || 是JS的逻辑或运算符,(通过有1出1的短路特性)实现了“备选值”的功能,那么这句话就会优先尝试 userInfo.name ,如果前者没有再试 userInfo.username
<el-dropdown @command="handleUserAction">
<el-dropdown> 是 Element UI 库提供的下拉菜单(点击触发元素、展开选项列表,提高空间利用率)组件,他分为两部分:触发元素、下拉菜单
这句代码中 @command="handleUserAction" 是事件绑定:其中@command是事件监听器(相当于Vue的@click),handleUserAction 方法是Vue实例中定义的一个方法,这句话实现了当用户点击任意带有 command 属性的菜单栏时,Element UI会自动将该菜单项的 command 属性作为参数传给 handleUserAction 方法,例如在我们这里有三种属性
<el-dropdown-menu slot="dropdown"><el-dropdown-item command="profile">个人资料</el-dropdown-item><el-dropdown-item command="settings">设置</el-dropdown-item><el-dropdown-item divided command="logout">退出登录</el-dropdown-item></el-dropdown-menu>
slot使用了Vue的插槽机制(slot),slot="dropdown" 告诉 el-dropdown 组件,这部分内容要放在dropdown插槽位置,<el-dropdown>是外层组件、<el-dropdown-menu>是要插到dropdown位置的内容,也就是上面的“下拉菜单”
在点击“个人资料”时传入参数profile,(钓鱼执法)脚本调用 handleUserAction("profile") ,
在 index.js 里面
// 用户下拉菜单操作处理handleUserAction(command) {switch (command) {case 'profile':window.location.href = 'pages/my/profile.html';break;case 'settings':window.location.href = 'pages/my/settings.html';break;case 'logout':Auth.logout();this.isLogin = false;this.userInfo = {};window.location.reload();break;}},
这样设计我们就可以用一个函数处理多个相关操作,在拓展菜单栏的时候只需要添加新的 case 就好
接着在 el-dropdown-link 类里面有:显示头像 <img:src="userInfo.avatar || images ..." alt=" " class=" "> 还是或语句实现备选图像,alt辅助SEO、障碍人群,class定义类届时进行样式渲染
8
<div class="login-btns" v-show="!isLogin"><a href="pages/login/index.html" class="btn-login">登录</a><a href="pages/login/register.html" class="btn-register">注册</a></div>
这段和上面 v-show="isLogin" 对应,在还没登录时提供两个链接,一个是登录、一个是注册,他们都使用 <a> 而非 <button>因为主要功能是导航而不是表单提交
首页主体内容部分
还是先用 div划分区域 叫做 main
9 横幅区域
<!-- 横幅区域 --><section class="banner"><div class="container"><div class="banner-content"><h1 class="banner-title">数据驱动的创业决策助手</h1><p class="banner-desc">通过大数据分析和AI技术,为创业者提供全方位的决策支持</p> <div class="banner-actions"><a href="pages/startup/index.html" class="btn btn-primary">开始分析</a><a href="#features" class="btn btn-outline">了解更多</a></div></div><div class="banner-image"><img src="images/banner-illustration.jpg" alt="创业分析平台" class="illustration"></div></div></section>
接着用了 <section ,他是HTML5的语义化标签-表示一个独立的内容区块,和div不同,它是由主体的,class="banner" 定义类应用css对应的样式
<section class="banner">
接着我们又一层层嵌套了类,方便区分css应用的样式
然后我们在里面写了 <h >(标题标签)、<p>(段落标签,会自动在前面留有空白间距)、<a>(前面介绍过的超链接标签)、<img>(图片标签)
设计意图
首先要吸引注意
接着表达我们这个网站的核心价值
并立即给出用户行动引导按钮 <a>
10 统计数字区
<!-- 统计数字区 --><section class="stats-section"><div class="container"><div class="stats-grid"><div class="stats-item"><div class="stats-number">{{ stats.companyCount }}</div><div class="stats-label">已分析企业</div></div><div class="stats-item"><div class="stats-number">{{ stats.insightsCount }}</div><div class="stats-label">AI洞察</div></div><div class="stats-item"><div class="stats-number">{{ stats.dataPoints }}万</div><div class="stats-label">数据点</div></div></div></div></section>
用上面介绍过的双花括号-Vue.js的胡子语法,传入来自 Vue实例(在index.js中创建)中定义的stats对象的动态数据
11 功能特色区
<!-- 功能特点区 --><section id="features" class="features-section"><div class="container"><h2 class="section-title">平台功能</h2><div class="features-grid"><div class="feature-card"><div class="feature-icon data-icon"></div><h3 class="feature-title">数据采集</h3><p class="feature-desc">自动抓取互联网公开数据,结合您提供的创业信息,构建全面的数据基础</p></div><div class="feature-card"><div class="feature-icon analysis-icon"></div><h3 class="feature-title">数据分析</h3><p class="feature-desc">通过Superset分析引擎,从多维度分析创业数据,挖掘潜在价值和风险</p></div><div class="feature-card"><div class="feature-icon ai-icon"></div><h3 class="feature-title">AI洞察</h3><p class="feature-desc">基于机器学习模型,预测创业成功率,生成SWOT分析和具体行动建议</p></div></div></div></section>
功能特色区主要通过文字直观地传达平台特色
但是里面掺了 data-icon 数据图表 类,而在 index.css 文件中有
.data-icon {background-image: url('../images/data-icon.svg');
}
上面是通过URL方式调用图片,我们也可以使用图标字体
.data-icon:before {content: "\f121"; /* 使用特定Unicode字符 */font-family: 'FontAwesome'; /* 图标字体 */font-size: 32px;color: #4285f4;
}
所以为什么不直接在html文件里面使用<img>而是要通过css的url呢?
1.<img> 位于html文件里面,是属于内容的一部分,而 css 中的 url 只是装饰,在屏幕阅读器、辅助技术等方面会有影响
2. css 里面可以灵活修改装饰,而且统一集中管理、便于维护
这体现了前端开发中的“关注点分离”原则
HTML负责结构,CSS负责表现,JS负责行为
12 最新动态区
<section class="news-section"><div class="container"><!-- 内容区 --></div>
</section>
首先定义了一块独立内容区域,然后通过 container类 提供局中布局和响应式宽度控制
<div class="section-header"><h2 class="section-title">最新动态</h2><a href="pages/news/index.html" class="more-link">查看更多</a>
</div>
.section-header {display: flex;justify-content: space-between;align-items: center;margin-bottom: 30px;
}
接着设置了 h2 级的标签,并附上链接,在 index.css 中有 section-header 的样式,可以看到应用了 flex弹性布局 ,设置了 justify-content:space-between 使元素分布在容器的两端,align-items:center 保证元素在垂直方向局中对齐,这是常见的左侧标题、右侧链接的布局
<div v-for="item in newsList" :key="item.id" class="news-item" @click="goToNewsDetail(item.id)">
这句代码使用了多个Vue语句:
v-for="item in newsList" 循环渲染,为 newsList 数组中的每条新闻创建一个分析卡片
:key 为每个列表项提供唯一标识符,帮助 Vue 优化渲染性能
@click 绑定点击事件,点击后调用 goToNewsDetail 方法,并传入参数 当前新闻ID
<div class="news-content"><h3 class="news-title">{{ item.title }}</h3><p class="news-summary">{{ item.summary }}</p><div class="news-meta"><span class="news-time">{{ item.publishTime }}</span></div>
</div>
通过胡子语法动态传入新闻标题、摘要、发布时间
<div class="news-image" v-if="item.coverUrl"><img :src="item.coverUrl" alt="新闻图片">
</div>
v-if="item.coverUrl" 判断:只有在存在封面时才显示图片区域
:src 也就是 v-blind:src 用于动态绑定图片(src是静态HTML属性,而 :scr 是Vue的动态绑定属性,绑定一个JS表达式作为资源路径)
<div v-if="newsList.length === 0" class="empty-tip">暂无最新动态
</div>
特判:用于空状态处理,可以注意到有三个等号,这是HTML中的严格相等判断,要求类型和值都相同,而两个等号在比较前会进行类型转换
数据来源:上面的 newsData 是在 index.js 中的实例
async fetchNews() {// 从API获取或使用模拟数据...const newsData = [{id: 1, title: '2025年创业趋势报告...', summary: '...', publishTime: '2025-05-05', coverUrl: './images/logo.png'},// 更多新闻数据...];this.newsList = newsData;
}
核心开发理念
声明式编程、数据驱动视图、关注点分离
13 热门分析区
<!-- 热门分析区 --><section class="insights-section"><div class="container"><div class="section-header"><h2 class="section-title">热门分析</h2><a href="pages/insights/index.html" class="more-link">查看更多</a></div><div class="insights-grid"><div v-for="item in insightsList" :key="item.id" class="insight-card" @click="goToInsightDetail(item.id)"><div class="insight-category">{{ item.category }}</div><h3 class="insight-title">{{ item.title }}</h3><p class="insight-summary">{{ item.summary }}</p><div class="insight-meta"><span class="insight-time">{{ item.publishTime }}</span></div></div><div v-if="insightsList.length === 0" class="empty-tip">暂无热门分析</div></div></div></section></div>
13 和 12 的结构差不多
section-container 又出现了,上面介绍过了,是用于实现两端对齐的左标题右链接的样式
接着还是 v-for 循环渲染,为 insightsList 中的每个元素都创建一个分析卡片
:key 绑定 为每个列表项都提供唯一标识,帮助 Vue 追踪 DOM 的变化
又是通过 @click 绑定 goToInsightDetail 方法
通过胡子语法传入动态数据
最后进行空状态判断
对应的 index.js 部分
// 数据部分
data() {return {insightsList: []};
},// 方法部分
methods: {async fetchInsights() {// 从服务器获取或使用模拟数据填充insightsList},goToInsightDetail(id) {// 导航到分析详情页window.location.href = `pages/insights/detail.html?id=${id}`;}
}
14 页脚部分
三层结构
<footer class="footer"><div class="container"> <!-- 容器层 --><div class="footer-content"> <!-- 主要内容区 --><!-- 三个内容块 --></div><div class="footer-bottom"> <!-- 底部版权区 --><!-- 版权信息 --></div></div>
</footer>
三个内容分别是:
1.网站品牌标识区
<div class="footer-logo"><img src="images/logo-white.jpg" alt="创业分析平台" class="logo-img"><span class="logo-text">创业分析平台</span>
</div>
可以看到这个结构是和顶部导航栏的logo保持一致的,提高了品牌的一致性
2.链接分组区
<div class="footer-links"><div class="link-group"><h4 class="group-title">关于我们</h4><a href="#" class="link-item">平台介绍</a><!-- 更多链接... --></div><!-- 更多链接组... -->
</div>
我先用 # 占位,后续会进行开发
3.联系信息区
<div class="footer-contact"><h4 class="group-title">联系方式</h4><p class="contact-item">邮箱:3506456886@qq.com</p><p class="contact-item">电话:19857907795</p><div class="social-links"><a href="#" class="social-item weixin">微信</a><!-- 等等社交平台 --></div>
</div>
这里没有通过 <img> ,而是通过 css样式 渲染类,方便维护 (在css中设计了flexbox布局、分组展示、响应式设计(在移动设备上会转为单列布局))
最后我们再进行版权声明
<div class="footer-bottom"><p class="copyright">© {{ new Date().getFullYear() }} 创业分析平台 版权所有</p><div class="terms"><a href="#" class="terms-link">隐私政策</a><a href="#" class="terms-link">使用条款</a></div>
</div>
使用Vue表达式 {{ new Date().getFullYear() }}
动态获取当前年份
15 引入JS库和脚本文件
为什么CSS样式在一开始就导入,而JS脚本在最后才引入
首先,CSS式渲染阻塞资源,浏览器得先下载和处理样式才能正确渲染页面,所以必须头部导入
而JS是解析阻塞资源,当浏览器遇到脚本时,会暂停DOM构建(还记得之前说的对象树吗),下载并执行脚本,所以假设我们将JS库和脚本在开头就导入,会导致页面加载时间变长,而且通常脚本需要操作DOM元素,所以在加载脚本的时候必须保证DOM已经完全构建,那么放在底部是最有保险的
接着我们看引入的内容
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/element-ui@2.15.10/lib/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.24.0/dist/axios.min.js"></script>
第一个是 Vue.js 架构(2.6.14),实现动态内容渲染和用户交互
然后导入 Element UI 组件库,因为 Element UI 组件库是依赖于 Vue.js 的所以它得在 Vue 后引入
第三个是 Axios ,是一个 HTTP请求库,用于处理与后端API的通信
<script src="js/config.js"></script>
<script src="js/common.js"></script>
config “配置”参数 js 脚本文件,包括API端口、环境变量等
第二个是 common 包含网站通用功能(比如Auth对象)、提供全局工具函数和共享逻辑
<script src="js/index.js"></script>
最后再导入 index 页面特定的 JS逻辑,包含 Vue 实例的创建、数据获取、事件处理,从而负责初始化统计数据、新闻列表、分析列表等动态内容
这种模块化分布式的处理方便我们后期进行维护