JSX基础语法

news2024/12/27 15:13:21

文章目录

  • 认识JSX语法
    • JSX是什么
    • 为什么Rect选择了JSX
    • JSX书写规范
    • JSX注释编写
  • JSX的基本使用
  • JSX的事件绑定
    • this绑定问题
    • 参数传递问题
  • JSX的条件渲染
    • 常见的条件渲染方式
  • JSX的列表渲染
  • JSX的原理和本质
    • JSX的本质
    • 虚拟DOM的创建过程
  • 案例练习


认识JSX语法

// 1. 定义根组件
const element = <div>Hello World</div>

// 2. 渲染根组件
const root = ReactDOM.createRoot(document.querySelector("#root"))
root.render(element)

上述代码中element变量的声明右侧赋值的标签语法其实就是一段JSX的语法。

  • 它不是一段字符串(因为没有使用引号包裹)
  • 它看起来是一段HTML元素,但是我们能在js中直接给一个变量赋值HTML吗?其实是不可以的,如果我们将type = "text/babel" 去除掉,那么就会出现语法错误。

JSX是什么

JSX是一种JavaScript的语法扩展,也在很多地方称之为JavaScript XML,因为看起来就是一段XML语法,它用于描述我们的UI界面,并且其完成可以和JavaScript融合在一起使用,它不同于Vue中的模块语法,不需要专门学习模块语法中的一些指令(比如v-if、v-for、v-bind等)

为什么Rect选择了JSX

React认为渲染逻辑本质上与其他UI逻辑存在内在耦合。比如UI需要绑定事件(button、a原生等等)、比如UI中需要展示数据的状态、比如在某些状态发生改变时,又需要改变UI,它们之间是密不可分的,所以React没有将标记分离到不同的文件中,而是将它们组合到了一起,这个地方就是组件。

image-20231024111707288

JSX书写规范

  • JSX的顶层只能有一个根元素,所以我们很多时候会在外层包裹一个div元素(或者Fragment)
  • 为了方便阅读,我们通常在jsx的外层包裹一个小括号(),这样可以方便阅读,并且jsx可以进行换行书写
  • JSX中的标签可以是单标签,也可以是双标签(如果是单标签,必须以/>结尾)
return (
    <div>
        <div>
            <h2>{message}</h2>
        </div>
        <div>哈哈哈</div>
    </div>
)

JSX注释编写

return (
    <div>
        {/* JSX的注释写法*/}
        <h2>{message}</h2>
    </div>
)

JSX的基本使用

  1. JSX嵌入变量作为子元素

    • 情况一:当变量是Number、String、Array类型时,可以直接显示
    • 情况二:当变量是null、undefined、Boolean类型时,内容为空
      • 如果希望可以显示null、undefined、Boolean,那么需要转成字符串
      • 转换的方式有很多,比如toString方法、和空字符串拼接、String等方式
    • 情况三:Object对象类型不能作为子元素
  2. JSX嵌入表达式

    • 运算表达式
    • 三元运算符
    • 执行一个函数
  3. JSX绑定属性

    • 比如元素都会有title属性
    • 比如img元素会有src属性
    • 比如a元素会有href属性
    • 比如元素可能需要绑定class
    • 比如元素使用内联样式style

JSX的事件绑定

如果原生DOM有一个监听事件,我们可以如何操作?

  • 方式一:获取DOM元素,添加监听事件
  • 方式二:在HTML原生中,直接绑定onclick

在React中是如何操作呢?

  • React事件的命名采用小驼峰(cameClass),而不是纯小写
  • 我们需要通过{}传入一个事件处理函数,这个函数会在事件发生时被执行
<body>
  <div id="root"></div>
  <script type="text/babel">

    // 类组件
    class App extends React.Component {
      // 组件数据
      constructor() {
        super()
        this.state = {
          message: "Hello World"
        }
      }

      // 组件方法
      btnClick() {
        // 内部完成了两件事:
        // 1. 将state中的message值修改掉
        // 2. 自动重新执行render函数
        this.setState({
          message: "Hello React"
        })
      }

      // 渲染内容
      render() {
        // 简单数据
        // return <h2>Hello World</h2>

        // 复杂数据
        return (
          <div>
            <h2>{this.state.message}</h2>
            <button onClick={this.btnClick.bind(this)}>修改文本</button>
          </div>
        )
      }
      // 为什么这里要bind一下? 因为类中的方法中的this默认指向undefined, 所以要将render函数中的this给方法

    }

    // 将组件渲染到界面上
    const container = document.getElementById('root');
    const root = ReactDOM.createRoot(container);
    root.render(<App />);
  </script>
</body>

这种数据的数据是定义在当前对象的state中的,我们可以通过构造函数中的this.state={定义的数据},然后当我们数据发生变化时,我们可以调用this.setState来更新数据,并且通知React进行update操作,在进行update操作时,会重新调用render函数,并且使用最新的数据来渲染界面。

this绑定问题

上述代码还存在this绑定问题

在事件执行后,我们可能需要获取当前类的对象中相关的属性,这个时候需要用到this。

在类中直接定义一个函数,并且将这个函数绑定到元素的onClick事件上,当前这个函数的this指向是谁呢?

默认情况下是undefined,因为在正常的DOM操作中,监听点击,监听函数中的this其实是节点对象(比如说button对象),但是因为React并不是直接渲染成真实DOM,我们所编写的button只是一个语法糖,它的本质React的Element对象,那么在这里发生监听的时候,react在执行函数时并没有绑定this,默认情况下就是一个undefined。

我们在绑定的函数中,可能想要使用当前对象,比如执行this.setState函数,就必须拿到当前对象的this,我们就需要在传入函数时,给这个函数直接绑定this:

  • 方案一:bind给btnClick显式绑定this
// 写法一
<button onClick={this.btnClick.bind(this)}>修改文本</button>

// 写法二
constructor() {
  super()
  this.state = {
    message: "Hello World"
  }
  this.btnClick = this.btnClick.bind(this)
}
  • 方案二:使用ES6 class fields 语法
  • 方案三:事件监听时传入箭头函数(推荐)
<body>
  <div id="root"></div>
  <script type="text/babel">
    /*
    this的四种绑定规则:
    1. 默认绑定 独立执行 
    2. 隐式绑定 作为对象中的方法执行
    3. 显式绑定 call apply bind
    4. new绑定
    */

    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          counter: 100
        }
      }

      btn1Click() {
        console.log("btn1Click")
        this.setState({ counter: this.state.counter + 1 })
      }

      // 所有实例都会有btn2Click这个字段,将一个箭头函数赋值给btn2Click,而箭头函数没有this,就会去上层作用域中查找,找到的是当前类的作用域的this,而this正好指向当前实例
      btn2Click = () => {
        console.log("btn2Click")
        this.setState({ counter: this.state.counter + 1 })
      }

      btn3Click = () => {
        console.log("btn3Click")
        this.setState({ counter: this.state.counter + 1 })
      }

      render() {
        return (
          <div>
            <h2>当前计数:{this.state.counter}</h2>

            {/*1. this绑定方式一:bind绑定*/}
            <button onClick={this.btn1Click.bind(this)}>按钮1</button>

            {/*2. this绑定方式二:ES6 class fields*/}
            <button onClick={this.btn2Click}>按钮2</button>

            {/*3. this绑定方式三:直接传入一个箭头函数(重要)*/}
            <button onClick={() => this.btn3Click()}>按钮3</button>
            {/*怎么做的?形成一个隐式绑定,this是当前实例,btn3Click作为当前实例的方法被调用*/}
          </div>
        )
      }

    }

    const container = document.getElementById('root');
    const root = ReactDOM.createRoot(container);
    root.render(<App />);
  </script>
</body>

参数传递问题

  • 情况一:获取event对象
    • 很多时候我们需要拿到event对象来做一些事情(比如阻止默认行为)
    • 那么默认情况下,event对象有被直接传入,函数就可以获取到event对象
  • 情况二:获取更多参数
    • 有更多参数时,最好的方式就是传入一个箭头函数,主动执行的事件函数,并且传入相关的其他参数
<body>
  <div id="root"></div>
  <script type="text/babel">

    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          counter: 100
        }
      }

      btn1Click(event) {
        console.log("btn1Click", event)
      }

      btn2Click(event, name, age) {
        console.log("btn2Click", event, name, age)
      }

      render() {
        return (
          <div>
            <h2>当前计数:{this.state.counter}</h2>

            {/*1. event参数的传递 */}
            <button onClick={this.btn1Click.bind(this)}>按钮1</button>
            <button onClick={(event) => this.btn1Click(event)}>按钮1</button>

            {/*2. 额外的参数传递*/}
            <button onClick={this.btn2Click.bind(this,)}>按钮2</button>
            <button onClick={(event) => this.btn1Click(event, "zy", 18)}>按钮2</button>

          </div>
        )
      }

    }

    const container = document.getElementById('root');
    const root = ReactDOM.createRoot(container);
    root.render(<App />);
  </script>
</body>

JSX的条件渲染

某些情况下,界面的内容会根据不同的情况显示不同的内容,或者决定是否渲染某部分内容:

  • 在vue中,我们会通过指令来控制:比如v-if、v-show
  • 在React中,所有的条件判断都和普通的JavaScript代码一致

常见的条件渲染方式

  • 方式一:条件判断语句,适合逻辑较多的情况
  • 方式二:三元运算符,适合逻辑比较简单
  • 方式三:与运算符&&,适合如果条件成立,渲染某一个组件;如果条件不成立,什么内容也不渲染
<body>
  <div id="root"></div>
  <script type="text/babel">

    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          isReady: true
        }
      }

      render() {
        const { isReady } = this.state

        let showElement = null
        if (isReady) {
          showElement = <h2>准备开始比赛吧</h2>
        } else {
          showElement = <h2>请提前做好准备!</h2>
        }
        return (
          <div>
            {/*1. 方式一:根据条件给变量赋值不同的内容*/}
            <div>{showElement}</div>

            {/*2. 方式二:三元运算符*/}
            <div>{isReady ? <button>开始战斗!</button> : <h3>准备</h3>}</div>

            {/*3. 方式三:&&逻辑与运算*/}
            {/*场景:当某一个值,有可能为undefined时,使用&&进行条件判断*/}
            <div>{info && <div>{info.name + " " + info.desc}</div>}</div>
          </div >
        )
      }

    }

    const container = document.getElementById('root');
    const root = ReactDOM.createRoot(container);
    root.render(<App />);
  </script>
</body>

JSX的列表渲染

真实开发中我们会从服务器请求到大量数据,数据会以列表的形式存储:

  • 比如歌手、歌曲、排行榜列表的数据
  • 比如商品、购物车、评论列表的数据
  • 比如好友消息、动态、联系人列表数据

在React中并没有像Vue模块语法中的v-for指令,而且需要我们通过JavaScript代码的方式组织数据,转成JSX,那到底如何展示列表呢?在React中,展示列表最多的方式就是使用数组的map高阶函数。很多时候我们在展示一个数据之前,需要先对它进行一些处理:比如过滤掉一些内容:filter函数;比如截取数组中的一部分内容:slice函数。

<body>
  <div id="root"></div>
  <script type="text/babel">

    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          students: [
            { id: 1, name: "zy", score: 99 },
            { id: 2, name: "lgc", score: 88 },
            { id: 3, name: "mxy", score: 100 },
            { id: 4, name: "jack", score: 66 },
            { id: 5, name: "kobe", score: 92 },
          ]
        }
      }

      render() {
        const { students } = this.state
        return (
          <div>
            <h2>学生列表数据</h2>
            <div className="list">
              {
                //  选出成绩大于90分的人
                students.filter(item => item.score > 90).map(item => {
                  return (
                    <div className="item" key={item.id}>
                      <h2>学号:{item.id}</h2>
                      <h2>姓名:{item.name}</h2>
                      <h2>分数:{item.score}</h2>
                    </div>
                  )
                })
              }
            </div>
          </div>
        )
      }

    }

    const container = document.getElementById('root');
    const root = ReactDOM.createRoot(container);
    root.render(<App />);
  </script>
</body>

JSX的原理和本质

image-20231025111055241

JSX的本质

实际上,jsx仅仅只是React.createElement(component, props, ...children)函数的语法糖,所有的jsx最终都会被转换成React.createElement的函数调用

React.createElement需要传递三个参数:

  1. 参数一:type
    • 当前ReactElement的类型
    • 如果是标签元素,那么就使用字符串表示“div”
    • 如果是组件元素,那么就直接使用组件的名称
  2. 参数二:config
    • 所有jsx中的属性都在config中以对象的属性和值的形式存储
    • 比如传入className作为元素的class
  3. 参数三:children
    • 存放在标签中的内容,以children数组的方式进行存储
    • 如果是多个元素,React内部有对它们进行处理

image-20231025160745269

虚拟DOM的创建过程

我们通过React.createElement最终创建出来一个ReactElement对象,这个ReactElement对象是什么作用呢?React为什么要创建它呢?这是因为React利用ReactElement对象组成了一个JavaScript的对象树,JavaScript的对象树就是虚拟DOM。

如何查看ReactElement的树结构呢?我们可以将之前的就实现返回结果进行打印:

image-20231025161606611

jsx-虚拟DOM-真实DOM

image-20231025161728352

案例练习

要求:

  1. 在界面上以表格的形式,显示一些书籍的数据
  2. 在底部显示书籍的总价格
  3. 点击+或者-可以增加或减少书籍(如果为1,那么不能继续-)
  4. 点击移除按钮,可以将书籍移除(当所有书籍移除完毕时,显示:购物车为空~)

image-20231025163055858

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>购物车</title>
  <!-- 添加依赖 -->
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <!-- babel -->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

  <style>
    table {
      border-collapse: collapse;
      text-align: center;
    }

    thead {
      background-color: #f2f2f2;
    }

    td,
    th {
      padding: 10px 16px;
      border: 1px solid black;
    }
  </style>
</head>

<body>
  <div id="root"></div>

  <script src="./data.js"></script>

  <script type="text/babel">
    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          books: books
        }
      }

      format(price) {
        return "¥" + Number(price).toFixed(2);
      }

      // 方法
      increment(index) {
        const newBooks = [...this.state.books]
        newBooks[index].count += 1
        this.setState({ books: newBooks })
      }

      decrement(index) {
        const newBooks = [...this.state.books]
        newBooks[index].count -= 1
        this.setState({ books: newBooks })
      }

      removeItem(index) {
        const newBooks = [...this.state.books]
        newBooks.splice(index, 1)
        this.setState({ books: newBooks })
      }

      render() {
        const { books } = this.state

        // 计算总价
        let totalPrice = 0
        for (let i = 0; i < books.length; i++) {
          totalPrice += books[i].count * books[i].price
        }

        return (
          <div>
            <table>
              <thead>
                <tr>
                  <th>序号</th>
                  <th>书籍名称</th>
                  <th>出版日期</th>
                  <th>价格</th>
                  <th>购买数量</th>
                  <th>操作</th>
                </tr>
              </thead>

              <tbody >
                {
                  books.map((item, index) => {
                    return (
                      <tr key={item.id}>
                        <td>{item.id}</td>
                        <td>{item.name}</td>
                        <td>{item.data}</td>
                        <td>{this.format(item.price)}</td>
                        <td>
                          <button disabled={item.count <= 1} onClick={() => this.decrement(index)}>-</button>
                          {item.count}
                          <button onClick={() => this.increment(index)}>+</button>
                        </td>
                        <td><button onClick={() => this.removeItem(index)}>移除</button></td>
                      </tr>
                    )
                  })
                }
              </tbody>
            </table>
            <h1>总价格:{this.format(totalPrice)}</h1>
          </div>
        )
      }

    }

    const container = document.getElementById('root');
    const root = ReactDOM.createRoot(container);
    root.render(<App />);
  </script>
</body>

</html>
// data.js
const books = [
    {
        id: 1,
        name: '《算法导论》',
        data: '2006-9',
        price: 85.0,
        count: 1,
    },
    {
        id: 2,
        name: '《UNIX编程艺术》',
        data: '2006-9',
        price: 59.0,
        count: 1,
    },
    {
        id: 3,
        name: '《编程珠玑》',
        data: '2006-9',
        price: 39.0,
        count: 1,
    },
    {
        id: 4,
        name: '《代码大全》',
        data: '2006-9',
        price: 128.0,
        count: 1,
    },
];

container);
root.render();

```
// data.js
const books = [
    {
        id: 1,
        name: '《算法导论》',
        data: '2006-9',
        price: 85.0,
        count: 1,
    },
    {
        id: 2,
        name: '《UNIX编程艺术》',
        data: '2006-9',
        price: 59.0,
        count: 1,
    },
    {
        id: 3,
        name: '《编程珠玑》',
        data: '2006-9',
        price: 39.0,
        count: 1,
    },
    {
        id: 4,
        name: '《代码大全》',
        data: '2006-9',
        price: 128.0,
        count: 1,
    },
];

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1143956.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Truffle】一、Truffle的安装与部署

目录 一、准备安装 二、安装truffle 三、创建 Truffle 项目工程 1.为 Truffle 项目创建新目录&#xff1a; 2.下载 (“unbox”) MetaCoin box: 四、项目分析 五、测试合约 一、准备安装 安装truffle必须要提前配置Nodejs环境&#xff0c;关于Nodejs的配置&#xff0c;我在…

黑豹程序员-架构师学习路线图-百科:Lombok消除冗长的java代码

文章目录 1、为什么要使用Lombok&#xff1f;2、Lombok的工作原理3、反对声渐渐消亡4、总结4.1、什么是Lombok&#xff1f;4.2、Lombok的发展历史4.3、Lombok常见的注解 1、为什么要使用Lombok&#xff1f; 现代的java项目开发都使用分层开发&#xff0c;MVC分层已经深入人心&…

Vue组件自定义事件实现子组件给父组件传递数据

一、绑定自定义事件 &#xff08;一&#xff09;使用v-on或绑定事件 事件是绑定在组件身上的&#xff0c;当我们触发这个事件的时候&#xff0c;就会执行事件回调函数。 <组件标签 v-on:事件名"事件回调函数"/> // 或 <组件标签 事件名"事件回调函…

文心一言 VS 讯飞星火 VS chatgpt (122)-- 算法导论10.4 3题

三、用go语言&#xff0c;给定一个n结点的二叉树&#xff0c;写出一个 O(n)时间的非递归过程&#xff0c;将该树每个结点的关键字输出。可以使用一个栈作为辅助数据结构。 文心一言&#xff1a; 以下是一个使用 Go 语言编写的函数&#xff0c;该函数使用一个栈作为辅助数据结…

Web应用系统设计

Web应用设计的本质目的是为了解决软件系统的复杂性,所以我们在进行web设计时,首先要分析系统的复杂性,然后再进行设计。 1.案例 某公司在创业初期快速地开发了一个B2C的垂直电商网站,然后就迅速的投向市场进行运营。为了能够快速上线,系统设计得非常简单,选择了三层架构…

大厂面试题-Java并发编程基础篇(一)

目录 一、什么是守护线程&#xff0c;它有什么特点 二、谈谈你对AQS的理解 三、AbstractQueuedSynchronized为什么采用双向链表 四、lock和synchronized区别 五、线程池如何知道一个线程的任务已经执行完成 六、什么叫做阻塞队列的有界和无界 七、ConcurrentHashMap底层…

拓扑排序基础详解,附有练习题

介绍 拓扑排序是一种对有向无环图&#xff08;DAG&#xff09;进行排序的算法。在一个有向图中&#xff0c;如果存在一条从节点 A 到节点 B 的路径&#xff0c;那么节点 A 就依赖于节点 B。 有向无环图如下 什么是入度&#xff0c;出度&#xff1f; 入度&#xff1a;有多少个…

10款轻量型的嵌入式GUI库分享

LVGL LittlevGL是一个免费的开源图形库&#xff0c;提供了创建嵌入式GUI所需的一切&#xff0c;具有易于使用的图形元素、漂亮的视觉效果和低内存占用。 特点&#xff1a; 强大的构建模组 按钮、图表、列表、滑块、图像等 ​先进的图形 动画、反锯齿、半透明、平滑滚动 多样…

【VR开发】【Unity】【VRTK】1-无代码VRVR开发介绍

本篇开始精简讲解VRTK相关的知识。 VRTK是基于Unity的一套提供无代码VR开发的插件,这套插件开源,可商用,集合了目前可能的VR体验组件,可以让不会C#编程但想要开发VR体验的人在不写一行代码的前提下开发出心仪的VR作品。 这套组件问世后也很受欢迎,目前已经进化到了第四代…

2023阿里云双十一优惠活动「云上聚·创未来」价格和代金券领取

2023阿里云双十一优惠活动「金秋云创季」开始啦&#xff0c;10月27日到10月31日可以领满减优惠&#xff0c;到11月1日和11月11日之间可以购买云服务器等产品&#xff0c;11.12到11.30日赢最高百万上云抵扣金&#xff0c;阿里云百科aliyunbaike.com分享2023阿里云双十一优惠活动…

合成数据的好处和用途

在不断变化的数据科学和人工智能环境中&#xff0c;合成数据集的概念成为具有多种用途的强大工具。 假设您是一名数据科学家&#xff0c;并分配了为电子商务网站创建尖端推荐系统的任务。为此&#xff0c;您需要大量的用户交互数据。但是&#xff0c;您面临着保护用户隐私和处…

基本微信小程序的外卖点餐订餐平台

项目介绍 餐饮行业是一个传统的行业。根据当前发展现状&#xff0c;网络信息时代的全面普及&#xff0c;餐饮行业也在发生着变化&#xff0c;单就点餐这一方面&#xff0c;利用手机点单正在逐步进入人们的生活。传统的点餐方式&#xff0c;不仅会耗费大量的人力、时间&#xf…

世界前沿技术发展报告2023《世界航空技术发展报告》(三)民用飞机技术

&#xff08;三&#xff09;民用飞机技术 1.干线飞机1.1 中国C919客机获得型号合格证并交付使用1.2 空客公司A321XLR超远程型窄体客机完成首飞1.3 NASA持续开展下一代民机技术研究1.4 欧洲开展“超高性能机翼”演示验证项目 2.支线飞机2.1 德国航宇中心完成“电动飞机概念及技术…

世界前沿技术发展报告2023《世界航空技术发展报告》(四)无人机技术

&#xff08;四&#xff09;无人机技术 1.无人作战飞机1.1 美国空军披露可与下一代战斗机编组作战的协同式无人作战飞机项目1.2 俄罗斯无人作战飞机取得重要进展 2.支援保障无人机2.1 欧洲无人机项目通过首个里程碑2.2 美国海军继续开展MQ-25无人加油机测试工作 3.微小型无人机…

Python+pytest+request 接口自动化测试!

一、环境配置 1.安装python3 brew update brew install pyenv 然后在 .bash_profile 文件中添加 eval “$(pyenv init -)” pyenv install 3.5.3 -v pyenv rehash 安装完成后&#xff0c;更新数据库 pyenv versions 查看目前系统已安装的 Python 版本 pyenv global 3.5…

C#WinformListView实现缺陷图片浏览器

C#&Winform&ListView实现缺陷图片浏览器 功能需求图像浏览行间距调整悬浮提示 功能需求 机器视觉检测系统中特别是缺陷检测系统&#xff0c;通常需要进行对已经检出的缺陷图片进行浏览查阅。主要是通过条件筛选查询出所需要的数据&#xff0c;进行分页再展示到界面中。…

基于SpringBoot的垃圾分类管理系统

基于SpringBootVue的垃圾分类管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven主要功能&#xff1a;包括前台和后台两部分、首页列表展示、垃圾分类、垃圾图谱、查看详…

当线性规划与算法相遇:揭秘单纯形法(Simplex)的独特魅力

传统的解决线性规划问题的方法是图形法、代数法求解&#xff0c;但是图形法解题有极大的局限性&#xff0c;因为一旦变量超过3个&#xff0c;基本上就无法通过图形解决&#xff0c;而代数法虽然可以解题&#xff0c;但对于复杂的问题可能效果较差甚至无法求解&#xff01; 相比…

嵌入式PID算法理论+实践分析

1.1 概述 比例&#xff08;Proportion&#xff09;积分&#xff08;Integral&#xff09;微分&#xff08;Differential&#xff09;控制器&#xff08;PID控制器或三项控制器&#xff09;是一种采用反馈的控制回路机制&#xff0c;广泛应用于工业控制系统和需要连续调制控制的…

LangChain+LLM实战---LangChain概述

LangChain介绍 LangChain是个开源的框架&#xff0c;它可以让AI开发人员把像GPT-4这样的大型语言模型(LLM)和外部数据结合起来。可以简单认为LangChain是LLM领域的Spring&#xff0c;以及开源版的ChatGPT插件系统。 LangChain的强大之处不仅能通过API调用语言模型&#xff0c;…