web学习笔记23-项目总结-爱代码爱编程
美食广场-项目总结
项目是程序员最好的锻炼神器,只有经过项目,才能真正检验知识的完整性。
本次项目是我在某内学习,跟着老师一步步写出来的,这种跟着老师思路走的项目,做完始终有种不太真实的感觉,虽然都是自己敲下的代码,但是整体的项目思想是不连贯的,因此,写一篇项目总结,将项目中的一些难点,还有整体的脉络梳理一下。在梳理过程中,我会按照我在gitee的提交顺序进行。
一、项目准备阶段
1.1,项目文件目录
在项目开发中,一个良好的文件目录,尤为重要,能帮助我们节省许多时间。例如,我们在使用express时,就会使用express创建出一个完整的项目目录结构,后续只需要在固定的结构下写入代码,就能快速构建好项目的服务器。
下面就是本次项目的文件目录结构,
-
common:公共样式css,公共js文件
-
components:公共组件(在项目开发中,对于像头部栏,侧边栏,底部这样频繁使用的地方,通常将代码抽离出去,形成一个单独的组件部分,在页面需要使用时,加载进来,一般称为组件化开发)
-
page:页面文件,每个页面文件包含完整的html,css,js文件
-
node_modules:项目中使用到的依赖(库)
-
index.html 项目的主体文件(项目采用SPA)
就是只有一张Web页面的应用。单页应用程序 (SPA) 是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。 浏览器一开始会加载必需的HTML、CSS和JavaScript,所有的操作都在这张页面上完成,都由JavaScript来控制。因此,对单页应用来说模块化的开发和设计显得相当重要。
1.2,基础样式、js库
在common文件中,css文件下写好样式重置文件,配置基础样式文件(例如版心样式等);
“*CSS 重置样式主要就是为了让各个浏览器的css样式有一个统一的基准。*我们可以通过重置样式,把浏览器的默认样式全部去掉,然后设置一个统一的标准。这样我们的网页在不同的浏览器下显示的效果就是一个的了
在js文件夹下,放置jQuery文件,方便后续项目中引用。
1.3,查看后端提供的API文档
后端工程师给到的项目开发文档,提供了请求的url,以及请求需要传递的参数,知道这些参数名,我们在构建页面的时候在关键位置使用同样的参数命名,对于后续的js操作会更加便捷。
二、项目开发阶段
2.1,html代码引入
在本项目中,采用SPA(单页面应用程序)的思想,因此如何将业务代码重新引入index页面,是我们需要解决第一项问题。
在本项目采用的方法使用的是监听hash变化的方法,来引入(切换)不同的功能页面
2.1.1 监听hash变化切换页面
demo
<body>
<div id="header">
<a href="#p=01.html">页面1</a>
<a href="#p=02.html">页面2</a>
<a href="#p=03.html">页面3</a>
<a href="#p=04.html">页面4</a>
</div>
<div id="main"></div>
<script src="../jquery/jquery.js"></script>
<script>
//addEventListener 监听事件,
//在hash变化时自动触发
addEventListener('hashchange',function(){
console.log('新的hash值:',location.hash);
console.log('截取字符串',location.hash.substr(1));
//如下获取p=xxx的字符串
let h = location.hash.substr(1)
//如下将h转为URLSearchParams对象,此对象专门用于处理url网址信息中的查询字符串
let params = new URLSearchParams(h)
//如下利用对象获取参数p的值
let p = params.get('p')
console.log(p);
//如下,利用load加载页面
$('#main').load(p)
})
</script>
</body>
需要说明的点:
-
addEventListener:是一个侦听事件并处理相应的函数,此处监听hash值得变化
-
location.hash:location对象的hash属性;hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)
-
URLSearchParams:URLSearchParams 对象提供了一些方法来操作查询参数,如获取参数值、添加新参数、删除参数等
-
load:加载数据,并把数据放置到指定的元素中
2.1.2 加载页面依赖文件
在加载完页面的html文件以后,需要将它的依赖文件一并引入,不然无法实现响应的效果。对于css文件直接拼接地址,使用模板用法就能引入。
//页面加载完毕以后,同步加载css文件
$(this).append(`<link rel="stylesheet" href="./pages/${p}/${p}.css">`)
但对于js文件则不能使用模板语法的方法引入,因为在脚本中再次写
const s = document.createElement('script')
s.src = `pages/${p}/${p}.js`
$(this).append(s)
2.2,GET请求,页面渲染
在本项目当中,除了页面基本的框架布局,其他内容都依靠通过后端获取数据后,利用js渲染动态生成的。在此项功能中,一是如何从后端获取数据,二就是如何使用css控制样式,是渲染页面满足设计要求。
在每一个功能页面的js中都会使用到get请求,并渲染页面。
发送请求模块
//url的值从api文档中复制
let url = 'https://serverms.xin88.top/mall?page=' + p
//jquer封装的get请求,$.get()直接调用
$.get(url, data => {
$('#mall-items').html(
data.data.map(value => {
//在服务器返回的数据中,解构需要的值
let { pic, name, price, sale_count } = value
//模板语法,拼接以后返回,渲染
return `
<li>
<img src="assets/img/mall/${pic}" alt="">
<div>
<p>${name}</p>
<div>
<span class="price">¥${price}</span>
<span class="sale">月售${sale_count}</span>
</div>
</div>
</li>
`
})
)
2.3,分页功能
页面的分页功能在后端是分页查询路由模块获取到本页查询的开始值start,每页返回的数据量size;在前端效果上,则是一些页码,点击之后进行切换,每页固定多少个页码,超过之后页码需要变化,另外,需要上下页的翻页按钮,这就是最基础的分页功能;后端的分页功能在前后端分离的今天,不需要考虑,我们只需要根据服务器返回当前页码值和总的页码数量,在前端实现分页就行。
前端js文件,分页功能模块:
根据服务器数据,解构当前页码和总的页码数
let { page, pageCount } = data
本项目中,固定显示5页
//最多显示五页
let start = page - 2
let end = page + 2
if (start < 1) {
start = 1
end = start + 4
}
if (end > pageCount) {
end = pageCount
start = end - 4
}
获得数据之后,在页面渲染出来,渲染之前的清空操作很有必要,因为这里循环添加必须使用append()这个追加,而不是html()的覆盖式渲染
//清空
$('.pages>ul').empty()
for (let i = start; i <= end; i++) {
$('.pages>ul').append(`<li class="${page == i ? 'active' : ''}">${i}</li>`)
}
因分页功能需要使用到请求服务器返回的数据,因此在项目中将页码渲染和页面渲染都封装成了函数getData()
因此,需要初始化就要调用一下函数
getData(1)//1是传入的页码,初始化时显示第一页的数据
为页码添加函数,使得点击时显示的数据能够发生变化
//利用事件委托机制
$('.pages>ul').on('click', '>li', function () {
let pno = $(this).html()
getData(pno)
})
实现了页码切换以后,我们还需要,上下页的按钮,也为其添加事件,使其点击时也能发生页面的改变
//翻页按钮
//下页
$('.pages>button').eq(1).click(function () {
// console.log('翻页点击');
$('.pages li.active').next().click()
})
//上页
$('.pages>button').eq(0).click(function () {
$('.pages li.active').prev().click()
})
})
在一些特殊时候,如第一页或者最后一页时,我们需要禁用按钮
//禁用按钮
let $btn_prev = $('.pages>button').eq(0)
let $btn_next = $('.pages>button').eq(1)
page==1?$btn_prev.hide():$btn_prev.show()
page==pageCount?$btn_next.hide():$btn_next.show()