简道云crm管理系统/优化设计七年级下册数学答案
不管是任何框架, React|Vue|angular也好, 设计之初都是希望我们按照 组件|模块
的方式来构建程序, 也就是把一个程序划分成多个组件, 写好后渲染到页面即可
-
优点:
-
利于多人开发, 每个人只需要管理自己的组件
-
组件能够被重复利用
-
减少代码冗余
…
-
-创建组件
组件存放位置为 项目根目录/src/component
1.函数声明式
-
首先在src/component下创建组件 导航栏组件
Header.js
-
编写组件代码
import React from 'react' // 每个组件中都要导入React, 因为需要用到React.reactElement渲染JSX语法/** * 函数声明式对话框组件 * 1. 函数返回结果是一个新的JSX对象, 也就是当前组件的结构 * 2. props变量存的是一个对象, 包含了调用组件时传递的属性, 不传递为{} */ export default function Dialog(props) {console.log(props) // Object { con: "hhh", ll: 6, what: "666" }let {con='我是默认的内容', what='我也是默认的内容'} = props // 对组件调用传入参数的结构con = con !== 1 ? con : '啦啦啦' what = what !== 1 ? what : '嘻嘻嘻' return <section><h2>{con}</h2><div>{what}</div></section> }
-
调用组件
2.继承式创建
-
首先在src/component下创建组件 导航栏组件
Header.js
-
编写组件代码
export default class Dialog extends React.Component {constructor(props, context) {super(props, context) // 写法1super() // 写法2// super(), 如果就这样写, 不挂载props和context, React.Component会有方法帮你挂载// 1. super()继承绑定两个属性 1. props属性 2. context上下文// 2. 就算没有在super里面传入props和context, 在构造函数执行的时候会自己挂载到实例}render() {// 必须有render函数, 内部会调用render并获得返回的组件let { type, content, children } = this.propsconsole.log(content)// => 自己写的样式const myCss = {width: '50%',margin: '0 auto 10px',padding: '0'}// => 传入的类型处理let typeValue = type || '系统提示'if (typeof type === 'number') {switch (type) {case (0): {typeValue = '系统提示'break}case (1): {typeValue = '系统错误'break}case (2): {typeValue = '系统警告'break}default: {typeValue = '真香'break}}}return <section className="panel panel-default col-lg-4" style={myCss}><div className="panel-heading"><h3 className="panel-title">{typeValue}</h3></div><div className="panel-body">{content}</div>{children ? <div className="panel-footer">{React.Children.map(children, item => item)}</div> : null}</section>} }
-
调用组件
3.两种方式对比
- 函数式组件更加快捷方便, 但是实现的功能比较单一
- 继承式组件虽然复杂, 但是可以实现更多的功能, 还能调用生命周期函数操作业务
- 各有优缺点, 根据需求来取舍
-组件属性管理
在继承式组件中, 所有实例的属性都是不可修改的
1.设置默认值
虽然在继承式组件中不能修改props的值, 但是可以设置默认值
// 在组件中加入这行代码, 设置props里面的默认值static defaultProps = {lx: '我是默认值'}
2.设置类型限制
需要用到React全家桶中的prop-types
插件
-
下载
yarn add prop-types
-
使用
import PropTypes from 'prop-types'static propTypes = { // 设置时候, 仅仅是在console上进行warning警告 lx: PropTypes.number, // 必须是numbercontent: PropTypes.string.isRequired, // 不仅是字符串, 而且必须传递值value: PropTypes.instanceOf('Promise') // 必须是Promise的示例 }
-
使用
-组件状态管理
React中有两个非常重要的概念
- 组件的属性 [只读] : 调用组件时候调用方传递进来的
- 组件的状态 [读写] : 自己在组建中设定和编写的 ( 只有类组件才有状态管理 )
首先做一个案例: 时钟效果
-
函数组件实现
函数组件式
静态组件
, 和执行普通方法一样, 调取一次, 就能获得一个固定的结果, 如果不重新调取组件, 组件内的值就不会变化 -
类组件实现
可以借用钩子函数 ( 周期函数 ), 来对组件的状态进行改变
当组件状态一发生改变, 组件就会基于 DOM-DIFF 算法进行再次DOM差异渲染
1.初始化状态
constructor(props) {super(props)// 初始化组件状态(对象类型)=>把需要被修改的状态在这里挂载初始化this.state = {time: (new Date()).toLocaleString()}
}
2.改变组件状态
componentDidMount() {// 钩子函数(生命周期函数之一): 该组件第一次渲染之后触发setInterval(() => {// 修改组件状态, 并通知React重新渲染页面/** * 1.修改状态对象中的部分状态, 只把我们传递状态的进行修改* 2.当状态修改完成后, 会通知React把组件中的部分JSX元素重新渲染*/this.setState({ time: (new Date()).toLocaleString() }, () => {console.log('ok') // 当React把需要重新渲染的JSX渲染之后触发})}, 1000)
}
-组件事件处理
首先做一个案例,简单的投票系统
-
代码
class Vote extends React.Component {static defaultProps = {title: '我是标题'}static propTypes = {title: PropTypes.string.isRequired}constructor(props, context) {super(props, context)this.state = {support: 0,oppose: 0,}}render() {let { support, oppose } = this.state,rate = support + oppose === 0 ? 0 : ((support / (support + oppose)) * 100).toFixed(2)return <section className='panel panel-default' style={{ width: '60%', margin: '20px auto' }}><div className='panel-heading'><h3 className='panel-title'>{this.props.title}</h3></div><div className='panel-body'>支持人数: {support}<br /><br />反对人数: {oppose}<br /><br />支持率: {rate}%</div><div className='panel-footer'>{/* <button className='btn btn-success' onClick={this.support.bind(this)}>支持</button> */}<button className='btn btn-success' onClick={this.support}>支持</button> <button className='btn btn-danger' onClick={this.oppose}>反对</button></div></section>}support = (ev) => {this.setState({support: this.state.support + 1})}oppose = (ev) => {this.setState({oppose: this.state.oppose + 1})} }
-
运行效果
1.添加事件
class Example extends React.Component {constructor(props, context) {super(props, context)}render() {return <div><button onClick={this.alertLogin}>登录</button><button onClick={this.alertLogout}>注销</button></div>}alertLogin = (e) => {// 会默认传入事件对象ealert('登录')}alertLogout = (e) => {// 会默认传入事件对象ealert('注销')}
}
2.事件回调this指向
在React组件中调用事件回调函数, 事件函数内部的this
与我们想象的不太一样, 是undefined
-
普通函数用
bind
绑定class Example extends React.Component {constructor(props, context) {super(props, context)}render() {return <button onClick={this.alertThis.bind(this)}>按钮</button>}alertThis(e) {// 会默认传入事件对象econsole.log(this)} }
-
利用箭头函数特性
ES6在类中定义的箭头函数, 其上下文是当前实例
class Example extends React.Component {constructor(props, context) {super(props, context)}render() {return <button onClick={this.alertThis}>按钮</button>}alertThis = (e) => {// 会默认传入事件对象econsole.log(this)} }
-
普通函数+箭头函数
class Example extends React.Component {constructor(props, context) {super(props, context)}render() {return <button onClick={() => this.alertThis()}>按钮</button>}alertThis (e) {// 会默认传入事件对象econsole.log(this)} }
3.向事件回调传递参数
-
bind实现
<button onClick={this.alertThis.bind(e, 'v1', 'v2')}>按钮</button>alertThis(value, value2, e) {console.log(e)console.log('value', value)console.log(this) }
-
箭头函数实现
<button onClick={(e) => this.alertThis(e, 'v1', 'v2')}>按钮</button>alertThis(e, value1, value2) {console.log(e)console.log('value1', value1)console.log('value2', value2)console.log(this) }