header/index.js
核心代码
...
class Header extends Component {
constructor(props) {
super(props);
this.state = {
focused: true
}
}
render() {
...
header/index.js
核心代码
搜索框和放大镜图标
<SearchWrapper>
<NavSearch
className={this.state.focused ? 'focused' : ''}
></NavSearch>
<i className={this.state.focused ? 'focused iconfont' : 'iconfont'}></i>
</SearchWrapper>
header/style.js
核心代码
export const SearchWrapper = styled.div`
position: relative;
float: left;
.iconfont {
position: absolute;
right: 5px;
bottom: 5px;
width: 30px;
line-height: 30px;
border-radius: 15px;
text-align: center;
&.focused {
background: #777;
color: #fff;
}
}
`;
export const NavSearch = styled.input.attrs({
placeholder: '搜索'
})`
width: 160px;
height: 38px;
padding: 0 30px 0 20px;
margin-top: 9px;
margin-left: 20px;
box-sizing: border-box;
border: none;
outline: none;
border-radius: 19px;
background: #eee;
font-size: 14px;,
color: #666;
&::placeholder {
color: #999;
}
&.focused {
width: 240px;
}
`;
header/index.js
核心代码
<NavSearch
className={this.state.focused ? 'focused' : ''}
onFocus={this.handleInputFocus}
onBlur={this.handleInputBlur}
></NavSearch>
handleInputFocus() {
this.setState({
focused: true
})
}
handleInputBlur() {
this.setState({
focused: false
})
}
下载react-transition-group
添加CSSTransition标签
header/index.js
核心代码
引入
import { CSSTransition } from 'react-transition-group'
<SearchWrapper>
<CSSTransition
in={this.state.focused}
timeout={200}
classNames="slide"
>
<NavSearch
className={this.state.focused ? 'focused' : ''}
onFocus={this.handleInputFocus}
onBlur={this.handleInputBlur}
></NavSearch>
</CSSTransition>
<i className={this.state.focused ? 'focused iconfont' : 'iconfont'}></i>
</SearchWrapper>
添加动画的css
header/style.js
核心代码
.slide-enter {
transition: all .2s ease-out;
}
.slide-enter-active {
width: 240px;
}
.slide-exit {
transition: all .2s ease-out;
}
.slide-exit-active {
width: 160px;
}
header/style.js
import styled from 'styled-components';
import logoPic from '../../statics/logo.png'
export const HeaderWrapper = styled.div`
position: relative;
height: 58px;
border-bottom: 1px solid #f0f0f0;
`;
export const Logo = styled.a.attrs({href:'/'})`
position: absolute;
top: 0;
left: 0;
display: block;
width: 100px;
height: 56px;
background: url(${logoPic});
background-size: contain;
`;
export const Nav = styled.div`
width: 960px;
height: 100%;
padding-right: 70px;
box-sizing: border-box;
margin: 0 auto;
`;
export const NavItem = styled.div`
line-height: 56px;
padding: 0 15px;
font-size: 17px;
color: #333;
&.left {
float: left;
}
&.right {
float: right;
color: #969696;
}
&.active {
color: #ea6f5a;
}
`;
export const SearchWrapper = styled.div`
position: relative;
float: left;
.slide-enter {
transition: all .2s ease-out;
}
.slide-enter-active {
width: 240px;
}
.slide-exit {
transition: all .2s ease-out;
}
.slide-exit-active {
width: 160px;
}
.iconfont {
position: absolute;
right: 5px;
bottom: 5px;
width: 30px;
line-height: 30px;
border-radius: 15px;
text-align: center;
&.focused {
background: #777;
color: #fff;
}
}
`;
export const NavSearch = styled.input.attrs({
placeholder: '搜索'
})`
width: 160px;
height: 38px;
padding: 0 30px 0 20px;
margin-top: 9px;
margin-left: 20px;
box-sizing: border-box;
border: none;
outline: none;
border-radius: 19px;
background: #eee;
font-size: 14px;,
color: #666;
&::placeholder {
color: #999;
}
&.focused {
width: 240px;
}
`;
export const Addition = styled.div`
position: absolute;
right: 0;
top: 0;
height: 56px;
`;
export const Button = styled.div`
float: right;
margin-top: 9px;
margin-right: 20px;
padding: 0 20px;
line-height: 38px;
border-radius: 19px;
border: 1px solid #ec6149;
font-size: 14px;
&.reg {
color: #ec6149;
}
&.writting {
color: #fff;
background: #ec6149;
}
`;
header/index.js
import React, { Component } from "react";
import { CSSTransition } from 'react-transition-group'
import {SearchWrapper,HeaderWrapper,Logo,Nav,NavItem,NavSearch,Addition,Button} from "./style";
class Header extends Component {
constructor(props) {
super(props);
this.state = {
focused: false
}
this.handleInputFocus = this.handleInputFocus.bind(this);
this.handleInputBlur = this.handleInputBlur.bind(this);
}
render() {
return (
<HeaderWrapper>
<Logo />
<Nav>
<NavItem className='left active'>首页</NavItem>
<NavItem className='left'>下载App</NavItem>
<NavItem className='right'>登录</NavItem>
<NavItem className='right'>
<i className="iconfont "></i>
</NavItem>
<SearchWrapper>
<CSSTransition
in={this.state.focused}
timeout={200}
classNames="slide"
>
<NavSearch
className={this.state.focused ? 'focused' : ''}
onFocus={this.handleInputFocus}
onBlur={this.handleInputBlur}
></NavSearch>
</CSSTransition>
<i className={this.state.focused ? 'focused iconfont' : 'iconfont'}></i>
</SearchWrapper>
</Nav>
<Addition>
<Button className='writting'>
<i className="iconfont "></i>
写文章</Button>
<Button className='reg'>注册</Button>
</Addition>
</HeaderWrapper>
)
}
handleInputFocus() {
this.setState({
focused: true
})
}
handleInputBlur() {
this.setState({
focused: false
})
}
}
export default Header;