一:组件样式设置
可以使用传统的css,不过传统的css容易造成样式的污染
解决办法:
-
LESS SASS
-
styled-components库
1·1:styled-components可以解决的问题是:
全局污染 - CSS的选择器是全局生效的,所以在class名称比较简单时,容易引起全局选择器冲突,导致样式互相影响。
命名混乱 - 因为怕全局污染,所以日常起class名称时会尽量加长,这样不容易重复,但当项目由多人维护时,很容易导致命名风格不统一。
样式重用困难 - 有时虽然知道项目上已有一些相似的样式,但因为怕互相影响,不敢重用。
代码冗余 - 由于样式重用的困难性等问题,导致代码冗余。
1·2:styled-components的介绍
styled-components 是一个常用的 JavaScript里写CSS 类库。和所有同类型的类库一样,通过 js 赋能解决了原生 css 所不具备的能力,比如变量、循环、函数等。
对从组件层面维护CSS样式的需求日益增大,styled-components就是在组件内部使用JavaScript对CSS进行了抽象,可以对其声明和加以维护。这样不仅降低了编写CSS样式带来的风险,也让开发变得更加轻松。它和CSS 模块化的区别是不再需要CSS样式文件。
1·3:styled-components的使用
- 下载:npm install --save styled-components【或者vscode-styled-components插件】
- 在需要使用的组件文件夹中创建styled文件夹并在其中创建js文件【注意组件首字母必须大写不然无法识别】
- 在组件中引用该以js结尾的css文件
第一步:创建一个以js文件为结尾的css文件
// 在这里使用styled-Components进行样式的书写(npm包下载的)
import styled from "styled-components"
//注意一点:使用export暴露的东西,需要结构
export let Styled = styled.div`
div{
background-color:red;
p{
color:greenyellow
}
}`
第二步:将该css文件引入到需要的jsx文件里
import React, { Component } from 'react'
import { Styled } from "./cssyang.js"
export default class csscom extends Component {
render() {
return (
<Styled>
<div>
我是stylecompont的组件
<p>我是css样式嵌套的div中的p标签</p>
</div>
</Styled>
)
}
}
二:多行标签
在脚手架使用多行标签有两种方法
- 方式一:传统的方式 (会增加很多多余的div)
- 方式二:使用空标签<></>(有点傻,测试过不来)
- 方式三:Fragment不在DOM中增加额外节点(比较推荐)
2·1:Fragment的使用
第一步:解构
import React, { Component, Fragment } from 'react'
第二步:添加标签
// 要是想要在这里实现多行标签,就添加一个Fragment标签
<Fragment>
<Styled>
<ul>
<li>11111</li>
<li>22222</li>
<li>33333</li>
<li>44444</li>
</ul>
</Styled>
</Fragment>
三:所有组件的子节点
3·1:为什么需要使用所有组件的子节点
需要在在组件调用的开标签和关标签之中写入内容并进行渲染,采用的是this.props.children
说明白了也就是将在父组件组件调用的开标签和关标签之中写入内容在子组件内进行渲染出来
3·2:this.props.children的值
this.props.children属性,它表示组件的所有子节点
this.props.children的值有三种可能:
- 如果当前组件没有子节点,它就是undefined;
- 如果有一个子节点,数据类型是Object;
- 如果有多个子节点,数据类型就是array。
3·3:this.props.children的一般使用
父组件
import React, { Component,Fragment } from 'react'
import Son from "./son.jsx"
export default class father extends Component {
render() {
return (
<Fragment>
<p>爸爸爸爸</p>
<Son>
//按道理:写在这里的内容是渲染不出来的
<p>爸爸一号</p>
<p>爸爸二号</p>
<p>爸爸三号</p>
</Son>
</Fragment>
)
}
}
子组件
<p>儿子儿子儿子儿子</p>
{
//通过它将父组件的内容渲染出来
this.props.children
}
四:强制刷新
在学完了状态的时候我们就把所有的数据放到state中 state修改了页面就会自动更新
需求:不把数据放到状态里,还想要修改了数据以后让页面自动渲染
【解决】:forceUpdate()就是重新调用render渲染。
constructor(props) {
super(props)
this.text = "123"
}
fun = () => {
this.text = "345是我被修改的值"
this.forceUpdate()
}
<h1 onClick={this.fun}>我是需要强制刷新的---{this.text}</h1>
五:组件正向传值
5·1:脚手架和本地state的区别
在脚手架中使用状态state和在本地模式是一样的
以及传参数也是一样的,有两种方法
5·2:正向传值props
父组件
自定义的名字={参数}
constructor(props) {
super(props)
this.state = {
text: "你好之华"
}
}
<Son name={this.state.text}></Son>
子组件:
this.props.自定义的名字
<p>我是正向传值的儿子---{this.props.name}</p>
六:组件逆向传值
父组件
通过自定义名字=函数接受参数
fun=(can)=>{
console.log(can)
}
<p>我是逆向传值的爸爸</p>
<Son father={this.fun}></Son>
子组件
通过this.props.自定义名字进行发送数据
<button onClick={this.props.father.bind(this,"偷偷告诉你,我是逆向传来的数据")}>点击进行数据逆向传值</button>
七:组件同胞传值
7·1:同胞传值的介绍
同胞传值使用pubsub-js
第一步:下载npm install --save pubsub-js
第二步:第一个组件中进行数据抛出 PubSub.publish(“事件名”,“数据”)
第三步:在第二个组件中接收PubSub.subscribe(“监听的事件”,(事件,数据)=>{})
子组件1
通过 Pubsub.publish发送参数
import Pubsub from "pubsub-js"
fun=()=>{
Pubsub.publish("pao","这里是传过来的参数")
}
<p>我是同胞传值的第二个儿子(弟弟)</p>
<button onClick={this.fun}>点我今进行同胞传值</button>
子组件2
通过 Pubsub.subscribe接受擦传过来的参数
import Pubsub from "pubsub-js"
componentDidMount() {
Pubsub.subscribe("pao", (a, b) => {
//参数a是表示发送的事件
console.log("a"+a)
//参数a是表示发送的参数
console.log("b"+b)
})
}
八:跨组件传值context
8·1:context的介绍
context叫做上下文对象,可以解决跨组件传值的问题
使用context进行跨组件传值,就要使用到createContext()方法【该方法是react的方法】
同时该方法中给我们提供了两个对象:
•Provider对象 生产者---->用来生产数据
•Consumer对象 消费者---->用来使用数据
8·2:content的使用
第一步:创建一个文件context.js和文件夹contnxt用来保存content对象,
第二步:在该文件下context.js创建内容,并引用createContext对象
import React, { Component, createContext } from 'react'
// 创建上下文对象
let context=createContext()
let {Provider,Consumer}=context
class Mycontext extends Component {
render() {
return (
<div>
<Provider value={{name:"haha",text:"我是生产者"}}>
{this.props.children}
</Provider>
</div>
)
}
}
export{Mycontext,Consumer}
第三步:在根组件下使用创建好的引用createContext对象文件
import {Mycontext} from "./context/mycontext"
<Mycontext>
</Mycontext>,
第四步:在该文件下context.js创建生产者和消费者
第五步:在该文件下通过Provide的value属性传递参数
第六步:将当前组件和消费者对象进行暴露
第七步:在需要使用组件进行使用
import {Consumer}from "../context/mycontext"
<Consumer>
{
(value)=>{
return (
<div>{value.text}---{value.name}</div>
)
}
}
</Consumer>
,
第四步:在该文件下context.js创建生产者和消费者
第五步:在该文件下通过Provide的value属性传递参数
第六步:将当前组件和消费者对象进行暴露
第七步:在需要使用组件进行使用
```js
import {Consumer}from "../context/mycontext"
<Consumer>
{
(value)=>{
return (
<div>{value.text}---{value.name}</div>
)
}
}
</Consumer>