当前位置:   article > 正文

高级特效开发_col-{breakpoint}-{number}

col-{breakpoint}-{number}

bootstrap 简介与安装

官网:https://getbootstrap.com/
中文网: https://v5.bootcss.com/docs/getting-started/introduction/

bootstrapgithub 地址:https://github.com/twbs/bootstrap

bootstrap 是一个用于制作页面界面的框架
复制/粘贴!经典!

框架: 由第三方提供一个标准和规范,再由开发人员自行填充内容

基于已存在的框架,可以到达快速开发项目的目的!
很多的实际应用例子可以直接使用! 1.复制 2.使用(粘贴) 3.适当的修改

bootstrap

响应式布局

响应式布局就是根据 pc 屏幕宽度,切换不同页面布局的一种布局方式,这里可以查看 bootstrap 官网在不同屏幕宽度下的表现

bootstrap 是使用断点来完成响应式布局的

断点 breakPoint

sm md lg xl xxl

断点是 bootstrap 面向不同屏幕宽度,预制好的媒体查询

通常的将,断点,代表的就是不同的屏幕宽度

bootstrap 中如何体现断点,在 class 中,添加不同断点的名称,可以采用不同断点的样式

<!-- breakpoint 待选值:
  - sm
  - md
  - lg
  - xl
  - xxl


-->
<!-- 语法:   row-cols-{Breakpoints}-{number} -->
<!-- 对应断点下,显示不同的列 -->

<div class="container">
  <div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4">
    <div class="col bg-light">col</div>
    <div class="col bg-danger">col</div>
    <div class="col bg-light">col</div>
    <div class="col bg-light">col</div>
  </div>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

布局容器

通常是页面的根节点,使用 class="container" 来设置布局容器

布局容器受断点影响,可以设置不同断点上的容器,具体可查表:

https://getbootstrap.com/docs/5.0/layout/containers/

网格布局

将内容进行行列分布的布局方式就叫网格布局

bootstrap 中网格布局的灵魂样式就是 行:row,列:col

<!-- 
   网格布局:实际上可以类比着表格布局进行学习!
   注意:只是类比学习,本质上网格布局!比表格布局更好,更强大,更灵活!
 -->
<!-- 
  表格布局中存在三个元素:
    1.表格容器(table) 2.行(tr) 3.列(td)  html标签
  网格布局中存在三个元素:
    1.布局容器(container) 2.行(row)  3.列(Colum)  bootstrap提供的类名


 -->
<!-- 网格布局的一行最多只能只能有 12 列  如果一行超过12列则自动换行!前提是每列占据确定的份数-->
<!-- row元素本身是一个flex布局 -->
<!-- 官网例子 -->
<h5>1.网格布局基本使用</h5>
<!-- text-center 容器中文本排列方式类  -->
<!-- style  text-align:center -->
<div class="container text-center">
  <!-- div ==> 行 -->
  <div class="row">
    <!-- class==> col 列-->
    <div class="col bg-danger">Column</div>
    <div class="col bg-info">Column</div>
    <div class="col bg-warning">Column</div>
    <div class="col bg-warning">Column</div>
  </div>

  <div class="row">
    <div class="col bg-danger">Column</div>
    <div class="col bg-info">Column</div>
    <div class="col bg-warning">Column</div>
    <div class="col bg-warning">Column</div>
  </div>
</div>

<h5>2.单独指定每一列所占份数 语法:col-{number} number:1-12</h5>
<!-- 
  注意:如果某一列未设置固定分数则自动对其分配剩余空间
 -->
<div class="container">
  <div class="row">
    <div class="col-6 bg-danger">hello1</div>
    <div class="col-5 bg-info">hello2</div>
    <div class="col bg-dark">hello3</div>
  </div>
</div>

<h5>3.指定一行中列的个数 row-cols-{number}</h5>
<div class="container">
  <div class="row row-cols-6">
    <div class="col">col1</div>
    <div class="col">col2</div>
    <div class="col">col3</div>
    <div class="col">col3</div>
    <div class="col">col3</div>
    <div class="col">col3</div>
    <div class="col">col3</div>
  </div>
</div>

<h5>4.边框 border 类</h5>
<!-- bootstrap框架   左右  left  right    被替换成了   start  end -->
<div class="container text-start">
  <div class="row">
    <div class="col border">col1</div>
    <div class="col border">col2</div>
    <div class="col border">col3</div>
  </div>
</div>

<h5>5.单元格嵌套</h5>
<div class="container text-center">
  <div class="row">
    <div class="col bg-danger">
      <div class="row">
        <div class="col-auto">child</div>
        <div class="col-1">2</div>
      </div>
    </div>
    <div class="col">col2</div>
    <div class="col">col3</div>
  </div>
</div>

<h5>6.单元格间距 gx-{number} gy-{number}</h5>
<!-- 
    gx-{nunber}  决定一行中每一个单元格的内容与边框之间的间距

    gy-{number}  决定一行中所有表格的上下间距

    number的取值范围 1-5

    gy-*  gx-* 加给row元素 
 -->

<div class="container">
  <!-- bootstrap中 很多的类,看似重复!看似类似的东西,但是其功能不一样 -->
  <!-- 
    比如: row  ==》 决定该元素是否是一个网格中行元素
          row-cols-{number}  ==》 决定该行元素中有最多的列数值

        

   -->
  <!-- gy-* 所决定同行的列元素自动换行后,的上下间距! -->
  <div class="row gy-5">
    <div class="col-6 bg-info">column1</div>
    <div class="col-6 bg-danger">column2</div>
    <div class="col-6 bg-danger">column2</div>
    <div class="col-6 bg-danger">column2</div>
  </div>
</div>

<h1>断点 : 关于列元素的断点份数指定 根据断点指定每一列所占份数</h1>
<!-- 断点 : 关于列元素的断点分数指定 -->
<!-- 语法:  col-{breakpoint}-{number} -->
<!-- 

  breakpoint待选值:  
      -  sm
      -  md
      -  lg
      -  xl
      -  xxl


 -->
<div class="container text-center">
  <div class="row">
    <!-- col-md-2 类什么时候会生效? 当屏幕到达指定断点时 md 生效-->
    <!-- col-lg-10 类什么时候会生效?当屏幕到达指定断点时 lg 生效 -->
    <div class="col col-md-2 col-lg-10 bg-danger">colmun1</div>
    <div class="col bg-dark">colmun2</div>
  </div>
</div>

<h1>列元素的自动宽度</h1>
<!-- col-auto -->
<div class="container">
  <div class="row">
    <div class="col-auto bg-danger">child112313213231</div>
    <div class="col-auto bg-success">child24654564646</div>
    <div class="col bg-info accordion">child24654564646</div>
  </div>
</div>
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
网格的横向布局
<!-- 单元格的横向布局 -->
<!-- row 默认是一个弹性容器  利用设置主轴的对齐方式即可 -->
<!-- 
  在原生的css样式中,可以利用flex布局,对弹性盒在主轴上的元素进行排列方式的定义!

  div {
    display:flex;
    justify-content:start  ||  end ||  space-between....
  }


 -->
<!-- 关注点在行上 -->
<!-- 语法:  justify-content-{value} -->
<div class="container text-center">
  <div class="row justify-content-start border">
    <div class="col-4 bg-danger">One of two columns</div>
    <div class="col-4 bg-dark">One of two columns</div>
  </div>
  <div class="row justify-content-center border">
    <div class="col-4 bg-success">One of two columns</div>
    <div class="col-4 bg-primary">One of two columns</div>
  </div>
  <div class="row justify-content-end border">
    <div class="col-4 bg-info">One of two columns</div>
    <div class="col-4 bg-danger">One of two columns</div>
  </div>
  <div class="row justify-content-around border border-5">
    <div class="col-4 bg-success">One of two columns</div>
    <div class="col-4 bg-info">One of two columns</div>
  </div>
  <div class="row justify-content-between border border-5">
    <div class="col-4 bg-danger">One of two columns</div>
    <div class="col-4 bg-info">One of two columns</div>
  </div>
  <div class="row justify-content-evenly border border-5">
    <div class="col-4 bg-primary">One of two columns</div>
    <div class="col-4 bg-danger">One of two columns</div>
  </div>
</div>

<div>----------------------------------</div>

<!-- 单元格的纵向布局 -->
<!-- 关注点在每一列上 设置弹性元素在侧轴上的对齐方式 -->
<!-- 语法: align-items-{value}  控制所有的单元格的纵向排列方式 -->

<div class="container text-center">
  <div class="row align-items-start border border-5" style="height: 300px">
    <div class="col bg-secondary">One of three columns</div>
    <div class="col bg-danger">One of three columns</div>
    <div class="col bg-dark">One of three columns</div>
  </div>
</div>

<div>-------------------------------</div>
<!-- 语法:  align-self -->
<div class="container text-center">
  <div class="row border border-5" style="height: 300px">
    <div class="col align-self-start">One of three columns</div>
    <div class="col align-self-center">One of three columns</div>
    <div class="col align-self-end">One of three columns</div>
  </div>
</div>
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

display

    display语法
    d-{value} || d-{breakpoint}-{value}
    value待选值:
        none
        inline
        inline-block
        block
        grid
        table
        table-cell
        table-row
        flex
        inline-flex


<!-- 普通用法 -->
<div class="d-block">hello world!</div>
<span>span元素</span>
<!-- 断点+display -->
<!-- xs断点中显示  sm断点下隐藏  lg断点下又显示 -->

<!-- 需求:有一个盒子
  在正常情况下是显示的状态   200*200  黄色的盒子
  在md断点下隐藏  
  在lg断点下又显示   300*300  红色的盒子

-->

<div class="box1 d-block d-md-none"></div>
<div class="box2 d-none d-lg-block"></div>
  • 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

border





<div>-------------</div>
<span class="border border-primary" style="--bs-border-opacity: 0.1"></span>
<span class="border border-primary-subtle"></span>
<span class="border border-secondary"></span>
<span class="border border-secondary-subtle"></span>
<span class="border border-success"></span>
<span class="border border-success-subtle"></span>
<span class="border border-danger"></span>
<span class="border border-danger-subtle"></span>
<span class="border border-warning"></span>
<span class="border border-warning-subtle"></span>
<span class="border border-info"></span>
<span class="border border-info-subtle"></span>
<span class="border border-light"></span>
<span class="border border-light-subtle"></span>
<span class="border border-dark"></span>
<span class="border border-dark-subtle"></span>
<span class="border border-white"></span>

<div style="width: 200px; height: 100px" class="bg-danger rounded-pill"></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

flex

flex类 工具类 本质是将原生css中所有与弹性容器相关的css属性整合成了类!进行使用!

参考链接:https://getbootstrap.com/docs/5.3/utilities/flex/

float

float类 控制元素是否开启浮动
float 语法
float-{value} || float-{breakpoint}-{value}
value待选值:
start ==》等价于原生css中float的left值
end ==》 等价于原生css中float的right值
none ==》 关闭浮动

position

开启元素的定位
1.开启定位模式
2.设置偏移量 left top right bottom

    position语法
    position-{value}   
    value待选值:
            static 元素静止未开启定位,默认值
            relative 开启相对定位
            absolute  开启绝对定位
            fixed   开启固定定位
            sticky   开启粘滞定位


    元素开启定位后需要设置偏移类(偏移类就是css中的偏移量):
    top  start(等价于以前的left)  end(等价于以前的right)  bottom
    语法:偏移类
    偏移方位-{number}  || 偏移方位-{百分比%}   number的取值范围:0 50 100 对应 0% 50% 100%   相对于父亲的宽度和高度!




    元素除了通过以上的方位类调整位置之外,bootstrap还提供了三个类以供使用
    translate-middle  元素居中平移自身x的50%和y的50%  ==》 translateX(-50%) and translateY(-50%) 
    translate-middle-x     元素平移自身x的50%
    translate-middle-y     元素平移自身y的50%
  注意: translate-middle-x  和  translate-middle-y 不能同时对一个元素使用

元素的居中:
<div class="father position-relative">
  <div class="box position-absolute start-50 top-50 translate-middle"></div>
</div>
  • 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

color和size

color类,bootstrap预测好了一些颜色类
参考地址:https://getbootstrap.com/docs/5.3/utilities/colors/
用于设置文本颜色 text-color
用于设置背景颜色 bg-color

    color:
      可选值:
<span class="text-danger text-">hello world!</span>
<span class="text-danger bg-dark">hello world!</span> -->

<!-- size:元素的大小,宽度和高度
    参考地址: https://getbootstrap.com/docs/5.3/utilities/sizing/
    语法:
      w-{number}  相对于元素父亲的宽度
      h-{number}  相对于元素父亲的高度

      vw-{number} 相对于屏幕视口的宽度
      vh-{number} 相对于屏幕视口的高度
      注意:w和h的有效取值 25、50、75、100、auto(默认值,由内容决定高度和宽度),其值都是百分比!参考于其父元素的宽度和高度!
      注意: vw、 vh 只能设置为100,其他值不生效
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

spacing和stacks

<!-- <div class="d-flex">
  <div class="d-inline-block bg-danger mt-5 py-1" style="width: 100px; height: 100px">box1</div>
  <div class="d-inline-block bg-info ms-5" style="width: 100px; height: 100px">box2</div>
</div> -->

<!-- stacks 元素之间的间距 -->
<!-- 参考地址 https://getbootstrap.com/docs/5.3/helpers/stacks/ -->
<!-- 垂直方向 vstack 元素的间距 -->
<!-- 
    1.给父元素开启:  vstack垂直方向布局   hstack布局    父元素自动变成flex元素
    2.gap-{number}   设置父元素内各个子元素之间的间隙
    number取值范围:0-5
 -->
<!-- <div class="vstack gap-3">
  <div class="bg-body-tertiary border">First item</div>
  <div class="bg-body-tertiary border">Second item</div>
  <div class="bg-body-tertiary border">Third item</div>
</div> -->

<!-- 水平方向 hstack 元素的间距 -->
<div class="hstack gap-3">
  <div class="bg-body-tertiary border">First item</div>
  <div class="bg-body-tertiary border">Second item</div>
  <div class="bg-body-tertiary border">Third item</div>
</div>
  • 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

text

text类 用于文本相关的工具类
<!-- 文本的对齐方式 -->
<!-- 
    语法:
    text-{value}  || text-{breakpoint}-{value}
    value:
        start
        center
        end
 -->
<div class="w-50 bg-danger text-start">hello world!</div>
<div class="w-50 bg-danger text-center">hello world!</div>
<div class="w-50 bg-danger text-end">hello world!</div>

<!-- 文本换行和溢出 -->
<!-- 
    语法:
    text-{value}
    value:
        wrap
        nowrap 默认值

    overflow-{value}
        value:
            hidden
            scroll
            auto
 -->
<div class="badge bg-primary text-wrap" style="width: 6rem">This text should wrap.</div>
<div class="badge bg-primary text-nowrap text-danger" style="width: 6rem">
  This text should wrap.
</div>
<div class="badge bg-primary text-nowrap text-danger overflow-hidden" style="width: 6rem">
  This text should wrap.
</div>

<!-- 设置字体大小 -->
<!-- 
    语法:
    fs-{value}   ==》 font-size
    值越小小字体越大!
 -->
<div class="fs-1">hello world!</div>
<div class="fs-2">hello world!</div>
<div class="fs-3">hello world!</div>
<div class="fs-4">hello world!</div>
<div class="fs-5">hello world!</div>
<div class="fs-6">hello world!</div>

<!-- 设置字体的粗细 -->
<!-- 
    语法:
    fw-{value}  ==》 font-weight
 -->
<p class="fw-bold">Bold text.</p>
<p class="fw-bolder">Bolder weight text (relative to the parent element).</p>
<p class="fw-semibold">Semibold weight text.</p>
<p class="fw-normal">Normal weight text.</p>
<p class="fw-light">Light weight text.</p>
<p class="fw-lighter">Lighter weight text (relative to the parent element).</p>

<!-- 设置字体的斜体 -->
<!-- 
    语法:
    fst-{value}   
        - italic  倾斜
        - normal  默认值 字体不倾斜
 -->
<p class="fst-italic">Italic text.</p>
<p class="fst-normal">Text with normal font style</p>

<!-- 行高 -->
<!-- 
    语法:
    lh-{value}   ==> line-height 
    value: 1  sm  base  lg
 -->
<p class="lh-1">
  This is a long paragraph written to show how the line-height of an element is affected by our
  utilities. Classes are applied to the element itself or sometimes the parent element. These
  classes can be customized as needed with our utility API.
</p>
<p class="lh-sm">
  This is a long paragraph written to show how the line-height of an element is affected by our
  utilities. Classes are applied to the element itself or sometimes the parent element. These
  classes can be customized as needed with our utility API.
</p>
<p class="lh-base">
  This is a long paragraph written to show how the line-height of an element is affected by our
  utilities. Classes are applied to the element itself or sometimes the parent element. These
  classes can be customized as needed with our utility API.
</p>
<p class="lh-lg">
  This is a long paragraph written to show how the line-height of an element is affected by our
  utilities. Classes are applied to the element itself or sometimes the parent element. These
  classes can be customized as needed with our utility API.
</p>

<!-- 文本装饰线 -->
<p class="text-decoration-underline">This text has a line underneath it.</p>
<p class="text-decoration-line-through">This text has a line going through it.</p>
<a href="#" class="text-decoration-none">This link has its text decoration removed</a>

<!-- 文本截断  省略号显示 -->
<!-- Block level -->
<!-- text-truncate  -->
<div class="row">
  <div class="col-1 text-truncate">
    This text is quite long, and will be truncated once displayed.
  </div>
</div>

<!-- Inline level -->
<span class="d-inline-block text-truncate" style="max-width: 150px">
  This text is quite long, and will be truncated once displayed.

  <!-- 

    overflow : hidden;
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118

text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;

   -->
</span>
  • 1
  • 2
## form conteol
<div>
  <input type="text" name="" value="" />
  <!-- 默认大小 -->
  <input type="text" class="form-control w-25" />
  <!-- 大 -->
  <input type="text" class="form-control form-control-lg w-50" />
  <!-- 小 -->
  <input type="text" class="form-control form-control-sm w-75" />

  <textarea class="form-control" name="" id="" cols="30" rows="10"></textarea>
</div>

<!-- 文件上传 -->

<input type="file" disabled />
<input class="form-control form-control-sm" type="file" />
<input class="form-control form-control-lg" type="file" />

<!-- multiple属性 控制多个文件的上传 -->
<input class="form-control" type="file" multiple />
<input class="form-control" type="file" disabled />

<input type="color" class="form-control" name="" value="" style="width: 50px" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

单选框和多选框

  <input type="checkbox" name="" value="" />
  <!-- 垂直方向的多选框按钮 -->
  <div class="form-check">
    <input class="form-check-input" type="checkbox" value="" id="flexCheckDefault" />
    <label class="form-check-label" for="flexCheckDefault"> Default checkbox </label>
  </div>

  <div class="form-check">
    <input class="form-check-input" type="checkbox" value="" id="flexCheckChecked" checked />
    <label class="form-check-label" for="flexCheckChecked"> Checked checkbox </label>
  </div>

  <!-- 水平方向的多选框按钮 -->
  爱好:
  <div class="form-check form-check-inline">
    <input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1" />
    <label class="form-check-label" for="inlineCheckbox1">打篮球</label>
  </div>
  <div class="form-check form-check-inline">
    <input class="form-check-input" type="checkbox" id="inlineCheckbox2" value="option2" />
    <label class="form-check-label" for="inlineCheckbox2">乒乓球</label>
  </div>

  <!-- 不确定的复选框 -->
  <div class="form-check">
    <input class="form-check-input" type="checkbox" value="" id="myCheck01" />
    <label class="form-check-label" for="flexCheckIndeterminate">
      Indeterminate checkbox
    </label>
  </div>

  <!-- 背禁用的复选框按钮样式 -->
  <div class="form-check">
    <input
      class="form-check-input"
      type="checkbox"
      value=""
      id="flexCheckIndeterminateDisabled"
      disabled
    />
    <label class="form-check-label" for="flexCheckIndeterminateDisabled">
      Disabled indeterminate checkbox
    </label>
  </div>
  <div class="form-check">
    <input class="form-check-input" type="checkbox" value="" id="flexCheckDisabled" disabled />
    <label class="form-check-label" for="flexCheckDisabled"> Disabled checkbox </label>
  </div>
  <div class="form-check">
    <input
      class="form-check-input"
      type="checkbox"
      value=""
      id="flexCheckCheckedDisabled"
      checked
      disabled
    />
    <label class="form-check-label" for="flexCheckCheckedDisabled">
      Disabled checked checkbox
    </label>
  </div>

  <!-- 垂直方向的单选框 -->
  <div class="form-check">
    <input
      class="form-check-input"
      type="radio"
      name="flexRadioDefault"
      id="flexRadioDefault1"
    />
    <label class="form-check-label" for="flexRadioDefault1"> Default radio </label>
  </div>
  <div class="form-check">
    <input
      class="form-check-input"
      type="radio"
      name="flexRadioDefault"
      id="flexRadioDefault2"
      checked
    />
    <label class="form-check-label" for="flexRadioDefault2"> Default checked radio </label>
  </div>

  <!-- 水平方向的单选框 -->
  <label for="">性别:</label>
  <div class="form-check form-check-inline">
    <input
      class="form-check-input"
      type="radio"
      name="inlineRadioOptions"
      id="inlineRadio1"
      value="option1"
    />
    <label class="form-check-label" for="inlineRadio1">男</label>
  </div>
  <div class="form-check form-check-inline">
    <input
      class="form-check-input"
      type="radio"
      name="inlineRadioOptions"
      id="inlineRadio2"
      value="option2"
    />
    <label class="form-check-label" for="inlineRadio2">女</label>
  </div>
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

select

基本用法 成都 重庆 北京 上海 选择框的大小更改 大号 form-select-lg
  <select class="form-select form-select-lg mb-3" aria-label=".form-select-lg example">
    <option selected>Open this select menu</option>
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
  </select>
  </form>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

原生表单验证

<!-- 
    验证的手段有两种:
        1.html原生的表单验证 
        2.js自定义的数据验证

  input控件的验证属性:
      required  必填
      pattern   符合正则自定义表达式
      minlength maxlength  最小和最大字符长度
      min max  最小值 最大值
      type  类型  email
 -->

<form onsubmit="return false">
  <div>
    <label for=""> 姓名:<input type="text" required minlength="2" maxlength="4" /> </label>
  </div>
  <div>
    <label for="">性别:<input type="text" pattern="男|女" /></label>
  </div>

  <div>
    <label for="">年龄:<input type="number" min="0" max="150" /></label>
  </div>

  <div>
    <label for=""> 邮箱:<input type="email" /> </label>
  </div>

  <button type="submit">提交</button>
</form>
  • 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

手动验证表单

<!-- 
 input 的验证属性
    required
    pattern
    minlength maxlength
    min max
    type

novalidate属性 屏蔽html自带的验证报告

input元素 的 validity 属性
    // validity.valueMissing -> required 用户没填数据时为 true
    // validity.patternMismatch -> pattern 用户输入不满足正则 true
    // validity.rangeOverflow -> max 用户输入超过最大值 true
    // validity.rangeUnderflow -> min 用户输入小于最小值 true
    // validity.tooLong -> maxlength 用户输入超出长度 不会触发 true
    // validity.tooShort -> minlength 用户输入小于了指定长度 true
    // validity.valid -> 输入没有问题 验证通过 true fo
自定义提示信息
    input.setCustomValidity
form checkValidity() 判断表单数据是否合格
显示验证报告
    form.reportValidity()
表单验证总结步骤
    1. 给表单添加 novalidate 屏蔽自动验证报告
    2. 对每个元素的 validity 属性进行验证
    3. 根据每个元素的验证结果设置自定义异常 setCustomValidity
    4. 提交验证报告
    5. 根据验证结果执行后续网络操作


<form onsubmit="return false" novalidate>
  <div>
    <label for="">
      姓名:<input type="text" required minlength="2" maxlength="4" name="uname" />
    </label>
  </div>
  <div>
    <label for="">性别:<input type="text" pattern="男|女" name="sex" /></label>
  </div>

  <div>
    <label for="">年龄:<input type="number" min="0" max="150" name="age" /></label>
  </div>

  <div>
    <label for=""> 邮箱:<input type="email" name="email" /> </label>
  </div>

  <button type="submit">提交</button>
</form>
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

懒加载的两种方式

// 懒加载方式一:
// container.addEventListener(‘scroll’, (el) => {
// console.log()
// imgs.forEach((el) => {
// // 检测是否需要加载该图片
// // 当前元素距离父元素顶部的距离 < 父元素可视区域的高度 + 父元素滚动条滚动的距离
// if (el.offsetTop <= container.clientHeight + container.scrollTop) {
// el.src = el.getAttribute(‘data-src’)
// }
// })
// })
// 懒加载方式二:
// console.log(imgs[0].getBoundingClientRect())
// window.addEventListener(‘scroll’, () => {
// // console.log(6666, window.scroolTop)

//   // getBoundingClientRect 获取对应elment元素距离浏览器窗口各方向的坐标值,top  left  right  bottom
//   imgs.forEach((el) => {
//     if (el.getBoundingClientRect().top <= window.innerHeight) {
//       el.src = el.getAttribute('data-src')
//     }
//   })
// })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

React

react 概述

react 是什么

中文官网:https://zh-hans.reactjs.org/

react 是一个 js 核心库,如同 jquery 一样,具有大量 react 生态(围绕 react 核心开发的库)

React是一个用于构建用户界面的JavaScript库
用户界面: HTML 页面(前端) 用户的可视界面
React 主要用来写 HTML 页面(html css js),或构建Web应用

MVC 是一种设计模式 M modle 模型层负责数据的增删查改 v view 视图层 展示数据,页面 C control 控制层 核心的业务逻辑 js 代码
如果从 MVC 的角度来看, React 仅仅是视图层(V ) , 也就是只负责视图的渲染,而并非提供了
完整的 M 和 C 的功能。

react 的特点

  • 声明式
  • 基于组件
  • 学习一次,随处使用

声明式

只需要描述 UI(HTML)是什么样,React 负责渲染 UI,并在数据变化时更新 UI

const jsx = (
  <div className="app">
    <h1>React动态变化:{count}</h1>
  </div>
)
  • 1
  • 2
  • 3
  • 4
  • 5

基于组件

  • 组件是 React最重要的内容
  • 组件表示页面中的部分内容 (部分内容包括:html js css)
  • 组合、复用多个组件,可以实现完成的页面功能

学习一次,随处使用

  • 使用 React 可以开发 Web 应用
  • 使用 React 可以开发移动端原生应用( react-native )
  • 使用 React 可以开发 VR(虚拟现实)应用(react360)

jsx基础语法

// jsx基础语法
// jsx大致上是兼容了JavaScript的所有特性,但其自身也存在一些独有的语法

 // 1.如果react-dom元素需要换行防止代码错误或者歧义,则应该使用()包裹
  // let div = (
  //     <div>
  //     <span>hello </span>
  //     <div>
  //      <p>sdfsfsfsdfsdfsdfsd</p>
  //     </div>
  //   </div>
  // )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  // 2.一个react-dom元素中只允许存在一个根节点  如果存在多个根节点,则报错
  // let div01 = (
  //  <div></div>
  //  <div></div>
  // )

  // 3.插值语法-对jsx标签的内容进行插值 {}
  // let name = '康康'
  // let obj = {
  //   name: '小明',
  // }
  // let arr = [100, 200, 300]
  // let div = <div>hello! {arr[1]}</div>

  //  4.插值语法-对jsx标签的属性进行插值  引号注意去掉!
  //注意在jsx中的单标签必须要使用/进行闭合,如果不闭合会报错!
  // let mysrc = './img/haizei1.jpg'
  // // let img = <img src={mysrc} alt="" />
  // let img = <img src="./img/haizei1.jpg" alt="" />

  // 5.jsx设置标签属性
  // jsx中大部分标签的属性都与html中是一致的,除了以下
  // jsx中的所有属性都是小驼峰命名方式
  // class ==> className
  // for ==> htmlFor
  // tableindex ==> tableIndex
  // 其他的基本就没有....

  // let div = (
  //   <div className="box" title="xxxx">
  //     4564564{' '}
  //   </div>
  // )
  // let label = <label htmlFor="">姓名:</label>

  // 注意:jsx中基本上所有的标签属性都可以直接进行赋值!与html方式一致,除了style属性!
  // 6.style属性的赋值操作,必须通过{}并将要设置的css属性利用json对象的格式传入

  // let mystyle = {
  //   backgroundColor: 'red',
  //   width: '500px',
  //   height: '500px',
  // }
  // let div = <div style={mystyle}>111111111</div>

  // 7. {}插值语法中可以是任何合法的js表达式 前提是该表达式一定有返回值!
  function fun() {
    if (true) {
      return 300
    } else {
      return 500
    }
  }
  // let div = <div>{100 * 200}</div>
  // let div = <div>{100 - 200}</div>
  // let div = <div>{100 / 200}</div>
  // let div = <div>{false ? 'hello' : 'world!'}</div>
  let div = <div>{fun()}</div>

  let mydiv = (
    <div>
      <span>xxxx</span>
    </div>
  )

  const root = ReactDOM.createRoot(document.querySelector('#app'))
  root.render(mydiv)
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

组件的简介

// 组件:
// 1.react中将可以复用的,UI模板称为组件!每个组件具备其独有的功能和样式
// 2.对于react来说,组件从某种概念上来说类似于JavaScript中的函数或者类
// 3.组件可以接受参数

  // 注意:react中只有人为定义的jsx标签才能称为组件!如果是已经存在的DOM元素只是叫做元素!并不是标签
  // DOM元素是组件的最小组成单位!

  // dom元素
  const domElment = <div>hello world!</div>

  //   渲染dom元素
  const root = document.querySelector('#root')
  ReactDOM.createRoot(root).render(domElment)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

定义组件

// 函数式组件
// 组件的命名,必须遵循首字母大写的规定!
// 一个组件中只能拥有一个根节点
// 函数名就是组件的名字!

  //  组件名  FunCompoent
  // function FunCompoent() {
  //   return (
  //     <div>
  //       <h1>我是FunCompoent组件</h1>
  //       <span>备注:我的类型是函数式组件</span>
  //     </div>
  //   )
  // }

  //   类式组件
  //    注意:定义类式组件时,必须让新创建的类继承react框架中 React.Component类
  class ClassCompoent extends React.Component {
    constructor() {
      super() //如果不调用super() 那么该组件中无法使用this!
    }

    // render函数  注意该函数的名字不能自定义 必须叫  render
    render() {
      return (
        <div>
          <h1>我是ClassCompoent组件</h1>
          <span>备注:我的类型是类式组件</span>
        </div>
      )
    }
  }

  //   渲染组件统一的步骤
  //   1.获取显示组件的容器
  //   2.渲染组件
  const root = document.querySelector('#root')
  ReactDOM.createRoot(root).render(<ClassCompoent />)
  • 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

条件渲染1

// 条件渲染一: if…else
function Show1() {
let flag = false

    if (flag) {
      return <div>加载完成....</div>
    } else {
      return <div>正在加载....</div>
    }
  }

  //   条件渲染二:  条件运算符
  function Show2() {
    let flag = true
    let child01 = (
      <div>
        <h1>show1</h1>
        <span>加载完成了</span>
      </div>
    )

    let child02 = (
      <div>
        <h1>show1</h1>
        <span>为加载完成</span>
      </div>
    )

    return flag ? child01 : child02
  }

  //   条件渲染三: 短路与
  function Show3(params) {
    let flag = true
    let child01 = (
      <div>
        <h1>show3</h1>
        <span>加载完成了</span>
      </div>
    )

    let child02 = (
      <div>
        <h1>show3</h1>
        <span>为加载完成</span>
      </div>
    )

    return flag && child01
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

条件渲染2

class App extends React.Component {
// 初始化实例对象的属性值
flag = false
constructor() {
super()
}

    render() {
      if (this.flag) {
        return <div>加载完成了....</div>
      } else {
        return <div>为完成</div>
      }
    }
  }

  const root = document.querySelector('#root')
  ReactDOM.createRoot(root).render(<App />)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

条件渲染3

function Child1(params) {
    return <div>我是child1组件</div>
  }

  function Child2(params) {
    return <div>我是child2组件</div>
  }

  function App() {
    let flag = false
    return (
      // 需求:我想在App组件中使用child1和child2组件

      <div>{flag ? <Child1 /> : <Child2 />}</div>
    )
  }

  const root = document.querySelector('#root')
  ReactDOM.createRoot(root).render(<App />)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

列表渲染

function App() {
let stuInfo = [
{
name: ‘小红’,
age: 18,
sex: ‘女’,
},
{
name: ‘小兰’,
age: 20,
sex: ‘女’,
},
{
name: ‘小黄’,
age: 18,
sex: ‘男’,
},
{
name: ‘小强’,
age: 38,
sex: ‘男’,
},
]

    return (
      <div>
        <div>
          <div>姓名:{stuInfo[0].name}</div>
          <div>年龄:{stuInfo[0].age}</div>
          <div>性别:{stuInfo[0].sex}</div>
        </div>
        <div>---------------------</div>
        <div>
          <div>姓名:{stuInfo[1].name}</div>
          <div>年龄:{stuInfo[1].age}</div>
          <div>性别:{stuInfo[1].sex}</div>
        </div>
        <div>---------------------</div>
        <div>
          <div>姓名:{stuInfo[2].name}</div>
          <div>年龄:{stuInfo[2].age}</div>
          <div>性别:{stuInfo[2].sex}</div>
        </div>
        <div>---------------------</div>
        <div>
          <div>姓名:{stuInfo[3].name}</div>
          <div>年龄:{stuInfo[3].age}</div>
          <div>性别:{stuInfo[3].sex}</div>
        </div>
      </div>
    )
  }

  const root = document.querySelector('#root')
  ReactDOM.createRoot(root).render(<App />)
  • 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

列表渲染2

function App() {
let stuInfo = [
{
name: ‘小红’,
age: 18,
sex: ‘女’,
},
{
name: ‘小兰’,
age: 20,
sex: ‘女’,
},
{
name: ‘小黄’,
age: 18,
sex: ‘男’,
},
{
name: ‘小强’,
age: 38,
sex: ‘男’,
},
]

    // react中如果存在数组类型的数据,react会自动的遍历他,在jsx,当你使用 插值语法 {}

    // <div>
    //       <div>姓名:{stuInfo[2].name}</div>
    //       <div>年龄:{stuInfo[2].age}</div>
    //       <div>性别:{stuInfo[2].sex}</div>
    //     </div>

    // let arr = [100, 200, 300, 400]

    // let arr2 = [<div>100</div>, <div>200</div>, <div>300</div>]

    // let res = stuInfo.map((el, index) => {
    //   return (
    //     <div key={index}>
    //       <div>姓名:{el.name}</div>
    //       <div>年龄:{el.age}</div>
    //       <div>性别:{el.sex}</div>
    //       <div>----------------</div>
    //     </div>
    //   )
    // })

    // console.log(res)
    return (
      <div>
        {stuInfo.map((el, index) => {
          return (
            <div key={index}>
              <div>姓名:{el.name}</div>
              <div>年龄:{el.age}</div>
              <div>性别:{el.sex}</div>
              <div>----------------</div>
            </div>
          )
        })}
      </div>
    )
  }

  const root = document.querySelector('#root')
  ReactDOM.createRoot(root).render(<App />)
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

事件绑定

// 事件绑定:在react-dom元素上添加事件事件属性
// react事件绑定规范:
// 事件类型: on+事件名 采用小驼峰命名法 eg: onclick react中 onClick react框架!原生的html js 封装了一些的东西
// 事件处理函数:函数组件中嵌套定义的函数 或者 类组件中的自定义方法
// 事件源:绑定事件的元素本身
// 事件处理函数

// 函数式组件中,react-dom元素绑定事件

  function FunComponent() {
    // show函数
    function show(params) {
      console.log('react-click...')
    }
    return (
      <div>
        <h1>函数式组件</h1>

        {/*JSX的注释语法*/}
        {/*需求:绑定一个点击事件,对button元素*/}

        {/*
          1.react-dom绑定事件 通过 on+事件属性  注意:小驼峰命名规则!  vscode没有提示!不代表不存在!
          2.事件处理函数的赋值  通过  插值语法 {函数名}
          3.函数名不要加小括号!如果加上了小括号,事件处理函数会立即执行一次!并且后续不再执行!
        */}
        <button type="button" onClick={show}>
          按钮
        </button>
      </div>
    )
  }
  
  // 类式组件绑定 react-dom事件
  class ClazzComponent extends React.Component {
    // 类利用的方法,一旦交予第三方调用时,则this指向为undefined
    // 因为类中的书写规则默认遵循 严格模式!

    count = 100
    constructor() {
      super()
    }

    // demo 方法
    demo() {
      console.log('demo..')
    }

    // 事件处理函数 show方法
    // show(ev) {
    //   // ev事件处理对象
    //   console.log('clazz-react-click...')
    //   // this.demo()
    //   console.log(this.count)
    //   // console.log(ev.target)
    // }

    // 方式二:防止事件函数中的this指向为undefined
    // show = () => {
    //   console.log('clazz-react-click...')
    //   this.demo()
    //   console.log(this)
    // }
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

state

// state(状态)
// state是react中最重要的特性之一,state本质是一个对象!
// state这个对象主要负责组件中私有的数据的维护!如果state中数据通过某种手段发生了改变,则react会自动更新响应的组件内容!
// 函数式:有状态组件
function Havestate1(params) {
// 函数式组件中使用state
// 1.创建state变量,修改state变量的方法
// 解释:uesState方法是React对象提供的一个API
// useState方法接受一个参数,该参数的作用是为state赋初始值,可以是任意类型
// useState方法的返回值是一个数组,数组中有两个元素,[state,setState]
// state是状态对象
// setState是修改状态对象的方法
// 通过ES6的解构赋值,赋值给两个变量

    let [num, setNum] = React.useState(1000)
    let [student, setStudent] = React.useState({})
  • 1
  • 2

// 类式:有状态组件
class Havestate2 extends React.Component {
// 类式组件使用state
constructor() {
super()
this.state = {
count: 200,
num: 300,
data: {
a: 10,
b: 20,
},
}
}

修改 state的值
// 定义一个事件处理函数
changeCount() {
// 2.修改state对象中的数据

      // 用法一: setState(obj)
      // this.setState({
      //   count: 500,
      // })

      // 用法二:setState(setdate)
      //  setdate函数用于修改state中的数据
      // this.setState(() => {
      //   // 利用callback进行复杂的运算
      //   // return的值覆盖之前的state中的数据
      //   return {
      //     count: 5000,
      //   }
      // })

      // 用法三:
      // setState方法也是一个异步方法
      // setState(参数一 obj,callback)
      // callback 数据修改完毕后的会回调函数
      // this.setState(
      //   {
      //     count: 500,
      //   },
      //   () => {
      //     console.log(this.state)
      //   }
      // )

      // 用法四:setState(setdata,callback)
      this.setState(
        (preObj) => {
          console.log(this.state, preObj)
          // 利用callback进行复杂的运算
          // return的值覆盖之前的state中的数据
          return {
            count: 5000,
          }
        },
        () => {
          console.log('okkkkkkkk')
        }
      )

      // console.log(this.state) // 使用的还是之前的state中保存的数据!
    }
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

受控组件

// 受控组件,满足以下条件的就是称为受控组件
// 1.组件中具备表单元素
// 2.表单元素的数据通过state对象来设置
// 3.用户对表单数据的修改也会反向的影响到state中的值
// react中建议使用受控组件来获取表单的数据

ref

// 知识点
// 什么是转发?
// 转发(ref) 的作用是获取组件中的 dom 或 react-dom
// 应用场景
// 1. 在 react 项目中 若希望通过 document.querySelector 获取某个元素时,我们应该使用 ref 替代
// 2. 当需要获取某个子组件的状态或调用组件的方法的时候
// 使用方法:
// 类组件使用 React.createRef()
// 函数组件使用 React.useRef()
// 通用方法 使用箭头函数 el => { temp = el }
// React.forwardRef

组件之间的通信

// 组件之间的数据通信,本质上就是组件之间相互传递数据的过程
// 大致可分为以下几种情况:
// 1.父组件向子组件传值 , props属性
// 2.子组件向父组件传值 ,这种情况react也称为(状态提升)
// 3.兄弟组件之间传值 (所有的兄弟共同的父亲,A组件将数据传输给父组件 ,再父组件将数据传输给B组件)

父传子

  // 组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”)。
  // 父组件可以利用props向任意子组件传递参数,类似于 函数的传参操作
  function Father(params) {
    function send1() {
      setData({
        name: '李四',
        age: 20,
      })
    }

    // 创建了一个state数据
    let [data, setData] = React.useState({
      name: '张三',
      age: 18,
    })

    return (
      <div>
        <h1>组件展示列表:</h1>

        {/*利用组件的自定义属性 自定义属性的命名符合规范即可!*/}
        <Child1 name={data.name} age={data.age} />

        <Child2 name={data.name} age={data.age} />
        <button type="button" onClick={send1}>
          更改传输组件的数据
        </button>
      </div>
    )
  }

  //   函数式组件中的 props

  function Child1(props) {
    return (
      <div>
        <div>我是Child1组件中的span元素</div>
        <div>
          父组件传输的内容展示:{props.name} : {props.age}
        </div>
      </div>
    )
  }

  //   类式组件中使用props
  //   this.props

  class Child2 extends React.Component {
    constructor(props) {
      super(props)
    }

    render() {
      return (
        <div>
          <div>我是Child2组件中的span元素</div>
          <div>
            父组件传输的内容展示:{this.props.name}:{this.props.age}
          </div>
        </div>
      )
    }
  }

  const root = document.querySelector('#root')
  ReactDOM.createRoot(root).render(<Father />)
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

子传父

需要设置一个修改父组件state的方法 然后将方法传给子组件
class Parent extends React.Component {
// 初始化state对象
state = {
child1: ‘xxxx’,
child2: ‘yyyy’,
}

    // 1.设置回调函数 用于子组件更新父组件的state值
    updateState = (data, index) => {
      if (index == 1) {
        this.setState({
          child1: data,
        })
      } else {
        this.setState({
          child2: data,
        })
      }
    }

    render() {
      return (
        <div>
          <Child1 updateState={this.updateState} />
          <div>------------------------</div>
          <Child2 updateState={this.updateState} />

          <div>展示child1中的数据</div>
          <div>{this.state.child1}</div>
          <div>展示child2中的数据</div>
          <div>{this.state.child2}</div>
        </div>
      )
    }
  }

  //  子组件 Child1
  function Child1(props) {
    let input_ref = null

    let [inpValue, setInpValue] = React.useState('')

    function send() {
      // 发送数据到父组件
      console.log(input_ref.value)
      props.updateState(input_ref.value, 1)
    }

    function changeInp(ev) {
      console.log(ev.target.value)
      setInpValue(ev.target.value)

      props.updateState(inpValue, 1)
    }

    return (
      <div>
        child1组件中的input数据:
        {/*<input type="text" ref={(el) => (input_ref = el)}    />*/}
        <input type="text" value={inpValue} onInput={changeInp} />
        <button type="button" onClick={send}>
          发送state给父组件
        </button>
      </div>
    )
  }

  // 子组件 Child2
  class Child2 extends React.Component {
    constructor(props) {
      super(props)
    }

    input_ref = null

    state = {
      inpValue: '',
    }

    send = () => {
      this.props.updateState(this.input_ref.value, 2)
    }

    changeInp = (ev) => {
      this.setState(
        {
          inpValue: ev.target.value,
        },
        () => {
          this.props.updateState(this.state.inpValue, 2)
        }
      )
    }
    render() {
  
      return (
        <div>
          child2组件中的input数据:
          {/*  <input type="text" ref={(el) => (this.input_ref = el)} />*/}
          <input type="text" value={this.state.inpValue} onInput={this.changeInp} />
          <button type="button" onClick={this.send}>
            发送state给父组件
          </button>
        </div>
      )
    }
  }
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100

Context

// 什么是 context?
// context 是一对 组件,用于向后代组件提供参数
// 注意: context 的数据是只读的

  // Father ==> A ===> a1 ==> aa1

  // 应用场景
  //      在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的
  //      但此种用法对于某些类型的属性而言是极其繁琐的
  //      (例如:地区偏好,UI 主题,因为他们是全局属性,每个和ui相关组件都应该读取其值)
  //      所以:很多不同层级的组件需要访问一些同样的数据,可以考虑使用 context
  // 概念
  //      context 提供了一对组件 如下:
  //      Provider(供应商) 提供数据的组件
  //      Consumer(消费者) 消费数据的组件

  // 使用方法
  //      1. 创建 context
  //          语法:const MyContext = React.createContext(defaultValue);
  //          defaultValue 若组件找不到对应 context 时会获取默认值
  //          Mycontext 的值可以是一个对象
  //      2. 页面中将 MyContext.Provider 作为父节点使用,并传入 value 参数作为 Provider 提供的数据
  //      3. 子组件或者后代组件 接收 Provider 提供的数据
  //          3.1 类组件接收的独有方法:
  //              1. 给类名的 contextType 赋值 context 对象,例如:
  //                  MyClassComponent.contextType = MyContext
  //              2. 在组件内使用 this.context 访问 最近的Provider 提供的数据

  //          3.2 通用组件接收方法:
  //              1. 在页面中,给要使用数据的函数组件套上一个 Consumer 父组件
  //              2. 在 Consumer 内 通过工厂函数返回要接收 Provider 数据的函数组件,工厂函数接收一个 value 参数,该参数即为 Provider 提供的数据
  //              3. 函数组件通过 props 接收 value 参数
  //                  例如:
  //                  <MyContext.Consumer>
  //                      {value => <FunctionComponent theme={value}></FunctionComponent>}
  //                  </MyContext.Consumer>
  // Provider 提供一个动态可变的值
  // 绑定多个 Context
  //      官网:https://zh-hans.reactjs.org/docs/context.html#consuming-multiple-contexts
  //      重点在于利用多重嵌套的 Context.Consumer,来实现绑定多个 Context

  // Context上下文对象,该对象的本质是react所提供的一对组件
  // 其对象中的角色有:
  //   context 提供了一对组件 如下:
  //      Provider(供应商) 提供数据的组件
  //      Consumer(消费者) 消费数据的组件
  // 该对象主要是用于各组件之间数据的共享!避免数据的层层传递!减少不必要的操作!
  // 注意Context对象中的数据是只读的

  //   使用Context
  // 1.创建Context对象
  // 2.通过Provider设置其value属性的数据
  // 3.通过Consumer读取其value的数据

  //   创建Context对象

  // 1.创建Context对象
  const MyContext = React.createContext()

  // 注意:Provider,Consumer这两个东西是react提供的组件
  const { Provider, Consumer } = MyContext
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

生命周期挂载阶段

// render函数是挂载阶段,以及更新阶段都会执行
render() {
console.log(‘render…’, this.state)
return <>hello react</>
}

    // 该钩子函数只会执行一次!当组件被挂载到页面时!
    // 一般在利用该钩子函数发送一些ajax请求,或者开启定时器之类的一些准备事宜
    componentDidMount() {
      console.log('compoentDidMount...', this.state)
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

生命周期更新阶段

componentDidUpdate() {
// 重点掌握 组件更新后,应该做些什么 根据需求
// 可以将一些更新后必要触发的业务逻辑放在这个地方
console.log(‘componentDidUpdate…’)
}
}

生命周期卸载阶段

此函数将在快要卸载前进行执行
componentWillUnmount() {
// 组件将要被卸载前所执行的钩子函数
console.log(‘我快被卸载了…’)
}

Hook Effect

// Hook简介
// Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
// 简单来说就是有了Hook的存在,让函数式组件变得更加强大,更趋近于类组件!

  //   Effect(效果,影响)其实就是将componentDidMount、componentDidUpdate、componentWillUnmount三者相结合的一个方法
  //   通过Effect可以让函数式组件也成功的操作钩子函数带来的影响!
  function App() {
    let [count, setCount] = React.useState(0)

    // 使用Effect方法
    // useEffect(callback)
    // 方式一: Effect使用 直接传入一个callback
    // 需求:我想让App组件在加载完成后,立马调用执行一个函数,并且页面更新时再次调用,类似于 类组件中   componentDidMount
    // callback等价于 componentDidMount | componentDidUpdate
    // React.useEffect(() => {
    //   console.log('组件挂载时和更新时都会被调用!')
    // })

    // 方式二:Effect使用
    // 需求:我想让App组件拥有一个函数,并且该函数只会在组件挂载时调用一次,更新时不会被调用
    // useEffect(callback,[])
    // 等价于:  componentDidMount 钩子函数
    // 第二个参数是一个数组,数组是一个数据监听容器!你可以指定某些数据,发送改变时才去调用对应callback
    // 传入一个[],代表你以后更新任何数据,都不会触发更新阶段!
    // React.useEffect(() => {
    //   console.log('组件挂载时调用')
    // }, [])

    // 方式三:Effect使用
    // 需求:我想让一个组件被卸载前,调用一个函数
    // useEffect(callback,[])
    // 利用callback return一个函数 该函数就会在组件卸载前调用执行
    // 等价于:componentWillUnmount
    // React.useEffect(() => {
    //   return () => {
    //     console.log('组件卸载时调用')
    //   }
    // }, [])

    // 方式四:Effect使用
    // 需求:我想让一个组件拥有两个函数,一个在挂载时调用一次,一个在卸载前调用一次
    // 等价于:componentDidMount  和  componentWillUnmount
    // React.useEffect(() => {
    //   console.log('子组件挂载时调用')

    //   return () => {
    //     console.log('子组件卸载时调用')
    //   }
    // }, [])
  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

错误边界

// 知识点
// 什么是错误边界
// react 的错误边界类似 js 的 catch 捕获错误
// 错误边界是一个 react 组件,其内部的子组件一旦发生异常就会触发错误边界
// 注意:错误边界只能捕获子组件所发送的错误!自身错误是无法捕获的
// 应用场景
// 需要对页面异常做出更友好的提示的时候,可以使用错误边界
// 如何使用?
// 1. 错误边界需要是一个 class 组件(函数组件不能充当错误边界)
// 2. 错误边界需要声明一个 hasError 状态
// 3. 错误边界需要实现生命周期钩子函数: static getDerivedStateFromError(error) 该函数返回要修改的状态,通常是{hasError: true} ; componentDidCatch(error, errorInfo) [该函数非必要]
// 4. 错误边界的渲染函数的内容,根据 hasError 状态进行调整
// 5. 使用错误边界的时候,在错误边界的标签体中嵌入其他子组件
// 6. 子组件生命周期任何阶段发生异常,都会被错误边界捕获到,从而显示错误的提示

传送门

// 什么是传送门
// 传送门是 react 通过 ReactDOM.createPortal 方法创建的一个特殊的 react-dom
// 传送门的内容可以显示到 html 文档的任何位置 甚至是 react 根节点外面
// 应用场景
// 制作模态等脱离自身组件结构的内容
// 注意:传送门的使用必须配合无状态的函数组件
// 使用方法:
// 1. 创建一个函数组件充当传送门组件(该函数组件不能有状态)
// 2. 函数组件内使用 ReactDOM.createProtal 方法创建传送门
// ReactDOM.createPortal 函数将返回一个可以被渲染到页面的一组html元素
// 第一个参数:要传送的 react-dom
// 第二个参数:传送门的目标节点,最后元素将渲染到该节点

  //ReactDOM.createPortal(child, container)
  //第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或 fragment。
  //第二个参数(container)是一个 DOM 元素,改元素的作用是作为传送门的容器。

  //child 载入container中
  //应用场景:Portal 传送门常用于弹窗设置
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Profiler 探测器

  // 探测器是一个用于优化页面检测页面运行效率的工具,在生产环境下禁用,因为他会带来额外的开销
  // 利用Profiler可以检测各个组件的运行效率,通过检测后的结果来反向优化组件

  //   需求:检测App这个组件的运行效率
  //   1.每秒钟让App重新渲染一次!,实时的观察App组件的渲染效率

  //   检测的callback,检测性能指标的函数
  function appCallback(
    id, // 发生提交的 Profiler 树的 “id”
    phase, // "mount" (如果组件树刚加载) 或者 "update" (如果它重渲染了)之一
    actualDuration, // 本次更新 committed 花费的渲染时间
    baseDuration, // 估计不使用 memoization 的情况下渲染整棵子树需要的时间
    startTime, // 本次更新中 React 开始渲染的时间
    commitTime, // 本次更新中 React committed 的时间
    interactions // 属于本次更新的 interactions 的集合
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/110774
推荐阅读
相关标签
  

闽ICP备14008679号