时间:2023-09-16 20:48:02 | 来源:网站运营
时间:2023-09-16 20:48:02 来源:网站运营
四、前端开发—搭建静态网站(3):my-blog/src/components/show-posts-list/show-posts-list.jsx
和 my-blog/src/components/show-sider/show-sider.jsx
这两处地方新建文件。show-posts-list.jsx
将会写 文章列表的组件;show-sider.jsx
将会写 个人资料侧边栏的组件。...import ShowPostsLists from "../../containers/show-posts-lists/show-posts-lists";import ShowSider from "../../containers/show-sider/show-sider";......return ( <> <Row style={{"marginBottom": 20}}> <Col span={24}> <Swiper /> </Col> </Row> <Row > <Col span={19} > <ShowPostsLists /> </Col> <Col span={5}> <ShowSider/> </Col> </Row> </>...
接下来,所有的重心就是在 my-blog/src/components/show-posts-list/show-posts-list.jsx
文件中详细编写文章列表组件。import React, {Component} from "react";import {Col, Row} from "antd";export default class ShowPostsList extends Component{ render() { return ( <Row> <Col span={24}> 博客类别导航栏 </Col> {/* 文章列表 */} <Col span={6}> <div> <span> 文章标题 </span> <span> 文章摘要 </span> <span> 文章类别 </span> <span> 文章标签 </span> </div> </Col> </Row> ) }}
上面的代码页很容易理解,从之前的网页中文章列表结构中我们可以看到,它是由一个 博客类别导航栏 和 一个文章列表 组成的。 同时 博客类别导航栏 独占一行,为了方便起见我是用 Col
组件,将 span
属性设置为 24
,当然我们也可以继续嵌套 Row
组件。Col
中的 span
属性是 6 。有人可能会问,文章列表是由好几行组成的,为什么这里只使用一个 Col
就完成了呢? 原因很简单,之前说过,Col
会将 Row
的一行分为了 24 份。但是呢,当 Row
中的 Col
的 span
属性值之和大于 24 时,它就会自动换行。<Col span={6}> ... </Col>
这个标签的内容,运行一下,查看效果演示。show-posts-list.jsx
中完善代码以及样式,那么所有的代码就会杂糅到一起,那和不使用 react 还有区别么。所以我们要使用 react 中组件化思想,尽量将能拆分出的组件就拆分出来。我们可以看到,show-posts-list.jsx
可以拆分成两个组件 博客类别导航栏组件,以及文章列表中每一个文章信息的卡片组件。my-blog/src/components/nav-posts/
中新建 nav-posts.jsx
文件,写入:import React, {Component} from "react";import "./nav-posts.less"export default class NavPosts extends Component{ render() { return ( <div className={"categoryNav"}> {/* 不包含子菜单栏 */} <div className={`dropdown active`} style={{marginLeft:0}}> <a><span>最新撰写</span></a> </div> {/* 包含子菜单栏 */} <div className={`dropdown`}> <span>编程语言</span> <div className={"dropdown-content"}> <p><a>gradle</a></p> <p><a>react</a></p> </div> </div> </div> ) }}
上面的 html
代码也很简单,编写了两个分类导航栏,其中一个不包含子菜单栏,另一个可以包含多个子菜单栏。这样就可以根据自己的需求定制特定的网页。import "./nav-posts.less"
是在同级目录下新建 nav-post.less
文件,并写入:.categoryNav{ float:left; width: calc(100%); position: relative; height: 56px;}.dropdown { position: relative; display: inline-block; cursor: pointer; line-height: 44px; margin-left: 5px;}.categoryNav>.dropdown.active { background: #20a0ff; border-radius: 10px; -webkit-box-shadow: 0 8px 10px rgba(32,160,255,.3); box-shadow: 0 8px 10px rgba(32,160,255,.3);}.categoryNav>.dropdown.active > a > span { color: #fff;}.categoryNav>.dropdown.active > span { color: #fff;}.dropdown span { transition: .25s; font-size: 14px; padding: 0 15px; color: #738192;}.dropdown-content { left: -32px; width: 138px; border-radius: 5px; display: none; position: absolute; background-color: #f9f9f9; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); padding: 5px 5px; z-index: 999;}.dropdown-content p { text-align: center; margin-bottom: 0px;}.dropdown-content p.active { color: white; background: #4fb2fb; border-radius: 5px 5px 5px 5px;}.dropdown:hover .dropdown-content { display: block;}.dropdown:hover { background: #20a0ff3b; border-radius: 10px; -webkit-box-shadow: 0 8px 10px rgba(32, 160, 255, .3); box-shadow: 0 8px 10px rgba(32, 160, 255, .3);}.dropdown-content p{ text-align: center; margin-bottom: 0px;}.dropdown-content p:hover{ color: white; background: #20a0ff3b; border-radius: 5px 5px 5px 5px;}.dropdown-content p:hover a{ color: white;}.dropdown-content a{ text-decoration: none; color: #738192;}
最后将我们写好的静态的博客文章类别导航栏组件导入到 show-posts-list.jsx
中,即 修改 my-blog/src/components/show-posts-list/show-posts-list.jsx
中部分代码:...import NavPosts from "../nav-posts/nav-posts"; // 导入组件...... <Row> <Col span={24}> <NavPosts /> </Col> {/*引入组件*/} <Col span={6}> <div> <span> 文章标题 </span> <span> 文章摘要 </span> <span> 文章类别 </span> <span> 文章标签 </span> </div> </Col> </Row>...
启动运行博客项目,就可看到相应的界面效果了。my-blog/src/components/nav-posts/nav-posts.jsx
文件中,不难发现,导航栏分类的数据都和 html 代码杂糅到一起。my-blog/src/components/nav-posts/nav-posts.jsx
文件中的代码如下:import React, {Component} from "react";import "./nav-posts.less"export default class NavPosts extends Component{ state = { current: 3, sub_current: -1, categories_data:[ { id: 3, name:"最新撰写" }, { id: 7, name:"编程语言", cub_cate:[ { name:"gradle", id: 3, }, { name:"React", id: 7, } ] } ] } handleClick = (id, sub_id) => { console.log(id) this.setState({ current: id,sub_current: sub_id }); }; render() { const {categories_data,current,sub_current} = this.state return ( <div className={"categoryNav"}> { categories_data.map((category,index) => ( <div className={`dropdown ${current === category.id ? 'active' : null }`} onClick={category.cub_cate === undefined && current !== category.id ? this.handleClick.bind(this,category.id) : null } style={{marginLeft:0}} key={index} > <span>{category.name}</span> { category.cub_cate === undefined ? null : ( <div className={"dropdown-content"}> { category.cub_cate.map((cate, index) => ( <p className={sub_current === cate.id ? 'active' : null } onClick={sub_current !== cate.id ? this.handleClick.bind(this, category.id, cate.id):null} key={index} >{cate.name}</p> ) ) } </div> ) } </div> )) } </div> ) }}
看着可能有些复杂,但是仔细研究一下的话,是非常简单的,如果又不懂的话,我将在下一段简单的介绍一下其中用到的语法,如果已经了解了的话,请跳过下面一段话,进入下一阶段吧!state
我们之前也用到过,它称为组件状态,它保管着我们组件的数据以及状态。其中,我设计了三个状态,current
、sub_current
、categories_data
。current
代表着已经被选中的菜单的 id;当菜单中存在 子菜单栏时,sub_current
代表着已经被选中的子菜单的 id;categories_data
代表着存放的数据,未来动态数据就将存放于此。current
和 sub_current
的作用就是判断菜单是否被选中,同时选中菜单的样式将会发生变化。const {categories_data,current,sub_current} = this.state
这行代码之前也用到过,它是将上方 state
中的三个对象引入进来,方便下方代码使用。{ 数组对象.map((aaa,index) => ( 此处写循环代码 ) ) }
这个已经写的很清楚了,这是一个循环数组的方法,其中 aaa
为每个循环时数组对象中的每个一对象,index
为 循环次数,它们两个使用范围仅在 循环体中使用{ 判断条件 ? 条件为真时执行的代码 : 条件为假时执行的代码 }
这个已经也写的很清楚了,就是一个简单的判断语句。OnClick
属性,顾名思义,指的就是当用户点击时执行的函数。my-blg/src/components/card/
中创建 card.jsx
文件,并写入:import React, {Component} from "react";import "./card.less"export default class Card extends Component{ render() { return ( <div className={"card"}> <a> <div className={"card-image"}> <img src={"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4166449390,244951508&fm=26&gp=0.jpg"} /> <span className={"card-title"}>标题</span> <span className={"posts-date"}> 2020年1月30日 </span> </div> </a> <div className={"card-content article-content"}> <div className={"summary"}> 文章摘要。。。。 </div> </div> <div className={"card-action article-tags"}> <a><span className={"chip tag-color"}>标签-1</span> </a> <a><span className={"chip tag-color"}>标签-2</span> </a> </div> </div> ) }}
上面的代码也很简单,对样式的制作,主要是通过百度搜索,以及其他相关网站代码的"借鉴",(假如大家都不知道如何借鉴的话,以后有机会分享一下)。card.less
,写入样式:.card{ border-radius: 8px; overflow: hidden; background-color: #fff; padding-bottom: 5px; transition: all 250ms cubic-bezier(.02, .01, .47, 1);}.card a { margin-right: 0 !important; color: #525f7f; text-transform: none !important;}.card .card-content { padding: 15px 15px 12px 18px; border-radius: 0 0 2px 2px;}.card .card-action:last-child { border-radius: 0 0 2px 2px;}.card .card-image { transition: 1s; position: relative; background: #000;}.card .card-image img { opacity: 0.5; transition: 1s;}.card:hover { box-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12), 0 5px 12px 4px rgba(0, 0, 0, 0.09); transform: translate(0,-5px); transition-delay: 0s !important; border-color: transparent;}.card:hover img { opacity: 1;}.card:hover .card-image { background: #fff;}.card .card-image img { width: 100%; border-radius: 8px 8px 0 0;}.card .card-image .card-title { color: #fff; position: absolute; bottom: 0; left: 0; max-width: 100%; padding: 24px;}.card .card-image .posts-date { color: #cacaca; font-size: 12px; position: absolute; bottom: 30px; left: 0px; max-width: 100%; padding: 24px;}.card .card-title { font-size: 24px; font-weight: 300;}.card .article-content .summary { padding-bottom: 2px; padding-left: 0; margin-bottom: 6px; word-break: break-all;}.summary { overflow: hidden; position: relative; line-height: 1.5em; max-height: 4.5em; text-align: justify; margin-right: -1em; padding-right: 1em;}.summary:before { content: '...'; position: absolute; right: 15px; bottom: 0;}.summary:after { content: ''; position: absolute; right: 15px; width: 1em; height: 1.5em; margin-top: 0.2em; background: white;}.article-content .post-category { float: right; padding-left: 5px;}.tag-color { background-image: linear-gradient(to left, #00c9ff 0%, #66a6ff 100%);}.chip { display: inline-block; height: 32px; font-size: 13px; font-weight: 500; color: rgba(0,0,0,0.6); line-height: 32px; padding: 0 12px; border-radius: 16px; background-color: #e4e4e4; margin-bottom: 5px; margin-right: 5px;}.card .article-tags .chip { margin: 2px; font-size: 0.8rem; font-weight: 400; height: 22px; line-height: 22px; color: #fff; border-radius: 10px;}.article-tags{ padding-left: 14px;}
其中,文章列表有一个小优化,即在鼠标未悬浮时,图片会有一个黑色的蒙版。当鼠标悬浮时,就会消失。这个为图片添加蒙版的效果有一个参考,地址如下: https://blog.csdn.net/yunsiwl5/article/details/80365956card.jsx
的代码修改如下:import React, {Component} from "react";import "./card.less"export default class Card extends Component{ state = { img_src:"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4166449390,244951508&fm=26&gp=0.jpg", title:"", abstract:"文章摘要。。。。", create_time:"2020年1月30日", category:"gradle", tags:[{ id:0, name:"标签-1", },{ id:2, name:"标签 - 2", },], } render() { const {img_src,tags,title,abstract,category,create_time} = this.state return ( <div className={"card"}> <a> <div className={"card-image"}> <img src={img_src} /> <span className={"card-title"}>{title}</span> <span className={"posts-date"}> {create_time} · {category} </span> </div> </a> <div className={"card-content article-content"}> <div className={"summary"}> {abstract} </div> </div> <div className={"card-action article-tags"}> {tags.map((tag,index) => ( <a key={index}> <span className={"chip tag-color"}> {tag.name} </span> </a> ))} </div> </div> ) }}
最后同样将我们写好的静态的卡片组件导入到 show-posts-list.jsx
中,即 修改 my-blog/src/components/show-posts-list/show-posts-list.jsx
中部分代码:import React, {Component} from "react";import {Col, Row} from "antd";import NavPosts from "../nav-posts/nav-posts";import Card from "../card/card"; // 导入卡片组件export default class ShowPostsList extends Component{ render() { return ( <Row gutter={[32, 24]}> <Col span={24}> <NavPosts /> </Col> {/* 导入三张文章卡片 */} <Col span={6}> <Card /> </Col> <Col span={6}> <Card /> </Col> <Col span={6}> <Card /> </Col> </Row> ) }}
这样,静态网站的第二小模块就算搭建完成了,赶紧运行查看一下吧! 哦哦,对了,细心的小伙伴会发现 Row
中出现了 gutter={[32, 24]}
这个属性,我们可以尝试删除它,运行一遍,看有什么差异,或者查询 antd 文档,看一下它们有什么作用吧!关键词:静态