08-React扩展

08-React扩展


1. setState的2种写法

案例:

export default class Demo extends Component {state = {count: 0}add = () => {// 获取当前的值const { count } = this.state// 更新状态this.setState({ count: count + 1 })console.log(count);}render() {const { count } = this.statereturn (<div><h2>当前求和为:{count}</h2><button onClick={this.add}>点击+1</button></div>)}
}

可以看到setState更新视图是一个异步的动作,同步的输出事件只能获取更新前的状态。可知setState()是立即执行同步的,但是它引起的后续动作(react模版更新)是异步的,要等后续的进程执行完再更新视图。

setStata函数可以传入两个参数,除了需要更新的state状态对象,还可以传入一个回调函数,这个回调函数是一个异步函数

export default class Demo extends Component {state = {count: 0}add = () => {// 获取当前的值const { count } = this.state// 更新状态this.setState({ count: count + 1 },() => {console.log(this.state.count)})}render() {const { count } = this.statereturn (<div><h2>当前求和为:{count}</h2><button onClick={this.add}>点击+1</button></div>)}
}

1).对象式的setState

setState(stateChange, [callback])
  1. stateChange为状态改变对象(该对象可以体现出状态的更改)

    this.setState({ count: count + 1 },() => {})
    
  2. callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用

    this.setState({ count: count + 1 },() => {console.log(this.state.count)
    })
    

2).函数式的setState

 setState(updater, [callback])
  1. updater为返回stateChange对象的函数。

    this.setState(() => {return {count: this.state.count + 1}
    },() => {})
    
  2. updater可以接收到stateprops

    this.setState((state,props) => {console.log(state,props);return {count: state.count + 1}
    },() => {})
    

  3. callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。

    this.setState((state,props) => {return {count: state.count + 1}
    },() => {console.log(state.count)
    })
    

3).总结

  1. 对象式的setState是函数式的setState的简写方式(语法糖)

  2. 使用原则:

    1. 如果新状态不依赖于原状态 ===> 使用对象方式

      this.setState({count:99})
      
    2. 如果新状态依赖于原状态 ===> 使用函数方式

      this.setState(state => ({ count: state.count + 1 }))
      
    3. 如果需要在setState()执行后获取最新的状态数据,要在第二个callback函数中读取


2. 路由组件的lazyLoad

在实际开发中,整个React应用会有许多的组件,一般情况下在运行React项目时,程序会将所有组件全部加载,这样还未用到的组件也被加载,这样会影响程序整体运行的速度

实验:

export default class Demo extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><div className="pae-header"><h2>路由项目</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="/about">About</NavLink><NavLink className="list-group-item" to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Route path="/about" component={About} /><Route path="/home" component={Home} /></div></div></div></div></div>)}
}

可以看出当点击每个组件的链接Tab时,程序并没有发送加载资源请求,说明一开始运行程序的时候,所有组件已经全部请求完毕了,为了减少资源的浪费和提升程序的性能,需要用到路由的懒加载。

1).lazy函数

通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包

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

2).<Suspense>组件

通过<Suspense>组件包裹需要懒加载的组件,配置Lazy使用

export default class Demo extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><div className="pae-header"><h2>路由项目</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="/about">About</NavLink><NavLink className="list-group-item" to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Suspense><Route path="/about" component={About} /><Route path="/home" component={Home} /></Suspense></div></div></div></div></div>)}
}

还可以通过<Suspense>指定在加载得到路由打包文件前显示一个自定义loading界面,当网速慢或者其他原因导致组件加载请求慢时会有一个备用组件作为优先显示

<Suspense fallback={<h1>Loading.....</h1>}><Route path="/about" component={About} /><Route path="/home" component={Home} />
</Suspense>


3. Hooks

1). React Hook/Hooks是什么?

(1). Hook是React 16.8.0版本增加的新特性/新语法
(2). 可以让你在函数组件中使用 state 以及其他的 React 特性

2). 三个常用的Hook

a. State Hook
  1. State Hook让函数组件也可以有state状态, 并进行状态数据的读写操作

    //类式组件
    class Demo extends Component {state = {count: 0}add = () => {this.setState(state => ({ count: state.count + 1 }))}render() {const { count } = this.statereturn (<div><h2>当前求和为:{count}</h2><button onClick={this.add}>点击+1</button></div>)}
    }
    
  2. 语法:

     const [xxx, setXxx] = React.useState(initValue)  
    
  3. useState()说明:

  • 参数: 第一次初始化指定的值在内部作缓存
  • 返回值: 包含2个元素的数组, 第1个为内部当前状态值, 第2个为更新状态值的函数
//函数式组件
function Demo() {const [count, setCount] = React.useState(0)function add() {setCount(count+1)}return (<div><h2>当前求和为:{count}</h2><button onClick={add}>点击+1</button></div>)
}
  1. setXxx()的2种写法:
  • setXxx(newValue): 参数为非函数值, 直接指定新的状态值, 内部用其覆盖原来的状态值

  • setXxx(value => newValue): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值

    function add() {// 第一种写法setCount(count+1)// 第二种写法setCount(count => count + 1)}
    
b. Effect Hook
  1. Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)

    // 类式组件写法
    class Demo extends Component {state = {count: 0}unmount = () => {createRoot(document.getElementById('root')).unmount();}componentDidMount() {this.timer = setInterval(() => {this.setState(state => ({ count: state.count + 1 }))}, 1000)}componentWillUnmount() {clearInterval(this.timer)}render() {const { count } = this.statereturn (<div><button onClick={this.unmount}>点击卸载</button></div>)}
    } 
    

  2. React中的副作用操作:

    • ajax请求数据获取
    • 设置订阅 / 启动定时器
    • 手动更改真实DOM
  3. 语法和说明:

    useEffect(() => { // 在此可以执行任何带副作用操作return () => {}
    }, [stateValue])
    
    //函数式组件
    function Demo() {const [count, setCount] = React.useState(0)React.useEffect(() => {let timer = setInterval(() => {setCount(count => count + 1)}, 1000)return () => {clearInterval(timer)}}, [])function unmount() {createRoot(document.getElementById('root')).unmount();}return (<div><h2>当前求和为:{count}</h2><button onClick={unmount}>点击卸载</button> </div>)
    }
    

    分析:

    1. 使用React.useEffect()时不写第二个参数,那么Effect Hook会监测所有状态值的变化

      function Demo() {const [count, setCount] = React.useState(0)const [name, setName] = React.useState('Tom')React.useEffect(() => {console.log('@@');})function add() {setCount(count => count + 1)}function changeName() {setName('Jack')}return (<div><h2>当前求和为:{count}</h2><h2>当前的名字为{name}</h2> <button onClick={add}>点击+1</button><button onClick={changeName}>点我改名</button></div>)
      }
      

    2. 使用React.useEffect()时写一个空数组为参数,那么Effect Hook不会监测任何状态值的变化,回调函数只会在第一次render()后执行

      React.useEffect(() => {console.log('@@');
      },[])
      

    3. 使用React.useEffect()时写值为指定状态值的非空数组作为第二个参数,那么Effect Hook只会监测指定状态值的变化

      React.useEffect(() => {console.log('@@');
      },[name])
      

    4. React.useEffect()中的返回函数return在组件卸载前执行,一般在此做一些收尾工作, 比如清除定时器/取消订阅等,

      注意点:每次执行这里的更新该函数也会去执行一遍

      React.useEffect(() => {let timer = setInterval(() => {setCount(count => count + 1)}, 1000)return () => {clearInterval(timer)} 
      },[])
      
  4. 可以把 useEffect Hook 看做如下三个函数的组合

    • componentDidMount()
    • componentDidUpdate()
    • componentWillUnmount()
c. Ref Hook
  1. Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据

    // 类式组件的写法
    class Demo extends Component {myRef=React.createRef();show=() => {alert(this.myRef.current.value)}render() {return (<div><input ref={this.myRef} type="text" /><button onClick={this.show}>点击显示</button></div>)}
    }
    

  2. 语法:

    const refContainer = useRef()
    
  3. 作用:保存标签对象,功能与React.createRef()一样

    // 函数式组件的写法
    function Demo() {const myRef=React.useRef()function show() {alert(myRef.current.value)}return (<div><input ref={myRef} type="text" /><button onClick={show}>点击显示</button></div>)
    }
    

4. Fragment

使用:
<Fragment><Fragment>
<></>
import React, { Component, Fragment } from 'react'
export default class Demo extends Component {render() {return (<Fragment><input type="text" /><input type="text" /></Fragment> )}
}
import React, { Component, Fragment } from 'react'
export default class Demo extends Component {render() {return (<><input type="text" /><input type="text" /></>)}
}
作用

可以不用必须有一个真实的DOM根标签了

未使用Fragment标签:

使用Fragment标签:


5. Context

理解:

一种组件间通信方式, 常用于【祖组件】与【后代组件】间通信

使用:

需求:将A组件状态中的数据传递给C组件,不通过B组件的二次传递

export default class A extends Component {state = {username: 'tom',age: 18}render() {const { username, age } = this.statereturn (<div className='parent'><h3>我是A组件</h3><h4>我的用户名是:{username}</h4><h4>我的年龄是:{age}</h4><B/></div>)}
}
class B extends Component {render() {return (<div className='child'><h3>我是B组件</h3><C/></div>)}
}
class C extends Component {render() {return (<div className='grand'><h3>我是C组件</h3><h4>我从A组件拿到的用户名是:???</h4><h4>我从A组件拿到的年龄时是:???</h4></div>)}
}
  1. 创建Context容器对象:

    const XxxContext = React.createContext()  
    
    // 创建context对象
    const UserNameContext = React.createContext()
    
  2. 渲染子组时,外面包裹xxxContext.Provider, 通过value属性给后代组件传递数据:

    <xxxContext.Provider value={数据}>
    子组件
    </xxxContext.Provider>
    
    const { Provider } = UserNameContext
    export default class A extends Component {state = {username: 'tom',age: 18}render() { const { username, age } = this.statereturn (<div className='parent'><h3>我是A组件</h3><h4>我的用户名是:{username}</h4><h4>我的年龄是:{age}</h4><Provider value={{ username, age }}><B /></Provider></div>)}
    }
    
  3. 后代组件读取数据:

    第一种方式:仅适用于类组件

      static contextType = xxxContext  // 声明接收contextthis.context // 读取context中的value数据
    
    class C extends Component {// 声明接收contextstatic contextType = UserNameContextrender() {console.log(this);console.log(this.context);const {username,age}=this.contextreturn (<div className='grand'><h3>我是C组件</h3><h4>我从A组件拿到的用户名是:{username}</h4><h4>我从A组件拿到的年龄时是:{age}</h4></div>)}
    }
    

    第二种方式: 函数组件与类组件都可以

     <xxxContext.Consumer>{value => ( // value就是context中的value数据//要显示的内容)}</xxxContext.Consumer>
    
    // 创建context对象
    const UserNameContext = React.createContext()
    const { Provider, Consumer } = UserNameContext
    function C() {return (<div className='grand'><h3>我是C组件</h3><Consumer>{value => {return (<div><h4>我从A组件拿到的用户名是:{value.username}</h4><h4>我从A组件拿到的年龄时是:{value.age}</h4></div>)}}</Consumer></div>)
    }
    

注意:

在应用开发中一般不用context, 一般都用它的封装react插件


6. 组件优化

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

    export default class Parent extends Component {state = {carName: '奔驰'}changeName = () => {const { carName } = this.statethis.setState({})}render() {console.log('parent---render');return (<div className='parent'><h3>我是Parent组件</h3><h4>我的车的名字是:{this.state.carName}</h4><button onClick={this.changeName}>点击换车</button></div>)}
    }
    

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

export default class Parent extends Component {state = {carName: '奔驰',stus:['小王','小李','小芳']}changeName = () => {const { carName } = this.statethis.setState({})}render() {console.log('parent---render');return (<div className='parent'><h3>我是Parent组件</h3><h4>我的车的名字是:{this.state.carName}</h4><button onClick={this.changeName}>点击换车</button><Child carName='奥拓'/></div>)}
}class Child extends Component {render() {console.log('child---render');return (<div className='child'><h3>我是Child组件</h3><h4>我接受到的车的名字是:{this.props.carName}</h4></div>)}
}

效率高的做法

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

原因

Component中的shouldComponentUpdate()总是返回true

解决
办法1:
  1. ​ 重写shouldComponentUpdate()方法

  2. ​ 比较新旧stateprops数据, 如果有变化才返回true, 如果没有返回false

    // person组件
    class Parent extends Component {state = {carName: '奔驰',}changeName = () => {const { carName } = this.statethis.setState({})}shouldComponentUpdate(nextProps,nextState){return !this.state.carName===nextState.carName} render() {console.log('parent---render');return (<div className='parent'><h3>我是Parent组件</h3><h4>我的车的名字是:{this.state.carName}</h4><button onClick={this.changeName}>点击换车</button></div>)}
    }
    

    // Child组件
    class Child extends Component {shouldComponentUpdate(nextProps,nextState){return !this.props.carName===nextProps.carName}render() {console.log('child---render');return (<div className='child'><h3>我是Child组件</h3><h4>我接受到的车的名字是:{this.props.carName}</h4></div>)}
    }
    

办法2:
  1. 使用PureComponent

    import React, { PureComponent} from 'react'
    
  2. PureComponent重写了shouldComponentUpdate(), 只有stateprops数据有变化才返回true

    export default class Parent extends PureComponent {state = {carName: '奔驰',}changeName = () => {const { carName } = this.statethis.setState({})}render() {console.log('parent---render');return (<div className='parent'><h3>我是Parent组件</h3><h4>我的车的名字是:{this.state.carName}</h4><button onClick={this.changeName}>点击换车</button><Child carName='奥拓'/></div>)}
    }class Child extends PureComponent {render() {console.log('child---render');return (<div className='child'><h3>我是Child组件</h3><h4>我接受到的车的名字是:{this.props.carName}</h4></div>)}
    }
    

  3. 注意:

    1. 只是进行stateprops数据的浅比较, 如果只是数据对象内部数据变了, 返回false

    2. 不要直接修改state数据, 而是要产生新数据

      export default class Parent extends PureComponent {state = {carName: '奔驰'}changeName = () => {const obj = this.stateobj.carName = '迈巴赫'console.log(obj === this.state);this.setState(obj)}render() {console.log('parent---render');return (<div className='parent'><h3>我是Parent组件</h3><h4>我的车的名字是:{this.state.carName}</h4><button onClick={this.changeName}>点击换车</button></div>)}
      }
      

      PureComponent的底层做了一个浅对比,不会管Obj里面的属性是否发生变化,只要Objthis.state是同一个对象,就不会引起更新

      在之前更新数组类型的状态时说过不能通过使用pushunshift等原生数组的方法改写数组来更新状态,需要返回一个新的数组进行更新

      export default class Parent extends PureComponent {state = {stus:['小王','小李','小芳']}addStus=() => {const {stus}=this.statestus.unshift('小刘')this.setState({stus})}render() {console.log('parent---render');return (<div className='parent'><h3>我是Parent组件</h3><h4>学生有{this.state.stus}</h4><button onClick={this.addStus}>添加学生</button></div>)}
      }
      

      需要通过[新增的数组元素,...原数组]的方式进行更新

      export default class Parent extends PureComponent {state = {stus:['小王','小李','小芳']}addStus=() => {const {stus}=this.statethis.setState({stus:['小刘',...stus]})}render() {console.log('parent---render');return (<div className='parent'><h3>我是Parent组件</h3><h4>学生有{this.state.stus}</h4><button onClick={this.addStus}>添加学生</button></div>)}
      }
      

  4. 项目中一般使用PureComponent来优化


7. render props

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

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

children props

之前说过标签体的内容是标签特殊的属性children,可以通过this.props.children进行读取,所以可以将B组件作为A组件的标签体写入

export default class Parent extends Component {render() {return (<div className='parent'><h3>我是Parent组件</h3><A> <B/> </A></div>)}
}
class A extends Component {state={name:'tom'}render() {const {name}=this.statereturn (<div className='a'><h3>我是A组件</h3>{this.props.children}</div>)}
}
class B extends Component {render() {return (<div className='b'><h3>我是B组件</h3></div>)}
}

问题: 如果B组件需要A组件内的数据 ==> 做不到

export default class Parent extends Component {render() {return (<div className='parent'><h3>我是Parent组件</h3><A> <B/> </A></div>)}
}
class A extends Component {state={name:'tom'}render() {const {name}=this.statereturn (<div className='a'><h3>我是A组件</h3>{this.props.children}</div>)}
}
class B extends Component {render() {return (<div className='b'><h3>我是B组件</h3><h3>从A获取到名字:{this.props.name}</h3></div>)}
}

render props
<A render={(data) => <C data={data}></C>}></A>

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

export default class Parent extends Component {render() {return (<div className='parent'><h3>我是Parent组件</h3><A render={(name)=><B name={name}/>}/></div>)}
}
class A extends Component {state={name:'tom'}render() {const {name}=this.statereturn (<div className='a'><h3>我是A组件</h3>{this.props.render(name)}</div>)}
}
class B extends Component {render() {return (<div className='b'><h3>我是B组件</h3><h3>从A获取到名字:{this.props.name}</h3></div>)}
}


8. 错误边界

理解:

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

特点:

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

使用方式:

getDerivedStateFromError配合componentDidCatch

// 生命周期函数,一旦后台组件报错,就会触发
static getDerivedStateFromError(error) {console.log(error);// 在render之前触发// 返回新的statereturn {hasError: true,};
}
componentDidCatch(error, info) {// 统计页面的错误。发送请求发送到后台去console.log(error, info);
}
// Parent组件
export default class Parent extends Component {state={hasError:''//用于标识子组件是否产生错误}// 出错时的生命周期钩子  componentDidCatch(){console.log('渲染组件出错');}// 当Parent的子组件出现报错时候,会触发getDerivedStateFromError调用,并携带错误信息static getDerivedStateFromError(error){console.log(error);return {hasError:error}}render() {return (<div><h2>我是Parent组件</h2>{this.state.hasError?<h2>网络出错</h2>:<Child/>}</div>)}
}
// Child组件
export default class Child extends Component {state={/* users:[{id:'1',name:'may',age:18},{id:'2',name:'tom',age:21},{id:'3',name:'jerry',age:19}] */// 错误原因:users:''}render() {return (<div><h2>我是Child组件</h2><ul>{this.state.users.map((userObj)=>{return <li key={userObj.id}>名字{userObj.name}——年龄{userObj.age}</li>})}</ul></div>)}
}

9. 组件通信方式总结

组件间的关系:
  • 父子组件
  • 兄弟组件(非嵌套组件)
  • 祖孙组件(跨级组件)
几种通信方式:
  1. propschildren propsrender props
  2. ​ 消息订阅-发布:pubs-subevent等等
  3. ​ 集中式管理:reduxdva等等
  4. conText:生产者-消费者模式
比较好的搭配方式:
  1. ​ 父子组件:props
  2. ​ 兄弟组件:消息订阅-发布、集中式管理
  3. ​ 祖孙组件(跨级组件):消息订阅-发布、集中式管理、conText(开发用的少,封装插件用的多)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript从入门到精通系列第二十二篇:JavaScript中的toString方法和JavaScript中的垃圾回收

文章目录 一&#xff1a;toString方法 1&#xff1a;怪异的返回值[object Object] 2&#xff1a;打印对象成为一个JSON 二&#xff1a;垃圾回收&#xff08;GC&#xff09; 1&#xff1a;垃圾回收概念 2&#xff1a;JS当中的垃圾回收机制 3&#xff1a;JS中的垃圾回收算…

基于厨师优化的BP神经网络(分类应用) - 附代码

基于厨师优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于厨师优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.厨师优化BP神经网络3.1 BP神经网络参数设置3.2 厨师算法应用 4.测试结果&#xff1a;5.M…

基于ssm的旅游管理系统

功能如下图所示 摘要 基于SSM框架的旅游管理系统代表了信息技术在旅行业中的崭新机遇&#xff0c;为旅行企业提供了强大的工具&#xff0c;以应对现代旅游市场的复杂挑战。这个系统的研发和实施具有广泛的研究意义&#xff0c;它深刻影响了旅游业的发展&#xff0c;具体表现如下…

自然语言处理---Transformer机制详解之GPT模型介绍

1 GPT介绍 GPT是OpenAI公司提出的一种语言预训练模型.OpenAI在论文<< Improving Language Understanding by Generative Pre-Training >>中提出GPT模型.OpenAI后续又在论文<< Language Models are Unsupervised Multitask Learners >>中提出GPT2模型.…

【LeetCode刷题(数据结构与算法)】:数据结构中的常用排序实现数组的升序排列

现在我先将各大排序的动图和思路以及代码呈现给大家 插入排序 直接插入排序是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a; 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为 止&#xff0c;得到一个…

基于协作搜索优化的BP神经网络(分类应用) - 附代码

基于协作搜索优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于协作搜索优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.协作搜索优化BP神经网络3.1 BP神经网络参数设置3.2 协作搜索算法应用 4.测试结果…

图论04-【无权无向】-图的广度优先遍历

文章目录 1. 代码仓库2. 广度优先遍历图解3.主要代码4. 完整代码 1. 代码仓库 https://github.com/Chufeng-Jiang/Graph-Theory 2. 广度优先遍历图解 3.主要代码 原点入队列原点出队列的同时&#xff0c;将与其相邻的顶点全部入队列下一个顶点出队列出队列的同时&#xff0c;将…

2023-10-19 LeetCode每日一题(同积元组)

2023-10-19每日一题 一、题目编号 1726. 同积元组二、题目链接 点击跳转到题目位置 三、题目描述 给你一个由 不同 正整数组成的数组 nums &#xff0c;请你返回满足 a * b c * d 的元组 (a, b, c, d) 的数量。其中 a、b、c 和 d 都是 nums 中的元素&#xff0c;且 a ! b…

前端工作方式要换了?HTMX简介:无需JavaScript的动态HTML

HTMX允许你使用扩展的HTML语法代替 JavaScript 来实现交互性。HTMX 在标记中直接为你提供HTTP 交互&#xff0c;并支持许多其他交互需求&#xff0c;无需求助于 JavaScript。这是一个有趣的想法&#xff0c;可能最终会影响到web前端的工作方式。让我们看看如何使用HTMX以及它的…

Studio One 6.5新版本功能讲解及一键安装下载教程

Studio One 6.5 发布&#xff1a;整合 Dolby Atmos 全景声&#xff0c;跟 Bitwig 联合推出开放的 DAWproject 格式&#xff0c;支持 Linux&#xff01; PreSonus 的“.5”更新通常都有比较大的变化&#xff0c;这次也不例外。Studio One 6.5 增加了一种全新的工作方式&#xff…

SpringMVC的工作流程

1、SpringMVC的定义 Spring MVC是基于Java的开源Web框架&#xff0c;它是Spring框架的一部分&#xff0c;用于构建MVC&#xff08;Model-View-Controller&#xff09;模式的Web应用程序。它提供了一种灵活且强大的方式来开发Web应用程序&#xff0c;并将应用程序的不同层进行解…

Hadoop3教程(二十八):(生产调优篇)NN、DN的多目录配置及磁盘间数据均衡

文章目录 &#xff08;148&#xff09;NN多目录配置&#xff08;149&#xff09;DataNode多目录配置及磁盘间数据平衡磁盘间数据均衡 参考文献 &#xff08;148&#xff09;NN多目录配置 NN多目录的意思是&#xff0c;本地目录可以配置成多个&#xff0c;且每个目录存放内容相…

Tmux:终端复用器的基本使用(二)

相关阅读 Tmuxhttps://blog.csdn.net/weixin_45791458/category_12472796.html?spm1001.2014.3001.5482 上一篇文章列举了一些关于tmux中会话的基本使用方法&#xff0c;但会话并非是tmux的最强大的功能&#xff0c;tmux还能在一个会话中创建多个窗口(windows)&#xff0c;并…

如何为 Elasticsearch 创建自定义连接器

了解如何为 Elasticsearch 创建自定义连接器以简化数据摄取过程。 作者&#xff1a;JEDR BLASZYK Elasticsearch 拥有一个摄取工具库&#xff0c;可以从多个来源获取数据。 但是&#xff0c;有时你的数据源可能与 Elastic 现有的提取工具不兼容。 在这种情况下&#xff0c;你可…

文件列表创建工具 Nifty File Lists mac中文版功能特色

Nifty File Lists mac是一款文件列表创建工具&#xff0c;全面的元数据支持&#xff0c;涵盖了从基本文件信息&#xff0c;如文件名、路径、大小、创建和修改日期等等内容。 Nifty File Lists mac功能特色 全面的 元数据支持强大的多线程元数据提取系统涵盖了从基本文件信息&a…

elasticsearch的docker安装与使用

安装 docker network create elasticdocker pull docker.elastic.co/elasticsearch/elasticsearch:8.10.4# 增加虚拟内存&#xff0c; 此处适用于linux vim /etc/sysctl.conf # 添加 vm.max_map_count262144 # 重新启动 sysctl vm.max_map_countdocker run --name es01 --net …

Spring定时任务@Scheduled

在 Spring 框架中&#xff0c;可以使用定时任务来执行周期性或延迟执行的任务。Spring 提供了多种方式来配置和管理定时任务。有Java自带的java.util.Timer类&#xff0c;也有强大的调度器Quartz&#xff0c;还有SpringBoot自带的Scheduled。 在实际应用中&#xff0c;如果没有…

聊聊分布式架构09——分布式中的一致性协议

目录 01从集中式到分布式 系统特点 集中式特点 分布式特点 事务处理差异 02一致性协议与Paxos算法 2PC&#xff08;Two-Phase Commit&#xff09; 阶段一&#xff1a;提交事务请求 阶段二&#xff1a;执行事务提交 优缺点 3PC&#xff08;Three-Phase Commit&#x…

实际项目中最常用的设计模式

在软件开发领域,设计模式是一种经过验证的通用解决方案,用于解决各种常见问题。它们有助于提高代码的可维护性、可扩展性和可重用性。虽然有许多不同的设计模式,但以下是实际项目中最常用的一些: 1. 单例模式 (Singleton Pattern) 单例模式确保一个类只有一个实例,并提供…

蓝桥杯每日一题2023.10.21

后缀表达式 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 30分解法&#xff1a;要求出最大的结果就需要加的数越大&#xff0c;减的数越小&#xff0c;以此为思路简单列举即可 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N 2e5 10…