第三十七章 扩展知识点

news2024/11/28 8:51:54

1、setState

(1). setState(stateChange, [callback])------对象式的setState
            1.stateChange为状态改变对象(该对象可以体现出状态的更改)
            2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用
					
	(2). setState(updater, [callback])------函数式的setState
            1.updater为返回stateChange对象的函数。
            2.updater可以接收到state和props。
            4.callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。
总结:
		1.对象式的setState是函数式的setState的简写方式(语法糖)
		2.使用原则:
				(1).如果新状态不依赖于原状态 ===> 使用对象方式
				(2).如果新状态依赖于原状态 ===> 使用函数方式
				(3).如果需要在setState()执行后获取最新的状态数据, 
					要在第二个callback函数中读取

写法一:对象式

import React, { Component } from 'react'

export default class Demo extends Component {
  state = {count:0}

  addCount = () => {
    // 获取原来的状态值
    const {count} = this.state
    // 更新状态值
    this.setState({count:count + 1},()=>{
      console.log('callback里面的状态',this.state.count)
    })
    // 监测查看状态值
    console.log('callback外面的状态',this.state.count)
  }
  render() {
    return (
      <div>
        <h1>当前求和为:{this.state.count}</h1>
        <button onClick={this.addCount}>点我+1</button>
      </div>
    )
  }
}

以上代码,就是一个简单的数字相加的功能,当我点击按钮【点我+1】的时候,状态值自增1。但是这里我们需要关注的是查看调用setState()方法后,在其callback内部与外部打印的状态值是否一样。

在这里插入图片描述

这里我们看到更新后打印的状态值是不一样的,在调用setState方法后,组件的状态并不会立即改变,而是在下一次渲染时才会更新。如果你在setState方法调用后立即打印组件的状态,你会发现它并没有发生变化。这是因为setState方法只是向React内部发出了一个更新组件状态的请求,而实际的更新过程是在下一次渲染时才会进行的。如果你需要及时获取组件的最新状态,你可以在组件的shouldComponentUpdate方法中进行判断,并在需要的时候调用setState方法进行更新。

写法二:函数式

import React, { Component } from 'react'

export default class Demo extends Component {
  state = {count:0}

  addCount = () => {
    // 获取原来的状态值
    const {count} = this.state
    // 更新状态值
    this.setState((state,props)=>({count:count + 1}),()=>{
      console.log('callback里面的状态',this.state.count)
    })
    // 监测查看状态值
    console.log('callback外面的状态',this.state.count)
  }
  render() {
    return (
      <div>
        <h1>当前求和为:{this.state.count}</h1>
        <button onClick={this.addCount}>点我+1</button>
      </div>
    )
  }
}

函数式就是第一个参数传递的是一个函数,它可以接收两个参数(state,props),返回值是一个状态对象。


2、LazyLoad

路由组件的懒加载

//1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包
	const Login = lazy(()=>import('@/pages/Login'))
	
//2.通过<Suspense>指定在加载得到路由打包文件前显示一个自定义loading界面
	<Suspense fallback={<h1>loading.....</h1>}>
        <Switch>
            <Route path="/xxx" component={Xxxx}/>
            <Redirect to="/login"/>
        </Switch>
    </Suspense>

案例代码

import React, { Component, lazy, Suspense } from 'react'

import { NavLink, Route, Routes } from 'react-router-dom'

const Home = lazy(() => import('./Home'))
const About = lazy(() => import('./About'))

export default class Demo extends Component {
  render() {
    return (
      <div>
        <div className="row">
          <div className="col-xs-offset-2 col-xs-8">
            <div className="page-header">
              <h2>React Router Demo</h2>
            </div>
          </div>
        </div>
        <div className="row">
          <div className="col-xs-2 col-xs-offset-2">
            <div className="list-group">
              <NavLink className="list-group-item" to="/home">
                Home
              </NavLink>
              <NavLink className="list-group-item" to="/about">
                About
              </NavLink>
            </div>
          </div>
          <div className="col-xs-6">
            <div className="panel">
              <div className="panel-body">
                <Suspense fallback={<h1>Loading...</h1>}>
                  <Routes>
                    <Route path="/home" element={<Home />} />
                    <Route path="/about" element={<About />} />
                  </Routes>
                </Suspense>
              </div>
            </div>
          </div>
        </div>
      </div>
    )
  }
}

这里懒加载引入组件,必须配合Suspense使用,不然会报错。

在这里插入图片描述

原来普通引入的组件,加载页面的时候会把所有组件一次性加载完,现在使用懒加载后,当你用到该组件的时候才会去动态引入。

这种做法有以下几个好处:

  1. 提高网页加载速度:如果网页中的图片、CSSJavaScript等资源都是懒加载的,那么当用户第一次访问网页时,只会加载必要的资源,而不是全部资源。这样就可以大大减少页面加载时间,提高用户体验。
  2. 减少页面内存占用:如果网页中的资源全部都是懒加载的,那么在页面加载时就不会一次性加载完所有资源,这样就可以避免内存不足的问题。
  3. 提高网站安全性:懒加载可以减少网站被黑客攻击的风险。因为懒加载可以避免在页面加载时全部资源都加载到浏览器缓存中,这样就可以避免攻击者利用缓存中的资源来攻击网站。
  4. 方便后续维护:如果网页中的资源是懒加载的,那么在后续维护时就可以更方便地修改或删除资源。这样可以减少对网站的影响,提高维护效率。

3、State Hook ===> React.useState()

(1). State Hook让函数组件也可以有state状态, 并进行状态数据的读写操作
(2). 语法: const [xxx, setXxx] = React.useState(initValue)  
(3). useState()说明:
        参数: 第一次初始化指定的值在内部作缓存
        返回值: 包含2个元素的数组, 第1个为内部当前状态值, 第2个为更新状态值的函数
(4). setXxx()2种写法:
        setXxx(newValue): 参数为非函数值, 直接指定新的状态值, 内部用其覆盖原来的状态值
        setXxx(value => newValue): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值

案例代码:

import React from 'react'

export default function Demo () {
  
  const [count,setCount] = React.useState(0)

  function addCount() {
    setCount(count + 1)
  }

  return (
    <div>
      <h1>当前求和为:{count}</h1>
      <button onClick={addCount}>点我+1</button>
    </div>
  )

同样是一个点击加1的功能组件,只不过由类式组件改成了函数式组件。

关键代码:

const [count,setCount] = React.useState(0)
  • count: 内部当前的状态值
  • setCount: 操作该状态的方法

其中setCount有两种写法:

  • setCount( count + 1), 参数直接是一个值
  • setCount( oldCount => oldCount + 1),参数是一个函数,内部可以介绍旧的状态,返回一个新的状态

4、Effect Hook ===> React.useEffect()

(1). Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
(2). React中的副作用操作:
        发ajax请求数据获取
        设置订阅 / 启动定时器
        手动更改真实DOM
(3). 语法和说明: 
        useEffect(() => { 
          // 在此可以执行任何带副作用操作
          return () => { // 在组件卸载前执行
            // 在此做一些收尾工作, 比如清除定时器/取消订阅等
          }
        }, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行
    
(4). 可以把 useEffect Hook 看做如下三个函数的组合
        componentDidMount()
        componentDidUpdate()
    	componentWillUnmount() 

案例代码:

import React from 'react'
import root from '../../index'

export default function Demo () {
  
  const [count,setCount] = React.useState(0)

  React.useEffect(()=>{

    let timer = setInterval(() => {
      console.log('@@@')
      setCount( count + 1)
    }, 1000);

    return () => {
      clearInterval(timer)
    }
  })

  function addCount() {
    setCount(count + 1)
  }

  function unmount () {
    root.unmount()
  }

  return (
    <div>
      <h1>当前求和为:{count}</h1>
      <button onClick={addCount}>点我+1</button>
      <button onClick={unmount}>点击卸载组件</button>
    </div>
  )
}

以上代码,打开页面就会每隔1秒自增1,新增卸载组件功能。

关键代码1:

import root from '../../index'
//-----------------------------
  function unmount () {
    root.unmount()
  }

react18.x版本中,卸载组件需要使用root.unmount()

关键代码2:

React.useEffect(()=>{

    let timer = setInterval(() => {
      console.log('@@@')
      setCount( count + 1)
    }, 1000);

    return () => {
      clearInterval(timer)
    }
  })

在副作用函数中,开启了一个定时器,在返回的函数中清除了定时器。

使用useEffect模拟componentDidMount

import React, { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    // 在这里执行您的副作用操作,例如 API 调用等
    console.log('componentDidMount');

    // 如果需要在组件卸载时执行清理操作,请返回一个函数
    return () => {
      console.log('componentWillUnmount');
    };
  }, []); // 空数组表示没有依赖项,因此副作用函数仅在组件挂载时运行

  return <div>MyComponent</div>;
}

要在函数组件中模拟 componentDidMount,您可以使用 useEffect 并传递一个空数组 [] 作为依赖项。这将确保副作用函数仅在组件挂载时运行一次。

使用useEffect模拟componentDidUpdate

import React, { useEffect } from 'react';

function MyComponent({ someProp }) {
  useEffect(() => {
    // 在这里执行您的副作用操作,例如根据 prop 更改更新数据等
    console.log('componentDidUpdate');

    // 如果需要在组件卸载时执行清理操作,请返回一个函数
    return () => {
      console.log('componentWillUnmount');
    };
  }, [someProp]); // 将需要观察的变量添加到依赖项数组中

  return <div>MyComponent</div>;
}

要模拟 componentDidUpdate,您可以使用 useEffect,并将需要观察的变量添加到依赖项数组中。这将确保副作用函数在依赖项更改时运行。

使用useEffect模拟componentWillUnmount

React.useEffect(()=>{
    // 开启一个定时器
	let timer = setInterval(()=>{
		console.log('开启副作用')
    },1000)
    
    // 这里return的函数,可以当做componentWillUnmount,在这里清除副作用
    return () => {
      clearInterval(timer)
      console.log('清除副作用')
    }
    
},[])

要模拟 componentWillUnmount,您可以在 useEffect 的副作用函数中返回一个函数。这个返回的函数将在组件卸载时执行。


5、Ref Hook ===> React.useRef()

(1). Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据
(2). 语法: const refContainer = useRef()
(3). 作用:保存标签对象,功能与React.createRef()一样

React 中,useRef 是一个非常有用的 Hook,它可以帮助您在函数组件中创建和访问可变的引用。useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传递的参数(默认为 null)。这个ref对象在组件的整个生命周期内保持不变。

以下是如何在 React 中使用 useRef

创建一个 ref

import React, { useRef } from 'react';

function MyComponent() {
  const myRef = useRef(null);

  // ...
}

使用 ref

您可以使用创建的 ref 来引用 DOM 元素或其他 React 组件。要将 ref 附加到 DOM 元素,只需将 ref 传递给元素的 ref 属性。

import React, { useRef } from 'react';

function MyComponent() {
  const myRef = useRef(null);

  return (
    <div>
      <input ref={myRef} />
    </div>
  );
}

现在,myRef.current 将指向输入元素。

访问 ref 的值

要访问 ref 的值,您可以使用 .current 属性。例如,您可以在事件处理程序中访问输入元素的值。

import React, { useRef } from 'react';

function MyComponent() {
  const myRef = useRef(null);

  const handleClick = () => {
    console.log('Input value:', myRef.current.value);
  };

  return (
    <div>
      <input ref={myRef} />
      <button onClick={handleClick}>Log input value</button>
    </div>
  );
}

在这个示例中,当用户点击按钮时,输入元素的值将被记录到控制台。

通过这些示例,您可以了解如何在 React 中使用 useRef。请注意,useRef 不仅可以用于访问 DOM 元素,还可以用于存储任何可变值,而不会触发组件重新渲染 。


6、Fragment 和空标签(<> 和 </>)

React 中,Fragment 和空标签(<></>)都用于组合多个子元素,而不需要添加额外的 DOM 元素。这在避免不必要的 DOM 层次结构和提高性能方面非常有用。

使用 Fragment

要使用 Fragment,您需要从 react 包中导入它,然后将它作为包裹元素。以下是一个示例:

import React, { Fragment } from 'react';

function MyComponent() {
  return (
    <Fragment>
      <div>Element 1</div>
      <div>Element 2</div>
    </Fragment>
  );
}

在这个示例中,Element 1Element 2 将作为同级元素渲染,而不需要额外的包裹元素。

使用空标签

空标签(<></>)是 Fragment 的简写语法。它们的功能与 Fragment 相同,但更简洁。以下是一个使用空标签的示例:

import React from 'react';

function MyComponent() {
  return (
    <>
      <div>Element 1</div>
      <div>Element 2</div>
    </>
  );
}

在这个示例中,Element 1Element 2 也将作为同级元素渲染,而不需要额外的包裹元素。

请注意,虽然空标签更简洁,但它们不支持添加 key 属性。如果您需要在迭代中使用 Fragment 并添加 key 属性,您应该使用完整的 <Fragment> 标签。


7、Context

React 中,Context 是一种在组件树中传递数据的方法,而无需通过每个中间组件显式传递 props。这在处理跨越多个层次的全局数据(如主题、语言设置或用户信息)时非常有用。

(1)、创建 Context

首先,您需要创建一个 Context。通常,您会在应用程序的顶层创建一个 Context

import React from 'react';

const MyContext = React.createContext();

export default MyContext

(2)、使用Provider传递Context值

要在组件树中提供 Context 值,您需要使用 Provider 组件。Provider 接受一个 value 属性,该属性将作为 Context 的值传递给所有使用该 Context 的子组件。

import React, { Component } from 'react'
import B from './B'
import MyContext from './MyContext'

const {Provider} = MyContext

export default class Demo extends Component {
  render() {
    return (
      <div>
        <Provider value={{username:'tom',age:18}}>
          <B/>
        </Provider>
      </div>
    )
  }
}

(3)、在类式组件中使用static contextType接收Context值

在类组件中访问 Context 的方法是使用 static contextType。将 contextType 设置为您要访问的 Context,然后在组件中,您可以通过 this.context 访问 Context 的值。

import React, { Component } from 'react'
import MyContext from '../MyContext'
import C from '../C'
import D from '../D'

export default class B extends Component {
  static contextType = MyContext
  render() {
    console.log('我是B组件接收的context',this.context)
    return (
      <div>
        <h2>我是B组件{this.context.username+','+this.context.age}</h2>
        <C/>
        <D/>
      </div>
    )
  }
}

(4)、使用Customer在函数组件和类组件中接收Context值

在类组件和函数组件中,您可以使用 Context.Consumer 组件来访问 Context 值。Context.Consumer 接受一个函数作为子元素,该函数接收 Context 的值作为参数。

import MyContext from "../MyContext"
const {Consumer} = MyContext
export default function C () {
  return (
    <div>
      <Consumer>
        {value => {
          console.log('我是C组件接收的Context',value)
          return <h3>我是C组件{value.username+''+value.age}</h3>
        }}
      </Consumer>
    </div>
  )
}

(5)、使用useContext Hook在函数组件中接收Context值

要在组件中使用 Context 值,您可以使用 useContext HookuseContext 接受一个 Context 对象,并返回该 Context 的当前值。

import { useContext } from 'react'
import MyContext from '../MyContext'

export default function D () {
  const contextValue = useContext(MyContext)

  console.log('我是D组件接收的context',contextValue)
  return (
    <div>
      <h3>我是D组件</h3>
      <div>{contextValue.username+','+contextValue.age}</div>
    </div>
  )
}

请注意,虽然 Context 可以简化跨多个层次的数据传递,但在不需要的情况下过度使用 Context 可能会导致组件之间的不必要的耦合。因此,建议仅在确实需要全局数据时使用 Context ,在应用开发中一般不用Context, 一般都用它的封装react插件


8、组件优化

Component的2个问题

  1. 只要执行setState(),即使不改变状态数据, 组件也会重新render() ==> 效率低

  2. 只当前组件重新render(), 就会自动重新render子组件,纵使子组件没有用到父组件的任何数据 ==> 效率低

效率高的做法

只有当组件的state或props数据发生改变时才重新render()

原因

Component中的shouldComponentUpdate()总是返回true

解决

办法1: 
	重写shouldComponentUpdate()方法
	比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false
办法2:  
	使用PureComponent
	PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
	注意: 
		只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false  
		不要直接修改state数据, 而是要产生新数据
项目中一般使用PureComponent来优化

如何理解pureComponent

我们首先需要了解React组件的基本概念。在React中,有两种类型的组件:函数组件和类组件。PureComponent是类组件的一种特殊类型,它可以帮助我们优化性能。

PureComponentReact提供的一个基类,它继承自React.Component。与普通的Component不同,PureComponent实现了一个浅比较(shallow comparison)的shouldComponentUpdate方法。这意味着,当组件的propsstate发生变化时,PureComponent会对新旧propsstate进行浅比较,如果它们相等,那么组件就不会重新渲染。这可以避免不必要的渲染,从而提高性能。

要使用PureComponent,只需将组件的基类从React.Component更改为React.PureComponent。例如:

import React from 'react';

class MyComponent extends React.PureComponent {
  // ...
}

需要注意的是,PureComponent的浅比较可能会导致一些问题。例如,当组件的propsstate包含嵌套对象时,浅比较可能无法检测到嵌套对象的变化。因此,在使用PureComponent时,需要确保组件的propsstate是不可变的(immutable)。

总之,PureComponent是一种特殊的React类组件,它通过实现浅比较的shouldComponentUpdate方法来避免不必要的渲染,从而提高性能。在使用PureComponent时,需要确保组件的propsstate是不可变的

使用shouldComponentUpdate进行自定义优化

如果PureComponentReact.memo的浅比较不足以满足需求,可以在类组件中实现自定义的shouldComponentUpdate方法。这允许您根据特定条件决定组件是否应该重新渲染。例如:

  class MyComponent extends React.Component {
    shouldComponentUpdate(nextProps, nextState) {
      // 自定义比较逻辑
      return nextProps.someProp !== this.props.someProp;
    }
    // ...
  }

React.memoReact库中的一个高阶组件(Higher-Order Component,简称HOC),它用于优化函数组件的性能。React.memo的作用类似于类组件中的PureComponent,它通过对组件的props进行浅比较(shallow comparison)来避免不必要的重新渲染。

当使用React.memo包装一个函数组件时,只有当组件的props发生变化时,组件才会重新渲染。这可以帮助我们减少不必要的渲染,从而提高性能。例如:

import React from 'react';

const MyComponent = React.memo(function MyComponent(props) {
  // ...
});

需要注意的是,React.memo的浅比较可能会导致一些问题。例如,当组件的props包含嵌套对象时,浅比较可能无法检测到嵌套对象的变化


9、render props

如何向组件内部动态传入带内容的结构(标签)?

Vue中: 
	使用slot技术, 也就是通过组件标签体传入结构  <A><B/></A>
React中:
	使用children props: 通过组件标签体传入结构
	使用render props: 通过组件标签属性传入结构,而且可以携带数据,一般用render函数属性

children props

<A>
  <B>xxxx</B>
</A>
{this.props.children}
问题: 如果B组件需要A组件内的数据, ==> 做不到 

标签体是一种React模式,它允许您将一个或多个React元素作为组件的子元素传递,并在组件中渲染这些元素。这些子元素可以是任何有效的React元素,包括其他组件。例如:

function MyComponent(props) {
  return (
    <div>
      {props.children}
    </div>
  );
}

function App() {
  return (
    <MyComponent>
      <div>Child 1</div>
      <div>Child 2</div>
    </MyComponent>
  );
}

在这个例子中,MyComponent接受一个名为childrenprop,该prop是一个React元素或一组React元素。在MyComponent中,我们使用props.children来渲染这些子元素。在App组件中,我们将两个<div>元素作为MyComponent的子元素传递。这些元素将被渲染为MyComponent的子元素。

render props

<A render={(data) => <C data={data}></C>}></A>
A组件: {this.props.render(内部state数据)}
C组件: 读取A组件传入的数据显示 {this.props.data} 

render props是另一种React模式,它允许您将一个函数作为prop传递给组件,并在组件中调用该函数以渲染子元素。这个函数通常称为renderchildren。例如:

function MyComponent(props) {
  const { render } = props;
  const data = { /* some data */ };
  return (
    <div>
      {render(data)}
    </div>
  );
}

function App() {
  return (
    <MyComponent
      render={(data) => (
        <div>
          {/* render something based on the data */}
        </div>
      )}
    />
  );
}

在这个例子中,MyComponent接受一个名为renderprop,该prop是一个函数。在MyComponent中,我们调用render函数并将数据作为参数传递。render函数返回一个React元素,该元素用于渲染MyComponent的子元素。

总之,标签体和render props是两种不同的React模式,它们的作用和用法也有所不同。标签体用于将React元素作为组件的子元素传递,而render props用于将函数作为prop传递,并在组件中调用该函数以渲染子元素。这两种模式都可以用于实现组件的可重用性和灵活性


10、 错误边界

理解:

错误边界(Error boundary):用来捕获后代组件错误,渲染出备用页面

特点:

只能捕获后代组件生命周期产生的错误,不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误

使用方式:getDerivedStateFromError配合componentDidCatch
// 生命周期函数,一旦后台组件报错,就会触发
static getDerivedStateFromError(error) {
    console.log(error);
    // 在render之前触发
    // 返回新的state
    return {
        hasError: true,
    };
}

componentDidCatch(error, info) {
    // 统计页面的错误。发送请求发送到后台去
    console.log(error, info);
}

对于React应用程序中的错误处理,可以使用错误边界来捕获和处理组件中的错误。错误边界是一种React组件,它可以捕获其子组件中的错误,并显示备用UI而不是崩溃的UI。以下是一个简单的错误边界组件的示例:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    console.error(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>服务器异常,请稍后在试.</h1>;
    }

    return this.props.children; 
  }
}

在这个例子中,ErrorBoundary是一个错误边界组件。它通过getDerivedStateFromErrorcomponentDidCatch方法来捕获子组件中的错误,并在发生错误时显示备用UIgetDerivedStateFromError方法返回一个对象,该对象将更新组件的状态以显示备用UIcomponentDidCatch方法可以用于记录错误或将错误发送到错误报告服务。

要使用错误边界,只需将其包装在可能会发生错误的组件周围即可。例如:

<ErrorBoundary>
  <MyComponent />
</ErrorBoundary>

在这个例子中,MyComponent是可能会发生错误的组件。通过将MyComponent包装在ErrorBoundary中,我们可以捕获并处理MyComponent中的错误。

案例:我们在render里面写一段错误代码,render属于生命周期

import React, { Component } from 'react'

export default class Demo extends Component {
  state = {users:'users'}

  render() {
    return (
      <div>
        我是Demo组件
        {
          this.state.users.map((user)=>{
            return <h1>{user.name}</h1>
          })
        }
      </div>
    )
  }
}

查看效果:

在这里插入图片描述


11、组件通信方式总结

组件间的关系:

  • 父子组件
  • 兄弟组件(非嵌套组件)
  • 祖孙组件(跨级组件)

几种通信方式:

	1.props:
		(1).children props
		(2).render props
	2.消息订阅-发布:
		pubs-sub、event等等
	3.集中式管理:
		redux、dva等等
	4.conText:
		生产者-消费者模式

比较好的搭配方式:

	父子组件:props
	兄弟组件:消息订阅-发布、集中式管理
	祖孙组件(跨级组件):消息订阅-发布、集中式管理、conText(开发用的少,封装插件用的多)

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

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

相关文章

敏捷专题:新一代的汽车软件研发

过去&#xff0c;买车属于一锤子买卖&#xff0c;但近年来智能制造、新能源汽车等概念的狂飙突进下&#xff0c;个性化、定制化、智能化的新车型正倍速来到消费者面前&#xff0c;不到20万元就能买到各大车企搭载了智能座舱和智能驾驶功能的产品。 ▲智能座舱 众所周知&#xf…

(一)微服务中间键工作原理——nacos客户端服务注册原理说明及源码解读

前言 本节内容我们主要介绍一下中间键nacos的客户端服务注册原理及其源码解读&#xff0c;便于我们理解nacos作为服务注册中心的具体实现。在springcloud的微服务体系中&#xff0c;nacos客户端的注册是通过使用spring的监听机制ApplicationListener实现的。学习本节内容&…

golang常见导致panic的场景

1、越界 常见有数组越界和字符串越界 2、空指针引用 直接引用空指针结构体的字段会引发panic&#xff0c;但调用成员方法里如果没引用结构体的字段不会引发panic 3、断言失败 4、map操作错误 map未初始化&#xff0c;可读不可写。 map的value如果是结构体指针&#xf…

G0第21章 :gin框架介绍、RESTful API、Gin渲染

G0第21章 &#xff1a;gin框架 01 内容介绍 web本质 Web是基于HTTP协议进行交互的应用网络Web就是通过使用浏览器/APP访问的各种资源 package mainimport ("fmt""net/http" )func sayHello(w http.ResponseWriter, r *http.Request){_, _ fmt.Fprintln(…

MKS SERVO4257D 闭环步进电机_系列1 产品简介

第1部分 产品概述 1.1 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口&#xff0c;RS485接口和CAN接口&#xff0c;内置高效FOC矢量算法&#xff0c;采用高精度编码器&#xff0c;通过位置反馈&#xff0c;有…

《深入理解计算机系统》读书笔记1.1-1.5

1.1信息就是位上下文 只由ASCLL字符构成的文件称为文本文件&#xff0c;所有其他文件都称为二进制文件。 系统中的所有的信息都由一串比特表示。区分不同数据对象的唯一方法是读到这些数据对象时的上下文。 1.2程序被其他程序翻译成不同的格式 预编译&#xff0c;编译&#xf…

EasyCVR视频融合平台设备分组共享功能的使用介绍

EasyCVR视频融合平台基于云边端一体化架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;平台支持海量视频汇聚管理&#xff0c;可支持多协议、多类型的设备接入&#xff0c;并能对设备进行分级、分组管理&#xff0c;并支持权限、角色分配&#xff0c;属于功能全…

PFC落石模拟

Landslide/Rockfall simulation 山体滑坡/落石模拟 https://www.youtube.com/watch?vWSa3909qYmI 模拟的目的在于通过导入团块的对象文件产生团块的二进制输出。 具体措施&#xff1a; (i) 使用导入的几何体形成团块模板 (ii) 使用Taghavi(2011)定义的BubblePack算法来生成卵石…

算法|4.归并排序及应用

算法|4.归并排序及应用 1.归并排序算法 题意&#xff1a;归并排序的递归和非递归实现 解题思路&#xff1a; ​ 递归实现&#xff1a; 预处理&#xff1a;数组为空或者长度小于2的直接返回调用子过程子过程终止条件LR分解成[L,mid]&#xff0c;[mid1,R] &#xff0c;子数组…

九章云极DataCanvas公司诚邀您共享AI基础软件前沿技术盛宴

“杭州通用人工智能论坛暨AIIA人工智能产业发展大会”将于2023年5月30日-31日在杭州举办。本次人工智能产业发展大会由中国信息通信研究院、中国人工智能产业发展联盟主办&#xff0c;杭州城西科创大走廊管委会、杭州市经济和信息化局、杭州未来科技城管理委员会、人工智能关键…

企业级信息系统开发——初探JdbcTemplate操作

文章目录 一、创建数据库与表1、创建数据库2、创建用户表3、用户表添加记录 二、打开Spring项目三、添加数据库相关依赖四、创建用户实体类五、创建用户数据访问接口六、创建用户数据访问接口实现类七、创建用户服务类八、创建数据库配置属性文件九、创建Spring配置文件十、创建…

Springboot +spring security,解决跨域问题

一.简介 这篇文章主要是解释什么是跨域&#xff0c;在Spring中如何解决跨域&#xff0c;引入Spring Security后Spring解决跨域的方式失效&#xff0c;Spring Security 如何解决跨域的问题。 二.什么是跨域 跨域的概率&#xff1a; 浏览器不能执行其他网站的脚本&#xff0c…

jsp页面调试

现象: 访问jsp页面, 页面为空, 网络请求显示失败, 控制台打印错误net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 分析: 错误描述&#xff1a;编码模块不完整&#xff0c;返回浏览器的流不完整 可能得原因: 1、网络是否稳定 2、服务器端是否有对响应数据做限制&#xff0c;比如…

【App自动化测试】(十七)遍历测试工具——Android Maxim

目录 1. Android Maxim介绍2. Android Maxim使用方法3.Android Maxim运行命令4.Android Maxim的策略5.实例演示——Windows系统&#xff0c;使用AVD模拟器&#xff0c;系统 Android6.0 1. Android Maxim介绍 Android Maxim是基于遍历规则的高性能Android Monkey&#xff0c;适…

基于SpringBoot+Vue的毕业生信息招聘平台设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

Elasticsearch常用接口使用说明以及postman调用调试

查看集群状态 接口url&#xff1a;http://xxxx:9200/_cat 查看所有索引 http://xxxx:9200/_cat/indices?v 创建索引 http://xxxx:9200/test-20230526?pretty 返回值 { "acknowledged": true, "shards_acknowledged": true, "index": &quo…

Opencv-C++笔记 (2) : opencv的矩阵操作

文章目录 创建与初始化1.1 数据类型1.2 基本方法1.3 初始化方法 矩阵加减法矩阵乘法矩阵转置矩阵求逆矩阵非零元素个数矩阵均值与标准差矩阵全局极值及位置GEMM 通用矩阵乘法Transform 对数组每一个元素执行矩阵变换MulTransposed 计算数组和数组的转置的乘积Trace 返回矩阵的迹…

WIN10:Cognos10.2_x32安装

一、Cognos BI Server 10.2 32Bit 二、Cognos Transformer 10.2 三、Cognos Framework Manager 10.2 四、环境 1、如果使用Cognos自带的Tomcat web容器&#xff0c;将E:\common\Cognos\c10\webcontent下的所有文件拷贝到E:\common\Cognos\c10\webapps\p2pd 下面.(一般我们就使…

redis高级篇 缓存双写一致性之更新策略

闲聊 缓存通用查询3部曲 redis 中数据&#xff0c;返回redis 中的数据redis 中没有&#xff0c;查询数据库并返回完成第二部的同时&#xff0c;将数据库查询结果写到redis,redis和数据库数据一致. 谈谈双写一致性的理解 1.如果redis 中有数据&#xff1a;需要和数据库中的相…

什么是可视化开发平台?拥有什么优势?

随着科技的进步和发展&#xff0c;可视化开发平台拥有广阔的市场前景&#xff0c;在提升企业办公企业效率、做好数据管理等方面具有自身的特色和优势。在办公自动化发展的年代&#xff0c;低代码开发平台是助力企业实现提质增效办公效率的得力助手&#xff0c;其可视化、易操作…