07 redux的使用

news2024/11/16 18:10:13

总结

在这里插入图片描述

一.@reduxjs/toolkit使用

1.1安装

  • 安装:
npm install @reduxjs/toolkit

在src目录中的store目录中的index.js中添加

1.2导入包中的对象

  • 导入包中的对象
import { createSlice, configureStore } from '@reduxjs/toolkit'

1.3创建切片对象

  • 创建切片对象
//这个方法需要传入一个参数是对象,在这个对象中必须要有的是name属性
const counter = createSlice({
    //这个名称会作为action.type中的前缀,避免命名冲突,自动追加
    name: 'count',
    //初始状态数据
    initialState: {
        num: 10
    },
    //定义reducers
    //定义reducer更新状态数据的函数
    //而里面的方法在后期组件中执行dispatch时是作为action函数的函数名去使用的
    reducers: {
        //需要传入两个参数,一个是state(代理的proxy对象)、一个是action
        add(state, { payload }) {
            //输出
            // console.log(state);
            // console.log(action)
            state.num += payload;
        },
        dec(state, { payload }) {
            //输出
            // console.log(state);
            // console.log(action)
            state.num -= payload;
        }
    }
});

1.4获取action函数并导出方法

  • 获取action函数并导出方法
export let { add,dec } = counter.actions;

1.5创建store对象

  • 创建store对象
//调用rtk的configureStore方法,
//该方法相当于集成了redux和redux-redux的createStore、combineReducers、middleware以及默认支持了Redux DevTools。
const store = configureStore({
    reducer: counter.reducer
})

1.6异步使用redux

  • 异步使用redux
    在store/index.js文件中只需要单独声明一个方法并导出,不需要其他操作
//单独创建一个函数
export let asynctianjia = (payload) => {
    return dispatch => {
        //执行异步操作
        setTimeout(() => {
            dispatch(add(payload));
        }, 1000)
    }
}

1.7导出store

  • 导出
export default store;

1.8获取状态数据

  • 获取状态数据
console.log(store.getState())

1.9修改状态数据

  • 修改状态数据
store.dispatch(add(10))
store.dispatch(dec(5))

1.10store.subscribe()来重新渲染数据

  • store.subscribe()来重新渲染数据
    不要忘记在主入口中重新渲染组件,因为redux只负责状态管理,不负责组件的重新渲染
import store from './store';
store.subscribe(() => {
  root.render(
    <>
      <App />
    </>
  );
})

二、react-redux 使用

redux的问题:

  • 需要自己绑定监听来重新渲染整个组件

  • 每次state更新, 都需要重新render所有组件(使用subscribe方法进行订阅redux状态的更新) ,

  • 效率低,应该有用到state数据的组件需要render

解决: 使用 react-redux 库,想要使用必须下载npm i react-redux

文档: https://react-redux.js.org/

react-redux 是一个 react 插件,用来简化 react 中使用 redux

在这里插入图片描述

Provider 组件:用来包裹整个 React 应用,接收 store 属性,为应用提供 state 和 更新 state 的函数。

核心Hook函数

  • useSelector 函数: 读取state数据
  • useDispatch 函数: 得到分发action的dispatch函数

2.1 使用步骤

  • 下载
  npm i react-redux
  • 通过Provider向App及其所有后代组件提供store
  import React from 'react';
  import ReactDOM from 'react-dom/client';
  import App from './App';
  import { Provider } from 'react-redux'
  import store from './store';
  const root = ReactDOM.createRoot(document.getElementById('root'));
  root.render(
    <>
      <Provider store={store}>
        <App />
      </Provider>
    </>
  );
  • 修改Redux.jsx组件中的代码,进行调用Hook函数
  import React from 'react'
  import { add, dec, asynctianjia } from '../../store/modules/counter';
  import { add as a, dec as b } from '../../store/modules/Hit'
  import { useSelector, useDispatch } from 'react-redux';
  //调用useSelector方法来获取redux中所有的状态数据,redux会将所获取到的状态通过state参数获取(参数名可以自定义)
  let { count: { num }, hit: { hitCount } } = useSelector(state => state);
  //调用useDispatch进行分发action
  let dispatch = useDispatch();
  let addCount = () => {
      dispatch(add(1)); //省略store
  }
  ... //后面的方法照旧

注意:在回调函数中不能调用React Hook,ReactHook必须在React函数组件或自定义ReactHook函数中调用

React全家桶

前言:

1.组件间的关系

  • 父子组件(嵌套组件)
  • 兄弟组件(非嵌套组件,平行书写的)
  • 祖孙组件 (跨级组件)

2.通信方式

  • props
  • 消息订阅发布模式:pub/sub
  • 集中式状态管理: redux
  • 生产者-消费者模式: context

3.具体使用场景

  • 父子组件通信: props

    • 父传子:子组件通过props直接接受。<子组件 name={“张三”}/>

    • 子传父,父组件定义一个函数,把函数传给子组件,

      子组件在一定时机触发这个函数,把要传递的数据以函数参数的形式传递过去。

  • 兄弟组件通信:消息订阅与发布、集中式状态管理

  • 祖孙组件通信:集中式状态管理、createContext结合useContext

一、Redux

含义:集中式状态管理工具,redux只管状态,不管其他(组件的更新)

官网:https://cn.redux.js.org/
在这里插入图片描述

2014年 Facebook 提出了 Flux 架构的概念。

在这里插入图片描述

Redux 是 JavaScript 应用的可预测状态容器,用来集中管理状态。

特点:集中管理、可预测、易于测试、易于调试、强大的中间件机制满足你所有需求。

注意:redux 是一个独立于 react 的库,可以配合任何 UI 库/框架来使用。

redux的三大原则

  1. 单一数据源(固定在某一个位置)

  2. State是只读的(不能直接修改,必须要借助于store中的dispatch方法才可以修改)

  3. 使用纯函数来执行产生新 state

什么情况下需要使用redux

  1. 总体原则: 大型项目状态管理复杂才用,如果是小型项目还是可以使用(useState、props、useContext)
  2. 某个组件的状态,需要共享
  3. 某个状态需要在任何地方都可以拿到
  4. 一个组件需要改变全局状态
  5. 一个组件需要改变另一个组件的状态

Redux有3大核心概念

  1. Action:操作状态数据的动作
  2. Reducer:包含状态数据和动作
  3. Store:仓库

在这里插入图片描述

在这里插入图片描述

1.1 Redux初体验

  • 安装:
npm install @reduxjs/toolkit

在src目录中的store目录中的index.js中添加

  • 导入包中的对象
import { createSlice, configureStore } from '@reduxjs/toolkit'
  • 创建切片对象
//这个方法需要传入一个参数是对象,在这个对象中必须要有的是name属性
const counter = createSlice({
    //这个名称会作为action.type中的前缀,避免命名冲突,自动追加
    name: 'count',
    //初始状态数据
    initialState: {
        num: 10
    },
    //定义reducers
    //定义reducer更新状态数据的函数
    //而里面的方法在后期组件中执行dispatch时是作为action函数的函数名去使用的
    reducers: {
        //需要传入两个参数,一个是state(代理的proxy对象)、一个是action
        add(state, { payload }) {
            //输出
            // console.log(state);
            // console.log(action)
            state.num += payload;
        },
        dec(state, { payload }) {
            //输出
            // console.log(state);
            // console.log(action)
            state.num -= payload;
        }
    }
});
  • 获取action函数并导出方法
export let { add,dec } = counter.actions;
  • 创建store对象
//调用rtk的configureStore方法,
//该方法相当于集成了redux和redux-redux的createStore、combineReducers、middleware以及默认支持了Redux DevTools。
const store = configureStore({
    reducer: counter.reducer
})
  • 获取状态数据
console.log(store.getState())
  • 修改状态数据
store.dispatch(add(10))
store.dispatch(dec(5))
  • 导出
export default store;

1.2 在组件中使用Redux

  • 在Component文件夹中创建Redux目录以及Redux.jsx文件
import React from 'react'
import store, { add, dec } from '../../store/index';
export default function Redux() {
    let { num } = store.getState();
    let addCount = () => {
        store.dispatch(add(1))
    }
    let decCount = () => {
        store.dispatch(dec(1))
    }
    return (
        <div>
            <p>点击次数:{num}</p>
            <button onClick={addCount}>1</button>&nbsp;&nbsp;
            <button onClick={decCount}>1</button>
        </div>
    )
}
  • App组件中导入Redux组件
import React from 'react';
import Redux from './Component/Redux/Redux';
export default function App() {
    return (
        <div>
            <Redux />
        </div>
    )
}

不要忘记在主入口中重新渲染组件,因为redux只负责状态管理,不负责组件的重新渲染

import store from './store';
store.subscribe(() => {
  root.render(
    <>
      <App />
    </>
  );
})

1.3 在组件中异步使用Redux

  • Redux组件中新增一行button,用来执行异步代码功能
<button>异步加20</button>
  • 在store/index.js文件中只需要单独声明一个方法并导出,不需要其他操作
//单独创建一个函数
export let asynctianjia = (payload) => {
    return dispatch => {
        //执行异步操作
        setTimeout(() => {
            dispatch(add(payload));
        }, 1000)
    }
}
  • Redux组件中导入并使用并传参
import store, { asynctianjia } from '../../store/index';
let asyncaAddCount = () => {
    store.dispatch(asynctianjia(20));
}
<button onClick={asyncaAddCount}>异步加20</button>

1.4 给Redux进行分层

  • 在store目录中创建modules文件夹,存储每一个切片状态,在其中创建一个counter.js文件
//1、创建reducers
import { createSlice } from '@reduxjs/toolkit'

//2、创建切片对象
//这个方法需要传入一个参数是对象,在这个对象中必须要有的是name属性
const counter = createSlice({
    //这个名称会作为action.type中的前缀,避免命名冲突,自动追加
    name: 'count',
    //初始状态数据
    initialState: {
        num: 10
    },
    //定义reducers
    //定义reducer更新状态数据的函数
    //而里面的方法在后期组件中执行dispatch时是作为action函数的函数名去使用的
    reducers: {
        //需要传入两个参数,一个是state(代理的proxy对象)、一个是action
        add(state, { payload }) {
            //输出
            // console.log(state);
            // console.log(action)
            state.num += payload;
        },
        dec(state, { payload }) {
            //输出
            // console.log(state);
            // console.log(action)
            state.num -= payload;
        }
    }
});

//3、获取action函数并导出方法
export let { add,dec } = counter.actions;

//单独创建一个函数
export let asynctianjia = (payload) => {
    return dispatch => {
        //执行异步操作
        setTimeout(() => {
            dispatch(add(payload));
        }, 1000)
    }
}

//3、导出
export default counter;
  • 整理store/index.js文件
import { configureStore } from '@reduxjs/toolkit'
import counter from './modules/counter'
const store = configureStore({ reducer: counter.reducer })
export default store;
  • 调整Redux.jsx中文件的导入
import store from '../../store/index';
import { add, dec, asynctianjia } from '../../store/modules/counter';

1.5 在Redux中新增一个状态

需求:新增一个点赞数

  • 在store/module文件中新增一个文件,用来存储点赞数状态
import { createSlice } from '@reduxjs/toolkit'
const hit = createSlice({
    name: 'hit',
    initialState: {
        hitCount: 100
    },
    reducers: {
        add(state, { payload }) {
            state.hitCount += payload;
        },
        dec(state, { payload }) {
            state.hitCount -= payload;
        }
    }
})
export let { add, dec } = hit.actions;
export default hit.reducer
  • 在store/index.js中导入并合并使用
import { configureStore } from '@reduxjs/toolkit'
import counter from './modules/counter'
import HitReducer from './modules/Hit'
const store = configureStore(
    {
        reducer: {
            count: counter,
            hit: HitReducer
        }
    })
export default store;
  • 在Redux组件中导入
import { add, dec, asynctianjia } from '../../store/modules/counter';
//注意:如果声明的方法和其他状态文件中重名,可以使用as添加别名使用
import { add as a, dec as b } from '../../store/modules/Hit'

重新对获取到的状态数据进行解构

let { count: { num }, hit: { hitCount } } = store.getState();
  • 增加页面结构
<p>点赞数:{hitCount}</p>
<button onClick={addHit}>增加点赞数</button>
<button onClick={DecHit}>减少点赞数</button>
  • 声明函数并调用
let addHit = () => {
    store.dispatch(a(1))
}
let DecHit = () => {
    store.dispatch(b(1))
}

二、react-redux 使用

redux的问题:

  • 需要自己绑定监听来重新渲染整个组件

  • 每次state更新, 都需要重新render所有组件(使用subscribe方法进行订阅redux状态的更新) ,

  • 效率低,应该有用到state数据的组件需要render

解决: 使用 react-redux 库,想要使用必须下载npm i react-redux

文档: https://react-redux.js.org/

react-redux 是一个 react 插件,用来简化 react 中使用 redux

在这里插入图片描述

Provider 组件:用来包裹整个 React 应用,接收 store 属性,为应用提供 state 和 更新 state 的函数。

核心Hook函数

  • useSelector 函数: 读取state数据
  • useDispatch 函数: 得到分发action的dispatch函数

2.1 使用步骤

  • 下载
  npm i react-redux
  • 通过Provider向App及其所有后代组件提供store
  import React from 'react';
  import ReactDOM from 'react-dom/client';
  import App from './App';
  import { Provider } from 'react-redux'
  import store from './store';
  const root = ReactDOM.createRoot(document.getElementById('root'));
  root.render(
    <>
      <Provider store={store}>
        <App />
      </Provider>
    </>
  );
  • 修改Redux.jsx组件中的代码,进行调用Hook函数
  import React from 'react'
  import { add, dec, asynctianjia } from '../../store/modules/counter';
  import { add as a, dec as b } from '../../store/modules/Hit'
  import { useSelector, useDispatch } from 'react-redux';
  //调用useSelector方法来获取redux中所有的状态数据,redux会将所获取到的状态通过state参数获取(参数名可以自定义)
  let { count: { num }, hit: { hitCount } } = useSelector(state => state);
  //调用useDispatch进行分发action
  let dispatch = useDispatch();
  let addCount = () => {
      dispatch(add(1)); //省略store
  }
  ... //后面的方法照旧

注意:在回调函数中不能调用React Hook,ReactHook必须在React函数组件或自定义ReactHook函数中调用

三、利用redux改写Todolist案例

3.1 完成初始状态数据的渲染

  • 先整理一个纯的案例,将之前实现的所有代码先删掉
  • 在store/modules下创建一个状态文件,名称定位Todo.js
//1、导入
import { createSlice } from '@reduxjs/toolkit';
//2、创建对象
const Todo = createSlice({
    name: 'Todo',
    initialState: [
        {
            id: 1,
            title: '任务1',
            done: false
        },
        {
            id: 2,
            title: '任务2',
            done: false
        }
    ],
    reducers: {
        addTo(state, { payload }) {
            state.push(payload);
        }
    }
});

export let { addTo } = Todo.actions;

//3、暴露
export default Todo.reducer;
  • 在store/index.js文件中导入
import { configureStore } from '@reduxjs/toolkit'
import TodoReducer from './modules/Todo'
const store = configureStore(
    {
        reducer: {
            todolist: TodoReducer
        }
    })
export default store;
  • 修改TodoItem.jsx文件,获取状态数据并渲染读取
import React from 'react'
import { useSelector } from 'react-redux'
export default function TodoItem() {
    let { todolist } = useSelector(state => state);
    return (
        <div>
            {
                todolist.map(item => {
                    return <li key={item.id}>
                        <label>
                            <input type="checkbox" />
                            <span>{item.title}</span>
                        </label>
                        <button className="btn btn-danger" >删除</button>
                    </li>
                })
            }
        </div>
    )
}

3.2 新增一个任务

直接修改TodoHeader.jsx文件中的内容

import React, { useState } from 'react'
import './TodoHeader.css'
import { useDispatch } from 'react-redux'
import { addTo } from '../../../store/modules/Todo'
import { nanoid } from 'nanoid'
export default function TodoHeader() {
    //可以使用受控组件或者是非受控组件写法来获取文本框中的数据
    let [title, setTitle] = useState('');
    let dispatch = useDispatch();
    let add = (e) => {
        setTitle(e.target.value);
    }
    let keyupFun = (e) => {
        //判断键盘按键是否是回车键
        if (e.keyCode === 13) {
            //将任务直接添加到状态中
            dispatch(addTo({
                id: nanoid(),
                title,
                done: false
            }))
            //清空文本框
            setTitle('');
        }

    }
    return (
        <div className="todo-header">
            <input type="text" value={title} placeholder="请输入你的任务名称,按回车键确认"
                onChange={add} onKeyUp={keyupFun}
            />
        </div>
    )
}

3.3 点击复选框修改某一个任务的状态

  • 现在store/modules/Todo.js文件中新增一个方法
//点击复选框转换状态  {id:xxx,done:xx}
checkTodo(state, { payload }) {
    //思路:循环找和id一样的任务做状态的修改
    state.map(item => {
        if (item.id == payload.id) {
            item.done = payload.done;
        }
    })
}

不要忘记导出

export let { addTo, checkTodo } = Todo.actions;
  • 修改TodoItem.jsx
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { checkTodo } from '../../../store/modules/Todo'
export default function TodoItem() {
    let { todolist } = useSelector(state => state);
    let dispatch = useDispatch();
    let changeDone = (id, e) => {
        //修改状态
        dispatch(checkTodo({ id, done: e.target.checked }));
    }
    return (
        <div>
            {
                todolist.map(item => {
                    return <li key={item.id}>
                        <label>
                            <input type="checkbox" checked={item.done} onChange={e => changeDone(item.id, e)} />
                            <span className={item.done ? 'done' : ''}>{item.title}</span>
                        </label>
                        <button className="btn btn-danger" >删除</button>
                    </li>
                })
            }
        </div>
    )
}

3.4 删除某一个任务

  • 在store/modules/Todo.js中新增一个删除单条的方法
//声明一个可以删除单条任务的方法  
deleteOneTodo(state, { payload }) {
    //思路:循环状态数据只要是符合传递的id那一条删掉
    state.forEach((item, index) => {
        if (item.id == payload) {
            state.splice(index, 1);
        }
    })
}

不要忘记导出

export let { deleteOneTodo } = Todo.actions;
  • 在TodoItem.jsx文件中导入
import { deleteOneTodo } from '../../../store/modules/Todo'
  • 给删除按钮添加点击事件并传递id参数
<button className="btn btn-danger" onClick={e => deleteTodo(item.id)}>删除</button>

  • 点击点击方法
let deleteTodo = (id) => {
    //删除
    dispatch(deleteOneTodo(id))
}

3.5 实现所有任务的全选与反选

  • 在store/modules/Todo.js中新增一个控制全选与反选的方法
//声明一个可以实现全选与反选的方法  payload只需要全选框的选中状态值,要么true,要么false
checkAllTodo(state, { payload }) {
    //思路:给每一个任务的状态都修改成payload中传入的状态值
    state.map(item => {
        item.done = payload
    })
}

不要忘记导出

export let { checkAllTodo } = Todo.actions;

  • 在TodoFooter.jsx文件中导入
import { useDispatch, useSelector } from 'react-redux'
import { checkAllTodo } from '../../../store/modules/Todo'
  • 给复选框添加事件函数
<input type="checkbox" onChange={checkAll} checked={
    Todolist.every(item => item.done) && Todolist.length > 0
} />
  • 声明函数,修改状态
let { Todolist } = useSelector(state => state);
let dispatch = useDispatch();
let checkAll = (e) => {
    dispatch(checkAllTodo(e.target.checked));
}

3.6 统计任务数量

  • 在TodoFooter.jsx文件中导入useSelector
import { useSelector } from 'react-redux'
  • 调用获取todolist中的数据
let { todolist } = useSelector(state => state);
  • 读取数据
<span>已完成{todolist.filter(item => item.done).length}</span> / 全部{todolist.length}

3.7 清除已完成任务

  • 在store/modules/Todo.js中新增一个方法
//声明一个清除所有已完成的方法
clearAllTodo(state) {
    //思路:循环所有的任务,只要是选中状态的,就删除
    for (let i = 0; i < state.length; i++) {
        if (state[i].done) {
            state.splice(i, 1);
            i--;
        }
    }
}

不要忘记导出

export let { clearAllTodo } = Todo.actions;
  • 在TodoFooter.jsx文件中导入
import {  clearAllTodo } from '../../../store/modules/Todo'
  • 给按钮添加点击事件
<button className="btn btn-danger" onClick={clearAll}>清除已完成任务</button>
  • 声明函数,修改状态数据
let clearAll = () => {
    dispatch(clearAllTodo());
}

3.8 异步实现获取任务状态数据

  • 利用json-server启动服务
json-server --watch(-w) db.json --port(-p) 3001
  • 清空初始状态数据(因为要来自于服务中)
initialState: []
  • 在store/modules/Todo.js中新增方法
//添加方法
setTodo(state, { payload }) {
    //通过push方法向状态数据进行追加
    state.push(...payload);
}

在定义一个异步处理的方法

import axios from '../../Component/utils/http'
export let aysncgetTodo = () => {
    return async dispatch => {
        //添加异步任务
        let result = await axios.get('/todos');
        //更新状态数据
        dispatch(setTodo(result.data))
    }
}
  • 在TodoList.jsx文件中导入
import React, { useEffect } from 'react'
import { aysncgetTodo } from '../../store/modules/Todo'
import { useDispatch } from 'react-redux'
let dispatch = useDispatch();
useEffect(() => {
    dispatch(aysncgetTodo());
}, [])

3.9 异步实现新增任务状态数据

  • 在store/modules/Todo.js中新增方法
export let asyncaddTodo = (payload) => {
    return async dispatch => {
        //添加异步任务
        let result = await axios.post('/todos', payload);
        //更新状态数据
        dispatch(addTo(result.data))
    }
}
  • 在TodoHeader.jsx组件中的addTodo函数导入替换成asyncaddTodo
import { asyncaddTodo } from '../../../store/modules/Todo'

将函数的调用也替换

let keyupFun = (e) => {
    //判断键盘按键是否是回车键
    if (e.keyCode === 13) {
        //将任务直接添加到状态中
        dispatch(asyncaddTodo({
            id: nanoid(),
            title,
            done: false
        }))
        //清空文本框
        setTitle('');
    }
}

3.10 异步实现更新单条任务状态数据

  • 在store/modules/Todo.js中新增方法
export let asyncUpdateTodo = (payload) => {
    return async dispatch => {
        //添加异步任务
        let result = await axios.patch(`/todos/${payload.id}`, { done: payload.done })
        //更新状态数据
        dispatch(checkTodo(result.data))
    }
}
  • 在TodoItem.jsx组件中的checkTodo函数导入替换成asyncUpdateTodo
import { deleteOneTodo, asyncUpdateTodo } from '../../../store/modules/Todo'

将函数的调用也替换

let changeDone = (id, e) => {
    //修改状态
    dispatch(asyncUpdateTodo({ id, done: e.target.checked }));
}

3.11 异步实现删除单条任务状态数据

  • 在store/modules/Todo.js中新增方法
export let asyncdeleteTodo = (payload) => {
    return async dispatch => {
        //添加异步任务
        let result = await axios.delete(`/todos/${payload}`)
        console.log(result)
        //更新状态数据
        dispatch(deleteOneTodo(payload))
    }
}
  • 在TodoItem.jsx组件中的deleteOneTodo函数导入替换成asyncdeleteTodo
import { asyncdeleteTodo, asyncUpdateTodo } from '../../../store/modules/Todo'

将函数的调用也替换

let deleteTodo = (id) => {
    //删除
    dispatch(asyncdeleteTodo(id))
}

四、Redux梳理总结

  1. action
    1. 本身就是一个普通对象 {type: 'add', payload: 任意类型的值}
  2. reducer
    1. 本身是一个函数. 加工厂函数, 与原生的 reduce 函数功能很像
    2. 作用: 就是根据 action 对象对保存的状态进行更新
  3. store
    1. 仓库对象
  4. dispatch
    1. 本身是一个函数. 是属于 store 对象的方法
    2. 作用: 分发任务,
    3. 参数: action 对象
      1. dispatch({type: ‘add’, payload: 1});
      2. dispatch(函数类型的值) => 异步的状态更新

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

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

相关文章

霍夫变换车道线识别-车牌字符识别代码(matlab仿真与图像处理系列第5期)

1.车道线识别 当使用霍夫变换进行车道线识别时,可以按照以下步骤来编写 MATLAB 代码: 读入图像:使用imread函数读取包含车道线的图像。image = imread(lane_image.jpg);图像预处理:为了减少噪音和突出车道线,可以对图像进行预处理。通常,可以采用以下步骤:将图像转换为…

kafka入门,Kafka Broker工作流程、Broker重要参数(十一)

Zookeeper 存储的 Kafka 信息 在zookeeper的服务端存储的Kafka相关信息 1&#xff09;/kafka/brokers/ids [0,1,2] 记录有哪些服务器 2&#xff09;/kafka/brokers/topics/first/partitions/0/state 记录谁是leader,有哪些服务器可用 3&#xff09;/kafka/controller 辅助选举l…

Java中的「接口」到底是什么?

&#x1f482; 个人网站:【海拥】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录 前言什么是接口接口的定…

浅浅的复习一下sql

DISTINCT 语法&#xff1a; SELECT DISTINCT 列名称 FROM 表名称1、现在有一个表如下&#xff1a; 2、执行sql语句-1 SELECT DISTINCT ename,email FROM emp 结果&#xff1a; 说明&#xff1a;由于小刘的ename和email重复了&#xff0c;所以结果只显示一次&#xff01; 3…

面试最爱问的浏览器的缓存机制问题

老规矩&#xff0c;想要了解学会一项技术&#xff0c;先从定义下手&#xff01; 浏览器的缓存的定义 浏览器的缓存是指浏览器在处理网络资源时&#xff0c;将这些资源存储在本地磁盘或内存中&#xff0c;并在后续的请求中重复使用这些缓存的资源。它旨在提高网页加载速度、减少…

AI画图——十二生肖

适当放下代码&#xff0c;有益身心健康。 AI绘画&#xff0c;码农必备&#xff0c;超解压。 多少没被和谐算多少~~~ 子鼠 丑牛 寅虎 卯兔 辰龙 巳蛇 午马 未羊 申猴 酉鸡 戌狗 亥猪

在期刊的参考文献中如何设置引用书中的一个章节

前言&#xff1a; 在bib文件中&#xff0c;使用book形式来引用书中的章节或文章。因为有些书籍是按照章节进行排列的&#xff0c;有些书籍收集了相关主题下的论文&#xff0c;当我们想要引用书中的要给章节或者书中的某篇文章的时候&#xff0c;我们该如何做呢&#xff1f; 下…

mysql不同隔离级别事务插入数据

文章目录 前言一、问题二、测试2.1.RR级别&#xff0c;mysql默认级别2.1.1 打开一个mysql窗口&#xff0c;事务A2.1.2 打开另一个窗口&#xff0c;事务B2.1.3 提交事务A&#xff0c;再看结果如下 2.2 READ-COMMITTED 级别下测试2.2.1修改数据库的my.ini文件修改隔离级别2.2.2 查…

国产MCU-CW32F030开发学习-OLED模块

国产MCU-CW32F030开发学习-OLED模块 硬件平台 CW32_48F大学计划板CW32_IOT_EVA物联网开发评估套件0.96 IIC oled模块 软件平台 Keil MDK 5.31IAR串口调试助手 IIC总线 处理器和芯片间的通信可以形象的比喻成两个人讲话&#xff1a;1、你说的别人得能听懂&#xff1a;双…

【AUTOSAR】AUTOSAR开发工具链(五)----polyspace-bug-finder 简单操作说明

1、打开polyspace-bug-finder&#xff0c;新建工程文件&#xff1a;File New Project&#xff0c;命名&#xff0c;选择保存路径&#xff0c;然后点击Next。 2、找到需要检测的文件&#xff0c;然后点击“Add Source Files” Finish 3、在Configuration左边窗口点击“…

HotSpot 虚拟机对象探秘

HotSpot 虚拟机对象探秘 对象的内存布局 在 HotSpot 虚拟机中&#xff0c;对象的内存布局分为以下 3 块区域&#xff1a; 对象头&#xff08;Header&#xff09; 实例数据&#xff08;Instance Data&#xff09; 对齐填充&#xff08;Padding&#xff09; 对象头 对象头记录了…

FreeRTOS_调度器开启和任务相关函数详解

目录 前言 1. 调度器开启过程分析 1.1 指令集 1.2 任务调度器开启函数分析 1.2.1 内核相关硬件初始化函数分析 1.2.2 使能 FPU 函数分析 1.2.3 启动第一个任务 1.2.4 SVC 中断服务函数 1.2.5 空闲任务 2. 任务创建过程分析 2.1 任务创建函数分析 2.2 任务初始化函…

K8S之可用年限修改

K8S之可用年限修改 1. 查看证书有效期&#xff1a; [rootmaster1 kubernetes]# kubeadm alpha certs check-expiration由上图可见&#xff0c;除了ca根证书&#xff0c;其他证书有效期都是1年。 2. go环境部署&#xff1a; //下载go二进制包 wget https://studygolang.com/…

基于matlab使用 HOG 功能和多类 SVM 分类器对数字进行分类(附源码)

一、前言 此示例说明如何使用 HOG 功能和多类 SVM 分类器对数字进行分类。 对象分类是许多计算机视觉应用中的一项重要任务&#xff0c;包括监控、汽车安全和图像检索。例如&#xff0c;在汽车安全应用程序中&#xff0c;您可能需要将附近的对象分类为行人或车辆。无论要分类…

CentOS Linux的最佳替代方案(一)_Rocky Linux OS 8.6基础安装教程

CentOS Linux的最佳替代方案&#xff08;一&#xff09;_Rocky Linux OS 8.6基础安装教程 一 Rocky Linux介绍和发展历史 Rocky Linux 官网&#xff1a;https://rockylinux.org/ 在CentOS官方宣布停止Centos的维护之后&#xff0c;Centos的创始人Gregory Kurtzer宣布启动新的…

2023年上半年部分团队的总结

&#xff08;目前还是草稿版本&#xff09; 写作&#xff0c;慢思考&#xff1a; 软件团队每天有繁忙的工作&#xff0c;有很多待办事项&#xff0c;会议&#xff0c;口头交流&#xff0c;线上的 bug 要处理&#xff0c;报表要生成和解释… … 一个月过去了&#xff0c;正想总…

数字化远传表计实验的记录

国网去年4月份出了一个《智慧变电站技术规范第 4 部分&#xff1a;数字化远传表计&#xff08;试行版&#xff09;》&#xff0c;对SF6数字化密度表、避雷器数字化泄漏电流表、变压器数字化油温计等设备数据通信做了要求。数字化感知单元与监测模块之间宜采用有线通信方式&…

深度学习:什么是多层感知机(神经网络)

文章目录 1.神经网络2.反向传播算法3.激活函数4.损失函数5.神经网络的使用场景参考 1.神经网络 神经网络是一种计算模型&#xff0c;它受到人脑神经元之间连接和信息处理方式的启发。它由许多简单的处理单元&#xff08;称为神经元或节点&#xff09;组成&#xff0c;并通过这…

innovus/ICC2:如何copy metal shape/via

如题,两家工具复制metal shape和via都可以用快捷键C,其中innovus还支持在复制过程中按"F3",调整复制的次数。 这里主要说一下命令: ICC2: copy_objects -x_pitch/y_pitch $pitch \ -x_times/-y_times $times \ [get_selection]/[get_shapes xx]/[get_v…

QWidget的相关API函数

目录 QWidget的相关API函数 设置父对象 窗口位置 窗口尺寸 窗口标题和图标 信号 槽函数 示例1&#xff08;设置窗口大小&#xff09;&#xff1a; 示例2&#xff08;移动窗口&#xff0c;修改窗口&#xff0c;获取窗口位置信息&#xff09;&#xff1a; 示例3 &#x…