五、前端开发—搭建静态网站侧边栏

五、前端开发—搭建静态网站侧边栏

高能预警,这次写的组件会非常的多,一大堆代码正在袭来。。。。。

构图解析

这次我们做一个网页中页面侧边栏,其中会放一些导航信息。在写代码之前,我们先分析一下,我们想要达成的效果:

 

首先,最上方有一个 切换 按钮,当前是一个网站信息。切换过去,是友情链接的存放地。

网站信息栏 可以看到,有网站介绍栏博主联系栏标签栏导航栏网站日志栏。

并且我们可以看到,这些栏中标题风格都是一样的,我们可以抽取出来做成一个 标题栏。

外加一个 友情链接栏,所以这次我们需要构建 8 个组件,组件间会有嵌套关系。组件的属性调用关系

那。。。我们开始吧!!

切换组件

这次,我们从上往下将组件依次写完,最终,将它们拼接到一起。首先,我们构建切换组件。

在 blog\src\components\switch\ 中新建 switch.jsx 文件,并写入:

import React, {Component} from "react";

import "./switch.less"
import {AliwangwangFilled, ApiFilled} from  '@ant-design/icons';

export default class Switch extends Component{
    state = {
        is_first : true,
        one_img:  <AliwangwangFilled style={{fontSize:23}} />,
        two_img: <ApiFilled style={{fontSize:23}} />,
    }

    handleChange = (location) => {
        if(location === "first"){
            this.setState({is_first:true})
        }
        else{
            this.setState({is_first :false})
        }
    }

    render() {
        const {is_first,one_img,two_img} = this.state
        return (
            <div className="sidebarMenu">
                <ul className="menu">
                    <li className="anchor-my" style={is_first ? {"left":1} : {"left":39}} />
                    <li className={is_first ? "active" : null} >
                        <a onClick={this.handleChange.bind(this, "first")}>
                            {one_img}
                        </a>
                    </li>
                    <li className={is_first ? null : "active"}>
                        <a onClick={this.handleChange.bind(this,"second")}>
                            {two_img}
                        </a>
                    </li>
                </ul>
            </div>
        )
    }
}

上方,就是我们编写的静态 切换 组件的代码了,代码也很简单,首先,在 state 中 新建一些状态,这些状态在未来是有可能会改变的(记住,return 中编写的是静态代码,代码中是动态变化的值时,就提取出来,写入 state 中)。然后,在 render 中导入这些状态,并在 return 中使用。

其中核心的代码就是如何做到从第一个按钮切换到第二个按钮的效果:当点击第二个按钮时,就会调用 handleChange 函数,并向其中传入 second 的字符串参数。handleChange 函数就会判断这是点击第二个组件了,函数就会将 state 状态中的 is_first 置为 false, 当 is_first 值是 false 时,样式也会发生相应的变化。

同时,导入切换组件的样式,在同级目录新建 switch.less,并写入样式:

.anchor-my{
  position: absolute;
  left: 1px;
  width: 38px;
  opacity: 1;}.sidebarMenu {
  position: relative;
  text-align: right;
  height: 56px!important;
  padding: 0 15px;}.sidebarMenu>.menu {
  position: relative;
  white-space: nowrap;
  margin: 0;
  text-align: left;
  display: inline-block;
  background: #e0e4ec;
  border-radius: 100px;
  padding: 1px;
  -webkit-box-shadow: 0 1px rgba(255,255,255,.5), 0 8px 13px rgba(0,0,0,.15) inset;
  box-shadow: 0 1px rgba(255,255,255,.5), 0 8px 13px rgba(0,0,0,.15) inset;}.sidebarMenu >.menu>li {
  cursor: pointer;}.sidebarMenu .anchor-my {
  display: inline-block;
  background: #fff;
  background: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#f7f8fa));
  background: -webkit-linear-gradient(#fff,#f7f8fa);
  background: linear-gradient(#fff,#f7f8fa);
  border-radius: 50%;
  width: 38px;
  height: 38px;
  -webkit-box-shadow: 0 6px 6px rgba(31,45,61,.05), 0 10px 10px rgba(31,45,61,.15), 0 -1px 2px rgba(255,255,255,.5) inset;
  box-shadow: 0 6px 6px rgba(31,45,61,.05), 0 10px 10px rgba(31,45,61,.15), 0 -1px 2px rgba(255,255,255,.5) inset;
  -webkit-transition: .3s;
  transition: .3s;}.sidebarMenu>.menu>li{
  display: inline-block;}.sidebarMenu>.menu>li {
  cursor: pointer;}.sidebarMenu>.menu>li.active>a {
  color: #20a0ff;}.sidebarMenu>.menu>li>a {
  display: block;
  text-decoration: none;
  position: relative;
  color: #99a9bf;
  text-shadow: 0 1px rgba(255,255,255,.5);
  width: 38px;
  height: 38px;
  line-height: 38px;
  text-align: center;
  font-size: 16px;
  -webkit-transition: .25s;
  transition: .25s;}.sidebarMenu svg {
  overflow: hidden;
  vertical-align: middle;}

网站介绍栏组件

接下来,开始编写网站介绍栏组件。这次,我们可以看到有一张图片。当然可以使用url 的方式引入,但是它基本不会变动,是一个静态数据,因此我们使用静态的方式引入。

在 blog\src\components\show-sider-components\user-info\ 中新建 user-info.jsx,并写入代码:

import React, {Component} from "react";
import {Avatar} from "antd";

import './user-info.less'
import head_img from "./img/head_img.jpg";  \\ 导入图片

export default class UserInfo extends Component{

    state = {
        icon:head_img,
        nickname: "Asa",
        description:"独属于我自己的个人小站",
    }

    render() {
        const {icon, nickname, description} = this.state
        return (
            <div className="user_info" style={{"marginTop": 10, "display": "flex"}}>
                <Avatar className="authorImg" shape="square" size={64} src={icon}  style={{"float":'left'}} />
                <div className="meta" style={{"float":'left'}}>
                    <div className="name">
                        {nickname}
                    </div>
                    <div className="description">
                        {description}
                    </div>
                </div>
            </div>
        )
    }
}

解释一下,为什么新建了一个 show-sider-components 文件夹,原因就是我们的 网站介绍栏博主联系栏标签栏导航栏网站日志栏以及标题栏 都是侧边栏的内部组件,为了和便于区分,我们新建了一个文件夹存放这些组件。

导入图片,在同级 user-info.jsx 的同级目录下新建 img 文件夹,存放图片,并重命名为 head_img.jpg 。

在代码中,为了方便起见,我们引入了 antd 组件库中的 Avatar 头像组件,很方便,很容易的达到了我们想要的效果。

引入样式文件,在同级 user-info.jsx 的同级目录下新建 user-info.less 文件,并写入样式:

.user_info .authorImg {
  background-size: cover;
  background-repeat: no-repeat;
  width: 70px;
  height: 70px;
  border-radius: 13px;
  float: left;
  -webkit-box-shadow: 0 13px 15px rgba(0,0,0,.13);
  box-shadow: 0 13px 15px rgba(0,0,0,.13);}.user_info {
  padding: 0px 24px;}.user_info .meta {
  width: calc(100% - 70px);
  float: left;
  padding-left: 15px;}.user_info .meta .name {
  font-size: 18px;
  margin-top: 7px;
  color: #475669;}.user_info .meta .description {
  color: #738192;
  font-size: 13px;
  margin-top: 4px;}

标题栏组件

上面我们说过,好多组件中标题样式都是一样的,所以我们抽取构建标题组件,这样的话,就减少了大量代码的编写。 很方便,哈哈。。。

在 blog\src\components\show-sider-components\user-title\ 中新建 user-title.jsx,并写入代码:

import React, {Component} from "react";
import PropTypes from "prop-types"

import "./user-title.less"

export default class UserTitle extends Component{

    static propTypes = {
        title:PropTypes.string.isRequired
    }

    render() {
        const {title} = this.props
        return (
            <div className="ant-list-item-meta">
                <div className="ant-list-item-meta-content"><h4 className="ant-list-item-meta-title">{title}</h4></div>
            </div>
        )
    }
}

上面代码虽然少,但是有点东西了。这个标题组件不像之前写的那些组件一样。标题组件是动态的,外面传入什么标题名称。这里就要接收名称,并显示出来。

我们想要达到一个效果就是,必须要给标题组件传入一个字符串,不传入的话,就会报错。

在这里我们需要使用一个新的库 prop-types ,安装它命令如下:

yarn add prop-types

而 prop-types 这个库就可以满足我们的需求:

static propTypes = {
        title:PropTypes.string.isRequired
    }
// title  代表着 标题组件要接收一个 title 属性的字段
// PropTypes.string 代表着必须要一个字符串的字段
// isRequired 代表着必须要传入这个字段,否则将报错

而 const {title} = this.props 也和之前不一样。之前我们都是从 state 状态中获取值,现在我们冲 props 中获取。props 中就包含着外部传入的参数。

当然如果大家对 props 中还有什么属性、数据感兴趣的话,可以 console.log(props) 打印一下,在浏览器中查看其中的数据。O(∩_∩)O

哦~,差点忘了,还要引入标题组件的样式文件,在同级 user-title.jsx 的同级目录下新建 user-title.less 文件,并写入样式:

h4.ant-list-item-meta-title{
  position: relative;
  margin: 10px 0 0 0;
  padding-bottom: 8px;
  color: #738192;
  font-size: 14px;
  border-bottom: 1px solid #d8e0ea;
  -webkit-box-shadow: 0 1px rgba(255,255,255,.5);
  box-shadow: 0 1px rgba(255,255,255,.5);
  -webkit-transition: .25s;
  transition: .25s;}h4.ant-list-item-meta-title:after {
  content: "";
  position: absolute;
  display: inline-block;
  height: 3px;
  background: #20a0ff;
  background: -webkit-gradient(linear,left top,left bottom,color-stop(30%,#58B7FF),color-stop(70%,#20a0ff));
  background: -webkit-linear-gradient(#58B7FF 30%,#20a0ff 70%);
  background: linear-gradient(#58B7FF 30%,#20a0ff 70%);
  border-radius: 3px;
  bottom: -2px;
  left: 0;
  width: 30px;
  -webkit-box-shadow: 0 3px 4px rgba(32,160,255,.5);
  box-shadow: 0 3px 4px rgba(32,160,255,.5);
  -webkit-transition: .25s;
  transition: .25s;}li:hover> div > div > h4.ant-list-item-meta-title {
  color: #20a0ff;}li:hover> div > div > h4.ant-list-item-meta-title:after{
  width: 45px;}

博主联系栏组件

这里主要是存放一些我们博主的其他联系地址。

在 blog\src\components\show-sider-components\user-link\ 中新建 user-link.jsx,并写入代码:

import React, {Component} from "react";

import './user-link.less'
import {AliwangwangFilled, WechatFilled} from "@ant-design/icons";
import UserTitle from "../user-title/user-title";

export default class UserLink extends Component{
    state = {
        links : [
            {
                avatar: <AliwangwangFilled />,
                name: "新浪微博",
                url:"https://weibo.com/u/6255813599"
            },
            {
                avatar: <WechatFilled />,
                name: "微信公众号",
                url:"https://weibo.com/u/6255813599"
            },
        ]
    }

    render() {
        const {links} = this.state
        return (
            <>
                <UserTitle title={"关注我"} />
                <ul className="user_link">
                    {
                        links.map((link, index) => (
                            <li key={index}>
                                <a href={link.url}> {link.avatar} {link.name}</a>
                            </li>
                        ))
                    }
                </ul>
            </>

        )
    }
}

这个其实也没有什么知识点好说的。不对,有的。<UserTitle title={"关注我"} /> 我们引入了标题组件,之前我们也说了,必须要写一个 title 属性而且是字符串,标题组件才能生效。其他的代码只是重复性操作。

在同级 user-link.jsx 的同级目录下新建 user-link.less 文件,并写入样式:

.user_link {
  padding: 9px 0 0;
  margin: 0;
  display: block;}.user_link>li{
  display: block;
  list-style: none;}.user_link>li a {
  line-height: 30px;
  color: #738195;
  font-size: 14px;
  text-shadow: 0 1px #fff;
  transition: .25s;}.user_link>li:hover svg {
  color:#20a0ff;
  -webkit-transform: scale(1.01);
  transform: scale(1.01);
  -webkit-transition: .5s cubic-bezier(.3,60,.5,1),color .25s;
  transition: .5s cubic-bezier(.3,60,.5,1),color .25s;}

标签栏组件

这里存放的是网站博客文章的标签云,未来,想要查看哪一类标签,我们就可以点击它们,进行查看。

在 blog\src\components\show-sider-components\user-tags\ 中新建 user-tags.jsx,并写入代码:

import React, {Component} from "react";

import './user-tags.less'
import UserTitle from "../user-title/user-title";

export default class UserTags extends Component{
    state = {
        tags:[
            {
                id:'1',
                name:"git"
            },
            {
                id:'2',
                name:"markdown"
            },
        ]
    }
    handleClick = id => {
        console.log(id)
    }
    render() {
        const {tags} = this.state
        return (
            <>
                <UserTitle title={"标签"} />
                <ul className="user_tags">
                    {
                        tags.map((tag, index) => (
                            <li key={index}><a target="_self" onClick={this.handleClick.bind(this,tag.id)}>{tag.name}</a></li>
                        ))
                    }
                </ul>
            </>
        )
    }
}

这其中也没有什么新的知识点,只是之前的重复性操作。

然后,我们引入标签的样式文件。在同级 user-tags.jsx 的同级目录下新建 user-tags.less 文件,并写入样式:

.user_tags{
  padding: 9px 0 0;
  margin: 0;
  display: block;}.user_tags>li {
  display: inline-block;
  -webkit-transform: translateY(0);
  transform: translateY(0);
  margin: 6px 6px 0 0;
  -webkit-box-shadow: 0 13px 15px rgba(0,0,0,.1);
  box-shadow: 0 13px 15px rgba(0,0,0,.1);
  border-radius: 7px;
  -webkit-transition: .25s;
  transition: .25s;}.user_tags>li>a {
  line-height: 30px;
  -webkit-transition: .25s;
  text-decoration: none;
  position: relative;
  z-index: 1;
  display: inline-block;
  font-size: 12px;
  padding: 0 10px;
  background: #fff;
  border-radius: 7px;
  color: #738192;}.user_tags>li:hover>a {
  color: #fff;
  background: #20a0ff;
  -webkit-transform: translateY(6px);
  transform: translateY(6px);
  -webkit-box-shadow: 0 3px 3px rgba(0,0,0,.15);
  box-shadow: 0 3px 3px rgba(0,0,0,.15);}

导航栏组件

在 blog\src\components\show-sider-components\user-navs\ 中新建 user-navs.jsx,并写入代码:

import React, {Component} from "react";

import './user-navs.less'
import UserTitle from "../user-title/user-title";

export default class UserNavs extends Component{
    state = {
        navs:[
            {
                id:'1',
                name:"区块链"
            },
            {
                id:'2',
                name:"Gradle"
            },
        ]
    }

    handleClick = id => {
        console.log(id)
    }

    render() {
        const {navs} = this.state
        return (
            <>
                <UserTitle title={"导航"} />
                <ul className="user_navs">
                    {
                        navs.map((nav, index) => (
                            <li key={index}><a onClick={this.handleClick.bind(this,nav.id)} target="_self">{nav.name}</a></li>
                        ))
                    }
                </ul>
            </>

        )
    }
}

我们引入导航的样式文件。在同级 user-navs.jsx 的同级目录下新建 user-navs.less 文件,并写入样式:

.user_navs {
  margin-top: 15px;
  margin-left: 15px;
  padding: 15px 0;
  border-left: 1px solid #cad1db;
  -webkit-box-shadow: 1px 0 rgba(255,255,255,.7) inset;
  box-shadow: 1px 0 rgba(255,255,255,.7) inset;
  position: relative;}.user_navs>li {
  display: block;
  list-style: none;}.user_navs>li a {
  position: relative;
  color: #738192;
  background: #fff;
  line-height: 38px;
  border-radius: 10px;
  display: inline-block;
  padding: 0 15px 0 12px;
  text-decoration: none;
  margin: 10px 0 10px 25px;
  max-width: calc(100% - 34px);
  -webkit-box-shadow: 0 13px 15px rgba(0,0,0,.1);
  box-shadow: 0 13px 15px rgba(0,0,0,.1);
  -webkit-transform: translateY(0);
  transform: translateY(0);
  -webkit-transition: .25s;
  transition: .25s;}.user_navs>li:nth-child(even) a {
  color: #fff;
  background: #50616d;
  background: -webkit-linear-gradient(350deg,#20a0ff,#20b8ff);
  background: linear-gradient(100deg,#20a0ff,#20b8ff);
  -webkit-box-shadow: 0 13px 15px rgba(32,160,255,.3);
  box-shadow: 0 13px 15px rgba(32,160,255,.3);}.user_navs>li a:before {
  content: "";
  position: absolute;
  border-right: 15.5px solid #fff;
  border-top: 15.5px solid transparent;
  border-bottom: 15.5px solid transparent;
  top: 4px;
  left: -13px;}.user_navs>li:nth-child(even) a:before {
  border-right-color: #20a0ff;}.user_navs>li a:after {
  content: "";
  position: absolute;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #a6b4c7;
  left: -29px;
  top: 15px;
  -webkit-box-shadow: 0 0 0 1px #cad1db inset, 0 0 0 2px #f0f2f7 inset;
  box-shadow: 0 0 0 1px #cad1db inset, 0 0 0 2px #f0f2f7 inset;}.user_navs>li:nth-child(even) a:hover {
  -webkit-transform: translateY(6px);
  transform: translateY(6px);
  -webkit-box-shadow: 0 3px 3px rgba(32,160,255,.35);
  box-shadow: 0 3px 3px rgba(32,160,255,.35);}.user_navs>li a:hover {
  -webkit-transform: translateY(6px);
  transform: translateY(6px);
  -webkit-box-shadow: 0 3px 3px rgba(0,0,0,.15);
  box-shadow: 0 3px 3px rgba(0,0,0,.15);}

网站日志栏组件

在 blog\src\components\show-sider-components\user-logs\ 中新建 user-logs.jsx,并写入代码:

import React, {Component} from "react";

import './user-logs.less'
import UserTitle from "../user-title/user-title";

export default class UserLogs extends Component{
    state = {
        logs:[
            "网站升级成功1.0",
            "网站升级成功2.0",
        ]
    }
    render() {
        const {logs} = this.state
        return (
            <>
                <UserTitle title={"微博客"} />
                <ul className="user_logs">
                    {
                        logs.map((log, index) => (
                            <li key={index}>
                                <div className="main">
                                    <p/>
                                    <p>{log}</p>
                                    <p/>
                                </div>
                            </li>
                        ))
                    }
                </ul>
            </>

        )
    }
}

我们引入网站日志的样式文件。在同级 user-logs.jsx 的同级目录下新建 user-logs.less 文件,并写入样式:

.user_logs{
  margin-top: 15px;
  margin-left: 15px;
  padding: 0 0 20px;
  border-left: 1px solid #cad1db;
  -webkit-box-shadow: 1px 0 rgba(255,255,255,.7) inset;
  box-shadow: 1px 0 rgba(255,255,255,.7) inset;
  position: relative;}.user_logs:after, .user_logs:before {
  content: "";
  position: absolute;
  width: 9px;
  height: 9px;
  background: -webkit-gradient(linear,left top,left bottom,from(#98a3b3),to(#d8e0ea));
  background: -webkit-linear-gradient(#98a3b3,#d8e0ea);
  background: linear-gradient(#98a3b3,#d8e0ea);
  -webkit-box-shadow: 0 0 0 1px #a4b2c6 inset, 0 0 0 2px #d8e0ea inset, 0 4px 3px rgba(166,180,199,.4);
  box-shadow: 0 0 0 1px #a4b2c6 inset, 0 0 0 2px #d8e0ea inset, 0 4px 3px rgba(166,180,199,.4);
  left: -5px;
  border-radius: 50%;}.user_logs>li {
  display: block;
  list-style: none;
  position: relative;
  margin-left: 20px;
  -webkit-transform: translateY(0);
  transform: translateY(0);
  -webkit-transition: .25s;
  transition: .25s;
  margin-bottom: 11px;}.user_logs>li:before {
  content: "";
  position: absolute;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #a6b4c7;
  left: -24px;
  top: 32px;
  -webkit-box-shadow: 0 0 0 1px #cad1db inset, 0 0 0 2px #f0f2f7 inset;
  box-shadow: 0 0 0 1px #cad1db inset, 0 0 0 2px #f0f2f7 inset;}.user_logs .main {
  position: relative;
  display: inline-block;
  background: #D3DCE6;
  background: -webkit-linear-gradient(bottom,rgba(255,255,255,.5),rgba(255,255,255,0) 10px) #D3DCE6;
  background: linear-gradient(0deg,rgba(255,255,255,.5),rgba(255,255,255,0) 10px) #D3DCE6;
  border-radius: 13px;
  border: 1px solid #acbacc;
  padding: 5px 15px;
  -webkit-box-shadow: 0 0 0 1px rgba(255,255,255,.4) inset, 0 13px 15px rgba(31,45,61,.15);
  box-shadow: 0 0 0 1px rgba(255,255,255,.4) inset, 0 13px 15px rgba(31,45,61,.15);
  max-width: 100%;
  -webkit-transition: .25s;
  transition: .25s;}.user_logs .main:before {
  content: "";
  display: block;
  position: absolute;
  left: 4px;
  top: 0;
  right: 4px;
  height: 20px;
  border-radius: 10px;
  background: rgba(255,255,255,.5);
  background: -webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,1)),to(rgba(255,255,255,.2)));
  background: -webkit-linear-gradient(rgba(255,255,255,1),rgba(255,255,255,.2));
  background: linear-gradient(rgba(255,255,255,1),rgba(255,255,255,.2));}.user_logs .main p {
  margin: 4px 0;}.user_logs .main * {
  text-shadow: 0 1px rgba(255,255,255,.5);
  color: #5d6b7d;
  font-size: 13px;
  position: relative;
  z-index: 1;}.user_logs .main:after {
  content: "";
  position: absolute;
  border-top: 6px solid transparent;
  border-right: 6px solid #D3DCE6;
  border-bottom: 6px solid transparent;
  top: 12px;
  z-index: 1;
  left: -3px;}.user_logs:after {
  bottom: 0;}.user_logs>li:hover .date span {
  opacity: 1;
  -webkit-transform: translateY(-3px);
  transform: translateY(-3px);}.user_logs>li:hover .main {
  -webkit-transform: translateY(6px);
  transform: translateY(6px);
  -webkit-box-shadow: 0 3px 3px rgba(0,0,0,.15);
  box-shadow: 0 3px 3px rgba(0,0,0,.15);}

友情链接栏

这里我希望存放一些我非常喜欢的网站链接,少而精。

在 blog\src\components\show-sider-components\friends-link\ 中新建 friends-link ,并写入代码:

import React, {Component} from "react";

import "./friends-link.less"
import UserTitle from "../user-title/user-title";

export default class FriendsLink extends Component{
    state = {
        friends : [
            {
                url:"http://asa-zhang.top",
                name:"大米歌",
                description:"在路上,永远年轻,永远热泪盈眶",
                url_logo:"https://www.damig.cn/logo.jpg",
            },
            {
                url:"http://asa-zhang.top",
                name:"软件教程盒子",
                description:"分享网络经典软件及使用教程",
                url_logo:"https://s1.ax1x.com/2020/09/07/wu71E9.png",
            }
        ]
    }
    render() {
        const {friends} = this.state
        return (
            <>
                <UserTitle title={"友情链接"} />
                <ul className="friends_links">
                    {
                        friends.map((f, index) => (
                            <li key={index}>
                                <div className="friend_card">
                                    <a className={"site_icon"} href={f.url} style={{backgroundImage: `url(${f.url_logo})`}} />
                                    <div className="metas">
                                        <div className="background reverse"
                                             style={{backgroundImage:"linear-gradient(#FFFFFF,var(--white_default))"}} />
                                        <a href={f.url} target="_blank" className="title">{f.name}</a>
                                        <div className="description" title={f.description}>{f.description}</div>
                                    </div>
                                </div>
                            </li>
                        ))
                    }
                </ul>
            </>
        )
    }
}

这里有两个小点:

  • 在 react 中的 html 中使用 style 属性添加样式的话,必须要使用两个花括号,而且其中的 css 代码也有一些不同,所有像 “background-image” 这种带 “-” 的,都要将 - 去掉,并且后面的首位字母大写。

  • 代码 在这个符号中,写代码可以通过 ${ 变量 } 引入 js 变量。

然后,我们引入友情链接的样式文件。在同级 friends-link.jsx 的同级目录下新建 friends-link.less 文件,并写入样式:

.friends_links{
  padding: 9px 0 0;
  margin: 0;
  display: block;}.friends_links>li{
  display: block;
  list-style: none;}.friend_card {
  display: flex;
  align-items: center;
  margin-bottom: 20px;}.friend_card:hover .site_icon {
  display: block;}.friend_card .site_icon{
  width: 48px;
  height: 48px;
  background-position: 50%;
  background-repeat: no-repeat;
  background-size: contain;
  display: none;
  border-radius: 6px 0 0 6px;}.friend_card .metas .background.reverse {
  transform: scaleY(-1);}.friend_card .metas {
  background: #20a0ff;
  box-shadow: 0 10px 15px var(--gray_opacity_1),0 0 0 1px hsla(0,0%,100%,.06) inset;
  border-radius: 6px;
  height: 60px;
  padding: 0 15px;
  display: flex;
  justify-content: center;
  flex-direction: column;
  width: calc(100% - 48px);
  text-shadow: 0 1px var(--white_default);
  position: relative;}.friend_card .metas .title {
  position: relative;
  z-index: 1;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  transition: .25s;}.friend_card .metas .description {
  position: relative;
  color: #f0f2f5;
  z-index: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;}

侧边栏组件

最后,我们将以上所有写好的组件组合进来。

在 blog\src\components\show-sider\ 中新建 show-sider.jsx 文件,并写入:

import React, {Component} from "react";

import "./show-sider.less"
import Switch from "../switch/switch";
import UserInfo from "../show-sider-components/user-info/user-info";
import UserLink from "../show-sider-components/user-link/user-link";
import UserTags from "../show-sider-components/user-tags/user-tags";
import UserNavs from "../show-sider-components/user-navs/user-navs";
import UserLogs from "../show-sider-components/user-logs/user-logs";
import FriendsLink from "../show-sider-components/friends-link/friends-link";

export default class ShowSider extends Component{
    state = {
        is_first: true,
    }

        handleSwitch = flag => {
        this.setState({is_first:flag})
    }

    render() {
        const {is_first} = this.state
        return (
            <>
                <div>
                    <Switch />
                </div>
                <UserInfo />
                <div className={"sider"}>
                    { is_first?(
                        <>
                            <UserLink />
                            <UserTags />
                            <UserNavs />
                            <UserLogs />
                        </>
                    ):(
                        <FriendsLink />
                    )}
                </div>
            </>
        )
    }
}

这个和 切换组件 一样的原理,判断一下 is_first 是否为真,若为真,显示 <UserLink /> <UserTags /> <UserNavs /> <UserLogs /> 这四个组件,否则,显示 友情链接组件

我们只需要控制 handleSwitch 函数就可以控制 is_first 状态的值。this.setState() 这个函数就是重置 state 状态中的值的函数

我们引入导航的样式文件。在 show-sider.jsx 的同级目录下新建 show-sider.less 文件,并写入样式:

.sider {
  padding-left:24px;}

最后将我们写好的侧边栏组件导入到网站架构中,

修改 my-blog\src\show\show.jsx 文件的代码为以下代码:

...
import ShowSider from "../show-sider/show-sider";  // 导入侧边栏组件
...
<Row style={{marginTop:16}}>
    {/*文章列表*/}
    <Col span={19}>
        <ShowPostsList />
    </Col>
    {/*个人资料*/}
    <Col span={5}>
        <ShowSider />
    </Col>
</Row>

...

编译运行项目后,我们会发现,虽然初步实现了我们想要的效果,但是发现用切换组件的按钮,并没有切换到友情链接组件,接下来,我们解决这个问题。

实现切换效果

修改 blog\src\components\show-sider\show-sider.jsx 的侧边栏组件的文件:

... 
                <Switch handleSwitch={this.handleSwitch} />
...

我们将 handleSwitch 函数传递给 Switch 组件,这样,切换组件就能调用 handleSwitch 函数,进而控制哪些组件需要显示。

修改 blog\src\components\switch\switch.jsx 切换组件的文件:

...
import PropTypes from "prop-types";   // 导入 prop-types 库
...
static propTypes = {
        handleSwitch: PropTypes.func
    }

    state = {
        is_first : true,
        one_img:  <AliwangwangFilled style={{fontSize:23}} />,
        two_img: <ApiFilled style={{fontSize:23}} />,
    }

    handleChange = (location) => {
        if(location === "first"){
            this.setState({is_first:true})
            this.props.handleSwitch(true)
        }
        else{
            this.setState({is_first :false})
            this.props.handleSwitch(false)
        }
    }
...
...

propTypes 功能和之前在标题组件中的作用一样。 我们修改的重点在 handleChange 函数中,在标题组件中我们也提到过参数都存放在 this.props 中,所以我们调用 handleSwitch 函数的方法就是:this.props.handleSwitch()

最后的效果图

 



END

 

 

这个公众号分享一些

我平时的胡思乱想和其他东西

如果您稍微感兴趣

可以关注一下

 

                                 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值