简书Header组件开发(样式组件的className、属性的样式)

总结

样式组件的className

  1. 找到几个组件之间的共性后只需要生成一个样式组件
  2. 在style.js中定义该样式时添加&.yourClassName{xxx:xxx}
  3. 使用样式组件时添加专属的className即可

解释&的含义

&表示当前元素,例如

1
2
3
a{
&.b {}
}

编译之后就是a.b{}
没有&就成了a .b(中间有个空格,b这个class成了a的后代元素的了)

使用场景

  1. 在style.js中我们会给大部分样式相同的元素创建一个组件A,并通过styled.div 写在模板字符串中的各种样式;定义组件A的样式
  2. 在index.js中直接使用<A>...</A>即可调用组件。但有时候我们使用<A>...</A>创建了几个组件,但希望这几个组件能拥有一些不同的样式,此时就可以在style.js的组件A的样式中再通过&.yourClassName{各种样式}来定义这些有区别的样式
  3. 在index.js中直接使用<A className={yourClassName}>...</A>即可调用有不同样式的组件了。

样式组件的属性的样式

  1. 在style.js或index.js中给样式组件增添属性(比如placeholder)
  2. 在style.js中**定义该样式时添加&::属性名{xxx:xxx}**(比如&::placeholder{color: #999;}就是给placeholder的字体定义颜色)

Header组件中间部分:导航栏(Nav组件)

之前我们写了logo,现在来完成logo右边的导航部分:
实现效果

在common-header文件夹中:

  1. 在style.js中定义Nav组件(div标签)
  2. 在index.js中引入并使用Nav组件
  3. 在style.js中定义4个NavItem组件(div标签)
    • 可以注意到“首页”“下载App”是左浮动,而“Aa”“登录”是右浮动,但他们4个都是用的同一个样式组件
    • 此时就需要在定义NavItem样式时使用&.left{float:left;},代表当NavItem组件有定义className为left的时候就让该组件左浮动
  4. 在index.js中引入并将4个NavItem放入Nav组件中,并给需要左浮动的NavItem组件加上className:left,给需要右浮动的NavItem组件加上className:right

定义导航栏(Nav组件)

在style.js中定义Nav组件(div标签):

1
2
3
4
5
6
export const Nav = styled.div`
width:960px;
height:100%;
margin: 0 auto;
background:green;
`

引入并使用导航栏(Nav组件)

在index.js中引入并使用Nav组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import React, { Component } from 'react'
import {
HeaderWrapper,
Logo,
Nav,
} from "./style";


class Header extends Component {
render() {
return (
<HeaderWrapper>
<Logo />
<Nav></Nav>
</HeaderWrapper>
)
}
}

export default Header;

可以看到导航栏的位置已经确定出来了:
效果


定义4个NavItem组件

同一组件实现左右浮动

左右浮动的效果:
效果

&.的使用(类似className的选择器)

  • 可以注意到“首页”“下载App”是左浮动,而“Aa”“登录”是右浮动,但他们4个都是用的同一个样式组件
  • 此时就需要在定义NavItem样式时使用&.left{float:left;},代表当NavItem组件有定义className为left的时候就让该组件左浮动

在style.js中定义4个NavItem组件(div标签):

1
2
3
4
5
6
7
8
export const NavItem = styled.div`
&.left{
float:left;
}
&.right{
float:right;
}
`

使用NavItem组件(className的使用)

在index.js中引入并将4个NavItem放入Nav组件中,并给需要左浮动的NavItem组件加上className:left,给需要右浮动的NavItem组件加上className:right:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React, { Component } from 'react'
import {
HeaderWrapper,
Logo,
Nav,
NavItem,
} from "./style";


class Header extends Component {
render() {
return (
<HeaderWrapper>
<Logo />
<Nav>
<NavItem className="left">首页</NavItem>
<NavItem className="left">下载App</NavItem>
<NavItem className="right">登录</NavItem>
<NavItem className="right">Aa</NavItem>
</Nav>
</HeaderWrapper>
)
}
}

export default Header;

多个className的使用

实现效果
实现效果

我们要使“首页”颜色不同,就需要给它多加一个独特的样式,此时调用该组件时就需要设置多个className,多个className属性值之间用 空格 分隔
style.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}
`

index.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React, { Component } from 'react'
import {
HeaderWrapper,
Logo,
Nav,
NavItem,
} from "./style";


class Header extends Component {
render() {
return (
<HeaderWrapper>
<Logo />
<Nav>
<NavItem className="left active">首页</NavItem>
<NavItem className="left">下载App</NavItem>
<NavItem className="right">登录</NavItem>
<NavItem className="right">Aa</NavItem>
</Nav>
</HeaderWrapper>
)
}
}

export default Header;

搜索框NavSearch组件

还剩三个组件
还剩三个组件,我们先来完成搜索框
注意:定义样式组件时是styled.input,带一个placeholder属性,使用&::placeholder定义 属性placeholder 的样式。

&::placeholder定义 属性placeholder 的样式

style.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export const NavSearch = styled.input.attrs({
placeholder: "搜索"
})`
width: 160px;
height: 38px;
padding: 0 20px;
margin-top:9px;
margin-left:20px;
box-sizing:border-box;
border:none;
outline:none;
border-radius:19px;
background: #eee;
font-size: 14px;
&::placeholder{
color: #999;
}
`

index.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import React, { Component } from 'react'
import {
HeaderWrapper,
Logo,
Nav,
NavItem,
NavSearch,
} from "./style";


class Header extends Component {
render() {
return (
<HeaderWrapper>
<Logo />
<Nav>
<NavItem className="left active">首页</NavItem>
<NavItem className="left">下载App</NavItem>
<NavItem className="right">登录</NavItem>
<NavItem className="right">Aa</NavItem>
<NavSearch />
</Nav>
</HeaderWrapper>
)
}
}

export default Header;

Header组件最右部分:Addition组件

“注册”和“写文章”按钮

实现效果

  1. 定义一个div的样式组件Addition,它是绝对定位的,相对<HeaderWrapper>进行定位,脱离文档流 悬浮在页面右上角
  2. 我们将 注册和写文章按钮 绝对定位Addition中。
  3. 定义div的样式组件Button,“注册”和“写文章”按钮就使用该组件。

注意
中间导航栏Nav与右边两个按钮重合,此时给Nav增加padding-right时还要设置为 替代盒模型box-sizing-border-box,这样才能保证width是我们可见的宽度
(标准盒模型 的宽度只是内容的宽度,不包括padding与border,所以我们一旦设置padding与border就应该设置替代盒模型,以确保我们设置的width就是我们看到的宽度)

1
2
3
4
5
6
7
export const Nav = styled.div`
width:960px;
height:100%;
margin: 0 auto;
box-sizing:border-box;
padding-right: 70px;
`

style.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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;
}
`

index.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import React, { Component } from 'react'
import {
HeaderWrapper,
Logo,
Nav,
NavItem,
NavSearch,
Addition,
Button,
} from "./style";


class Header extends Component {
render() {
return (
<HeaderWrapper>
<Logo />
<Nav>
<NavItem className="left active">首页</NavItem>
<NavItem className="left">下载App</NavItem>
<NavItem className="right">登录</NavItem>
<NavItem className="right">Aa</NavItem>
<NavSearch />
</Nav>
<Addition>
<Button className="writting">写文章</Button>
<Button className="reg">注册</Button>
</Addition>
</HeaderWrapper>
)
}
}

export default Header;

,