# bootstrap简介与安装
官网:<https://getbootstrap.com/>
`bootstrap` 的 `github` 地址:<https://github.com/twbs/bootstrap>
`bootstrap` 是一个用于制作页面界面的框架
框架: 提供一个标准和规范,再由开发人员自行填充内容
## 安装
点击页面中的 download 按钮:<https://getbootstrap.com/docs/5.0/getting-started/download/>
或者在 `github` 中下载 `bootstrap` 源代码,源代码中的 `dist` 文件夹就是我们要用的文件
`npm` 安装
```shell
npm i bootstrap
- [布局](#布局)
- [响应式布局](#响应式布局)
- [断点](#断点)
- [布局容器](#布局容器)
- [网格布局](#网格布局)
# 布局
## 响应式布局
响应式布局就是根据屏幕宽度,切换不同页面布局的一种布局方式,这里可以查看 bootstrap 官网在不同屏幕宽度下的表现
bootstrap 是使用断点来完成响应式布局的
## 断点
断点是 bootstrap 面向不同屏幕宽度,预制好的媒体查询
通常的讲,断点,代表的就是不同的屏幕宽度
bootstrap 中如何体现断点,在class中,添加不同断点的名称,可以采用不同断点的样式
# 布局容器
通常是页面的根节点,使用 `class="container"` 来设置布局容器
布局容器受断点影响,可以设置不同断点上的容器,具体可查表:
<https://getbootstrap.com/docs/5.0/layout/containers/>
## 网格布局
将内容进行行列分布的布局方式就叫网格布局
bootstrap中网格布局的灵魂样式就是 行:`row`,列:`col`
display显示方式
<!-- 参考:https://getbootstrap.com/docs/5.2/utilities/display/ -->
<!-- 语法:
在 xs 断点下: d-{value}
xs 以上: d-{breakpoints}-{value}
-->
<!-- 当屏幕宽度小于 sm 时显示 -->
<div class="container d-block d-sm-none">小于 sm</div>
<!-- 当屏幕宽度为 md 时 显示 -->
<div class="container d-none d-sm-block d-md-none">md</div>
<!-- 当屏幕宽度大于 lg 时 显示 -->
<div class="container d-none d-md-block">大于 lg</div>
原声表单验证
<!--
// 参考:https://developer.mozilla.org/zh-CN/docs/Learn/Forms/Form_validation
知识点
学会使用html自带的表单验证
input 的验证属性
required
pattern
minlength maxlength
min max
type
novalidate 屏蔽html自带的验证报告
input 的 validity 属性
validity.valueMissing
validity.patternMismatch
validity.rangeOverflow
validity.rangeUnderflow
validity.tooLong
validity.tooShort
validity.valid
自定义提示信息
input.setCustomValidity
form 或 input 的 checkValidity
显示验证报告
form.reportValidity()
表单验证总结步骤
1. 给表单添加 novalidate 屏蔽自动验证报告
2. 对每个元素的 validity 属性进行验证
3. 根据每个元素的验证结果设置自定义异常 setCustomValidity
4. 提交验证报告
5. 根据验证结果执行后续网络操作
# 其他组件和工具类
除了布局和表单元素等基础功能外,`bootstrap` 还提供了一系列的开箱即用的功能
例如组件(`Component`)和工具类(`Utilities` 和 `Helper`),这些东西需要开发者在需要时,按需引入
<https://getbootstrap.com/docs/5.1/components/accordion/>
其中,部分组件包含动画,若要使用带动画的组件,请引入 `bootstrap.js` 文件,并参考文档中的 `via JavaScript` 部分进行函数调用
# 媒体文件和图片懒加载(lazy-loading)
什么是懒加载?
懒加载就是页面中看不到时,就不去加载它,当页面中出现该内容时再去加载
懒加载多用于图片和媒体文件
好处:
好处在于用户看不见的东西就不用使用浏览器去下载了
还可以让页面加载更快
// 总结
// 1. 给需要懒加载的元素添加 data-src
// 2. 给滚动元素添加 scroll 事件监听器
// 3. 计算显示图片的临界值 scrollTop = 内容高 - 图片高 - 窗口高
// 4. 判断容器元素的 scrollTop 大于临界值 加载 data-src
react
# react 简介
中文官网:<https://zh-hans.reactjs.org/>
`react` 是一个 **js核心库**,如同 `jquery` 一样,具有大量 `react` 生态(围绕 `react` 核心开发的库)
特点:
- 声明式
- 也就是js中的数据决定页面最终渲染的结果
- 声明式不是响应式,但往往都是同时出现共同作用页面
- 响应式:数据变化页面会立即更新
- 组件化
- 一个包含所有外观和行为的,独立可运行的模块,称为组件
- 组件化的思想可以将复杂页面,化繁为简的进行设计
- 组件可提高代码复用性
- 一次学习,跨平台编写
- 使用 `react` 可以开发 桌面web页面,移动端页面,移动app,桌面app等
# jsx 语法
jsx 语法保留了js的所有特性,在此基础上扩展了 react 的元素声明语法,例如:
```jsx
// 声明一个 react-dom
const element = <h1>Hello World</h1>
若 react-dom 标签有多行,可以用圆括号包裹
```jsx
const element = (
<h1>
Hello World
</h1>
)
每一给 react-dom 只能有一个根节点
```jsx
const element = (
<h1>
Hello World
</h1>
// h1 和 h2 都是根节点 这个写法是错误的
<h2>
222
</h2>
)
## 插值
将变量插入到元素中,使用大括号 `{}`
```jsx
const msg = 'hello world !!!'
const element = <h1>{msg}</h1>
花括号内的插值部分可以写入任何有效的 js 表达式
## 插入html属性
直接使用引号或花括号插入表达式,如:
```jsx
const styleObj = {backgroundColor: "green"}
// 需要注意的是 style 属性必须用花括号来插入值
// 不是所有的html属性名都是原始名称,例如 class 应该写为 className 并采用驼峰式命名方法 而不是html的短横线 因为本质上这里的标签是js代码
const element = (
<h1
style={styleObj}
className="content">
Hello World
</h1>
)
```
## 使用函数创建对象
```jsx
// 可以使用函数创建 react-dom 对象
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
// 等价于
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
```
> 注意:jsx 中的 react-dom 内容,本质上会被 babel 翻译成 React.createElement 函数
什么是组件
组件具备以下特点
1. 独立显示的页面内容
2. 独立维护的组件状态
3. 组件被当作标签使用
// 所以,组件是一个具备独立显示内容,独立维护状态,被当作标签使用的可复用模组
// 应用场景
// 可复用的页面内容,就可以考虑封装成组件
// 声明组件
// 类组件
// render函数
// 构造函数和props
// props.children
// 函数组件
// 参数props
// 函数组件没有this
// react 中声明组件有两种方法
// 一种叫 类组件 另一种叫 函数组件
// 两种组件对于 react 来说是等价的
// 声明类组件
// 需要继承 React.Component
class AComponent extends React.Component {
// 可以有组件的属性
label = 'h'
// 构造函数中包含props参数
// props 代表组件的 html 属性
// props 是只读属性
constructor(props) {
// 由于存在父类 React.Component
// 所以构造函数中应先调用super
super(props)
// render 函数中可以使用 this.props 访问此处的 props
console.log(props)
// 可以使用 props.children 代表组件标签体里的内容
console.log(props.children)
}
// 可以有组件方法
getTime() {
return new Date()
}
// 类组件中必须包含 render 方法
render() {
// render 方法必须返回一个 react-dom 对象
// 返回的 react-dom 对象用于描述组件长什么样子的
return (
<div>
{/* 组件中可以调用自己的属性和方法 */}
{this.label}: {this.getTime().getHours()}; m: {this.getTime().getMinutes()};
s: {this.getTime().getSeconds()}
<br/>
{/* 标签体的内容可以插值到 render 中 */}
{this.props.children}
</div>
)
}
}
// 函数组件
// 参数props就是标签的html属性
// props 中也包含 children
function BComponent(props) {
// 此处的this为 undefined
// 之所以为 undefined 是因为函数组件没有实例对象
console.log(this)
console.log(props)
// 可以在组件内声明其他函数和变量
let count = 0
function getCount() {
return count
}
// 函数组件必须返回一个react-dom对象
return (
<div>
<div>我是一个函数组件</div>
<div>{count}: {getCount()}</div>
<div>{props.children}</div>
</div>
)
}
ReactDOM.createRoot(document.querySelector('#root')).render((
<div>
{/* 组件被当作标签使用 */}
{/* 可以使用插值给属性赋值 这样赋值的属性就可以不是字符串 */}
<AComponent name="张三" age={16} isShow={false}>
<div>hello</div>
<div>world</div>
</AComponent>
<AComponent></AComponent>
<BComponent name="张三" age={16} isShow={false}>
<h1>这是BComponent的标签体</h1>
<div>hello</div>
<div>world</div>
</BComponent>
</div>
))
什么是组件状态?
// 在计算开发领域 怎么理解状态(state)这个英文?
// 假设我们制作一个时钟,时钟每秒钟的时间值都不一样
// 那么我们将描述某个 “时刻” 的时钟的 “数据” 称为该时钟在那个 “时刻” 的 “状态” (state)
// 所以 state 一词,通常指某个时刻用于描述某个对象的数据模型
// 因此 有时会听到上一个状态 下一个状态的说法 这指的就是不同时刻 描述同一个对象的数据模型
// 声明状态
// 组件的状态更新 this.setState 的使用
// 1. 不要直接修改 state 要通过 setState 修改
// 2. setState 的参数不要直接依赖 this.state 或 this.props;应使用 this.setState((state, props)=>{return {}}) 代替
// 3. setState 方法是异步的 可以通过 setState 的第二个回调函数 来执行赋值成功后的代码
// 4. setState 最终会修改 this.state
什么是生命周期
// 当我们以面向对象的思想看待组件时,可以将组件看成一个人
// 那么人就有生老病死的过程,那么组件的生老病死的过程是通过组件的方法来体现的
// 这些体现生命过程的方法,就称为生命周期
// 总结:
// 人->生老病死
// 代码->用函数来描述对象的生老病死
// 生命周期有哪些阶段
// 挂载
// constructor()
// static getDerivedStateFromProps() // https://zh-hans.reactjs.org/docs/react-component.html#static-getderivedstatefromprops
// render()
// componentDidMount()
// 更新
// static getDerivedStateFromProps(props, state)=>{[key: string]: any} 每次调用渲染函数render前调用,返回值是希望改变的状态对象
// shouldComponentUpdate(props, state)=>boolean 判断是否应该更新,返回一个布尔值
// render()
// getSnapshotBeforeUpdate(prevProps, prevState)=>{[key: string]: any} 每次更新前调用,返回值将被传递给 componentDidUpdate 充当第三个参数
// componentDidUpdate(prevProps, prevState, snapshot)
// 卸载
// componentWillUnmount()
// 异常捕获
// static getDerivedStateFromError()
// componentDidCatch()
// 应用场景
// 其中 挂载和卸载的 生命周期用得比较多
// constructor() 常用于初始化组件,拉取远程数据
// componentDidMount() 用于页面第一次渲染完成后,查询页面元素
// componentWillUnmount() 卸载组件时对事件的解绑等需要处理的事
// 卸载组件
// root.unmount()