从0开始搭建react项目(函数组件)

news2024/11/18 17:26:27

目录

项目搭建步骤

本地开发环境

脚手架构建项目

关联Git仓库

strictMode 严格模式

路由配置

路由传参

路由守卫

数据绑定

生命周期

父子组件通信

redux持久化

安装Sass

安装postcss-pxtorem(移动端项目)

安装axios

环境变量

本地代理

项目部署

nginx配置

jenkins自动化部署

自由风格配置

流水线配置

灰度部署方案


项目搭建步骤

本地开发环境

安装nodejs,node版本建议大于16.0.0

Download | Node.js

脚手架构建项目

官网:快速入门 – React

npx create-react-app my-app

关联Git仓库

初始化后的项目关联远程git仓库

strictMode 严格模式

index.js 中包裹了一层 React.strictMode,开发环境严格模式,用于校验页面方法,在开发模式会调用两次页面方法,建议删除

root.render(
  // <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  // </React.StrictMode>
)

路由配置

1、安装react-router-dom

npm i react-router-dom -S

2、新增 / src / router / index.js,可配置路由懒加载

import { lazy } from 'react'
import { Navigate } from 'react-router'

// 非懒加载的路由,组件及引入的css会打包到全局
import Index from '../views/index'
import Login from '../views/login'
// 以下为懒加载路由,访问到路由才会加载页面代码,组件及引入的css也是访问时才加载生效
const My = lazy(() => import('../views/my'))
const Profile = lazy(() => import('../views/my/profile'))
const Order = lazy(() => import('../views/my/order'))

//创建路由
const routes = [
  {
    path: '/',
    meta: {
      title: '首页',
    },
    exact: true,
    element: <Index />,
  },
  {
    path: '/login',
    element: <Login />,
    meta: {
      title: '登录',
    },
  },
  {
    path: '/my',
    element: <My />,
    exact: true,
    meta: {
      title: '我的',
    },
    children: [
      {
        path: '/my/profile',
        element: <Profile />,
        meta: {
          title: '我的-主页',
        },
      },
      {
        path: '/my/order',
        element: <Order />,
        meta: {
          title: '我的-订单',
        },
      }
    ]
  },
  {
    // 未匹配到全部跳转首页
    path: '*',
    element: <Navigate to="/" />,
  },
]

export default routes

3、修改index.js

...
import { BrowserRouter } from 'react-router-dom'

root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
)

4、修改App.js

import {useRoutes} from "react-router-dom"
import router from "./router/index"
function App() {
  return useRoutes(router)
}
export default App;

路由传参

1、search方式

// 传参页面
<Link to={`/my/order?id=123`}>订单</Link>

// 接收参数页面
import { useSearchParams } from "react-router-dom"
export default function Order() {
  // 获取params参数
  const [search] = useSearchParams()
  const id = search.get('id')
  return (
    <div>订单id为:{ id }</div>
  )
}

2、动态路由方式

// 路由配置 /router/index.js
path: '/my/order/:id'

// 传参页面
<Link to={`/my/order/123`}>订单</Link>

// 接收参数页面
import { useParams } from "react-router"
export default function Order() {
  // 获取params参数
  const params = useParams()
  const id = params.id
  return (
    <div>订单id为:{ id }</div>
  )
}

路由守卫

1、新建 / src / router / beforeEnter.js

import { useLocation, useNavigate, useRoutes } from 'react-router-dom'
import { useEffect } from 'react'
const BeforeEnter = ({ routers }) => {
  // 1.在路由数组中找当前页面路由的对应路由项
  const fineRouter = (routes, path) => {
    for (let item of routes) {
      if (item.path === path) return item
      if (item.children) {
        // 如果有子路由,查找子路由
        // 注意:1)因为传入的path是当前完整路径,子路由的path也需要设置完整的路径,例如:/my/order,而不是 order
        //      2)不可配置动态参数路由,例如:/product/:id
        return fineRouter(item.children, path)
      }
    }
    return null // 没有找到录音配置,返回null,由judgeRouter方法跳转404页面
  }
  // 2.路由守卫判断
  const judgeRouter = (location, navigate) => {
    const { pathname } = location
    // 2.1路由数组找路由项
    const findRoute = fineRouter(routers, pathname)
    // 2.2没找到,说明没有这个路由,直接404
    if (!findRoute) {
      navigate('/404')
      return
    }
    // 2.3更新页面标题
    if (findRoute?.meta?.title) {
      document.title = findRoute.meta.title
    }
    if (findRoute.auth) {
      // 用户未登陆,挑战登陆页面
      if (!localStorage.getItem('user')) navigate('/login')
    }
  }
  // 3.基于useEffect监听页面路由改变。然后组件重新加载,又重新校验权限。
  const navigate = useNavigate()
  const location = useLocation()
  const router = useRoutes(routers)
  useEffect(() => {
    // 路由守卫判断
    judgeRouter(location, navigate)
  })
  return router
}
export default BeforeEnter

2、修改App.js

import BeforeEnter from "./router/beforeEnter"
import router from "./router/index"

function App() {
  return <BeforeEnter routers={router} />
}
export default App;

数据绑定

1、表单数据

import { useNavigate } from 'react-router-dom'
export default function Login() {
  const navigate = useNavigate()
  // 声明账号、密码变量
  let account, password
  // form提交
  function loginSubmit(e) {
    // 阻止form提交事件
    if (e) e.preventDefault()
    // 通过ref方法获取到输入框内容
    if (account.value === 'xxx' && password.value === 'xxx') {
      // 登录成功本地存储登录状态
      localStorage.setItem('isLogin', true)
      // 登录成功跳转我的页面
      navigate('/my', {
        replace: true
      })
    }
  }
  return (
    <div>
      <h4>登录页面</h4>
      <form onSubmit={loginSubmit}>
        <p>账号</p>
        <input type="text" ref={(input) => (account = input)} />
        <p>密码</p>
        <input type="password" ref={(input) => (password = input)} />
        <button type="submit">提交</button>
      </form>
    </div>
  )
}

2、页面渲染

通过useState方法声明变量,变量更新时才能同步渲染到页面

import React, { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'

export default function ProductList() {
  const navigate = useNavigate()
  // 声明商品列表数据
  const [productList, setProductList] = useState([])
  //  添加商品
  // 注意:不可以对原变量productList做push操作
  const addProduct = () => {
    const list = productList.concat([
      {
        id: 1,
        name: '新商品'
      }
    ])
    setProductList(list)
  }
  // 删除商品
  // 注意:不可以对原变量productList做splice操作
  const deleteItem = (product) => {
    setProductList(productList.filter((item) => item.id !== product.id))
  }
  // 跳转商品详情
  const goDetail = (item) => {
    navigate('/productDetail?id=' + item.id)
  }
  return (
    <div>
      <h4>商品列表页</h4>
      <button onClick={() => addProduct()}>添加商品</button>
      <ul>
        {productList.map((item, index) => {
          return (
            <li key={index}>
              <h5>商品名称:{item.name}</h5>
              <button onClick={() => goDetail(item)}>跳转详情页</button>
              <button onClick={() => deleteItem(item)}>删除</button>
            </li>
          )
        })}
      </ul>
    </div>
  )
}

生命周期

使用useEffect方法,第一个参数传入一个方法,第二个可选参数传入[],如果不写第二个参数,则页面更新就会执行

import React, { useState, useEffect } from 'react'

export default function ProductList() {
  const [productList, setProductList] = useState([]);
  // 获取商品列表接口
  const getList = async () => {
    const res = await React.$http({
      url: '/m1/2235670-0-default/article/list',
    })
    setProductList(res.productList)
  }
  // useEffect hook,可作为生命周期方法使用
  // 第二个可选参数传入[],进入页面只执行一次
  useEffect(()=>{
    console.log('进入列表页')
    getList()
  }, [])
  return (
    <div>...</div>
  )
}

父子组件通信

1、父组件

import React, { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
// 引入子组件
import ProductItem from '../components/productItem'

export default function ProductList() {
  const navigate = useNavigate()
  const [productList, setProductList] = useState([]);
  // 声明删除商品方法,注册子组件时传入
  const deleteItem = (product) => {
    setProductList(productList.filter(item => item.id !== product.id))
  }
  // 声明跳转方法,注册子组件时传入
  const goDetail = (item) => {
    navigate('/productDetail?id='+item.id)
  }
  return (
    <div>
      <h4>商品列表页</h4>
      <ul>
        {
          productList.map((item, index) => {
            return (
              <li key={index}>
                <ProductItem item={ item } goDetail={ goDetail } deleteItem={ deleteItem } />
              </li>
            )
          })
        }
      </ul>
    </div>
  )
}

2、子组件

// 接收父组件传入的变量和方法,可直接调用
export default function ProductItem({ item, goDetail, deleteItem }) {
  return (
    <div className="flex product-item">
      <div>
        <h5>{ item.name }</h5>
        <button onClick={() => goDetail(item)}>查看详情</button>
        <button onClick={() => deleteItem(item)}>删除</button>
      </div>
    </div>
  )
}

redux持久化

1、新建 src / store / reducer.js,配置state数据

// 定义state数据
const defaultState = {
  inputValue: 0, // 输入框内容
  isLogin: false // 登录状态
}
function reducer(state = defaultState, action) {
  const newState = JSON.parse(JSON.stringify(state)) // 深度拷贝state
  switch (action.type) {
    case 'changeInput':
      newState.inputValue = action.value
      break
    case 'changeIsLogin':
      newState.isLogin = action.value
      break
    default:
  }
  return newState
}
export default reducer

2、新建 src / store / index.js,配置state数据

// 因为 redux已经不推荐使用 createStore()创建数据仓库了,如果我们继续使用,需要引入具有标识的 legacy_createStore
import { legacy_createStore as createStore } from 'redux';
// 持久化插件
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import reducer from './reducer';

// 配置持久化插件
const persistConfig = {
  key: 'root',
  storage,
  // blacklist: ['inputValue'], // 黑名单,例:inputValue不会被持久化
  whitelist: ['isLogin'] // 白名单,例:只有isLogin会被持久化
}

const persistedReducer = persistReducer(persistConfig, reducer)

// 创建数据存储仓库
const store = createStore(persistedReducer,
  // 浏览器redux devTools添加以下配置
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

const persistor = persistStore(store);

export {
  store,
  persistor
}

3、修改index.js,全局配置redux

import React, { Suspense } from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from 'react-router-dom';

// redux
import { store, persistor } from './store'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      {/* 持久化redux,在路由懒加载时,无法获取数据,所以添加Suspense Loading */}
      <Suspense fallback={<h2>Loading..</h2>}>
        {/* history模式路由 */}
        <BrowserRouter>
          <App />
        </BrowserRouter>
      </Suspense>
    </PersistGate>
  </Provider>
);

4、页面使用

import { useDispatch, useSelector } from "react-redux"

export default function Pdp() {
  // 声明输入框
  let textValue

  // 获取redux中的inputValue数据
  const inputValue = useSelector(state => state.inputValue)
  
  // 修改redux数据
  const dispatch = useDispatch()
  const changeInputFun = () => {
    dispatch({ type: 'changeInput', value: textValue.value })
  }
  return (
    <div>
      <span>redux值为:{inputValue}</span>
      <input ref={(input) => (textValue = input)} />
      <button onClick={() => changeInputFun()}>修改</button>
    </div>
  )
}

安装Sass

npm i sass -D

使用:将css文件换为scss文件即可

安装postcss-pxtorem(移动端项目)

移动端适配,兼容不同分辨率的手机

npm i @craco/craco postcss-pxtorem -D
npm i amfe-flexible -S

使用craco启动服务,项目根目录新增 craco.config.js

module.exports = {
  style: {
    postcss: {
      mode: 'extends',
      loaderOptions: {
        postcssOptions: {
          ident: 'postcss',
          plugins: [
            [
              'postcss-pxtorem',
              {
                rootValue: 75, // 根元素字体大小
                propList: ['*'],
                minPixelValue: 2 // 最小px为2,如果设置1px则不转rem
              }
            ]
          ]
        }
      }
    }
  }
}

在index.js引入amfe-flexible

import 'amfe-flexible'

修改package.json的script命令,将 react-scripts 替换为 craco

"scripts": {
  "start": "craco start",
  "build": "craco build",
  "test": "craco test",
  "eject": "craco eject"
}

安装axios

官网:axios

npm i axios -S

封装axios方法,新建/ src / utils / request.js文件

import axios from 'axios'

const service = axios.create({
  // process.env.NODE_ENV 判断是否为本地环境
  baseURL: process.env.NODE_ENV === 'development' ? '/api' : 'https://www.baidu.com',
  timeout: 30000
})

/* 请求拦截器 */
service.interceptors.request.use(
  (config) => {
    // 登录状态鉴权
    // if (token) {
    //   config.headers.Authorization = `Bearer ${token}`;
    // }
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

/* 响应拦截器 */
service.interceptors.response.use(
  (response) => {
    const { code, message, data } = response.data
    // 根据自定义错误码判断请求是否成功
    if (code === '0') {
      // 将组件用的数据返回
      return data
    } else {
      // 处理业务错误。
      return Promise.reject(new Error(message))
    }
  },
  (error) => {
    // 处理 HTTP 网络错误
    let message = ''
    // HTTP 状态码
    const status = error.response?.status
    switch (status) {
      case 401:
        message = 'token 失效,请重新登录'
        // 这里可以触发退出的 action
        break
      case 403:
        message = '拒绝访问'
        break
      case 404:
        message = '请求地址错误'
        break
      case 500:
        message = '服务器故障'
        break
      default:
        message = '网络连接故障'
    }
    console.log(message)
    return Promise.reject(error)
  }
)

/* 导出封装的请求方法 */
export const http = (options) => {
  return new Promise((resolve, reject) => {
    // 方法一:get和delete请求,将请求体转换为queryString形式拼接在url
    // if (!options.method || options.method === 'get' || options.method === 'delete') {
    //   if (options.data) {
    //     options.url = options.url + '?' + new URLSearchParams(options.data).toString()
    //   }
    // }

    // 方法二:get和delete请求,使用params参数传参,post和put使用data参数
    const serviceOpt = {}
    if (!options.method || options.method === 'get' || options.method === 'delete') {
      serviceOpt.params = options.data
    } else {
      serviceOpt.data = options.data
    }
    service({
      method: options.method || 'get',
      url: options.url,
      ...serviceOpt
    })
      .then((res) => {
        resolve(res)
      })
      .catch((err) => {
        reject(err)
      })
  })
}

使用

import { http } from '@/utils/request'

const res = await http({
  url: '/get/product/list',
  // method: 'get',
  data: {
    id: 1
  }
})
console.log(res)

环境变量

1、获取系统环境变量

const NODE_ENV = process.env.NODE_ENV

2、获取自定义环境变量

在create-react-app中获取npm自定义变量,可以使用process.env对象。在package.json中设置变量后,可以在代码中使用process.env.VARIABLE_NAME来获取变量的值。

"scripts": {
  "start-test": "REACT_APP_ENV=test react-scripts start",
  "start-dev": "REACT_APP_ENV=dev react-scripts start"
}

在业务代码中获取,比如:/ src / index.js

const ENV = process.env.REACT_APP_ENV;

 注意:变量名必须以REACT_APP_开头,这是create-react-app的约定

本地代理

新建 / src / setupProxy.js

const { createProxyMiddleware } = require('http-proxy-middleware')

module.exports = function (app) {
  app.use(
    createProxyMiddleware('/api', {
      // 使用 /api 前缀代理配置
      target: 'https://mock.apifox.cn', // 跨域地址
      changeOrigin: true, // 控制服务器收到的请求头中host的值
      pathRewrite: {
        '^/api': '',
      },
    })
  )
}

项目部署

nginx配置

Apache,Nginx部署vue/react项目_apached发布 react_不求甚解bc的博客-CSDN博客

jenkins自动化部署

自由风格配置

jenkins部署vue/react项目_jenkins部署vue项目_不求甚解bc的博客-CSDN博客

jenkins分环境部署vue/react项目_不求甚解bc的博客-CSDN博客

流水线配置

jenkins流水线部署H5项目_jenkins部署h5_不求甚解bc的博客-CSDN博客

灰度部署方案

web前端灰度部署_不求甚解bc的博客-CSDN博客

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

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

相关文章

直播预告:CoremailHVV经验分享与重保整体解决方案发布

面对更具有目的性、针对性的网络攻击压力&#xff0c;重保既是抵抗攻击的重要举措&#xff0c;也是数字经济时代下企业发展的刚需。 正值重保期&#xff0c;企业在面对多样化的攻击手段、持续化的攻击行为、剧增化的攻击危害&#xff0c;应该如何应对重保大考&#xff1f; 6月1…

供应链安全

供应链安全 目录 文章目录 供应链安全目录本节实战可信任软件供应链概述构建镜像Dockerfile文件优化镜像漏洞扫描工具&#xff1a;Trivy检查YAML文件安全配置&#xff1a;kubesec准入控制器&#xff1a; Admission Webhook准入控制器&#xff1a; ImagePolicyWebhook关于我最后…

openpnp - 底部相机支架的制作

文章目录 openpnp - 底部相机支架的制作概述END openpnp - 底部相机支架的制作 概述 前几天总结了底部相机校验通不过的原因(openpnp - 底部相机矫正(subject not found)的原因总结), 并且可以校验通过了. 好景不长, 在校验通过的第三天(中间再穿插做其他事情), 从头做了一次…

【ArcGIS Pro二次开发】(38):清理字段值(空格、空值)

由于一些不规范的输入&#xff0c;或是其它数据转换而来&#xff0c;要素类或者独立表的字段值经常含有空值、空格等影响数据质量的内容。 这个工具的目的就是清理、转换这些字段内容&#xff0c;提高数据质量。 一、要实现的功能 如上图所示&#xff0c;点击【清洗字段值】按…

springboot+vue+java仓库管理系统_0r36w

部门管理员&#xff1a; 申购入库&#xff1a;发起申购&#xff0c;进行入库申请。 调拨申请&#xff1a;发起资产调拨的申请以及查看申请的详情信息。 出库管理&#xff1a;查看调拨的详情信息&#xff0c;可以进行资产的申请报废以及申请维修。 资产报废查询&#xff1a;查看…

薛定谔maestro 安装

【1】先删除之前不能用的文件包 【2】tar -xvf 解压包 进行解压 【3】cd 解压出来的文件下 【4】sudo ./INSTALL 【也可以不用sudo&#xff0c;我的电脑不知道上面问题&#xff0c;需要用sudo&#xff0c;否则在之后创建生成文件夹的时候没有权限】 【5】根据操作一步一步…

电子行业 K 公司对接 Nexperia EDI 项目案例

项目背景 Nexperia 是一家全球领先的半导体制造商&#xff0c;专注于提供高性能、高可靠性和创新性的半导体解决方案。公司成立于2017年&#xff0c;是前飞思卡尔半导体业务的一部分&#xff0c;并在全球范围内拥有多个设计、研发和生产基地。 Nexperia 使用 EDI&#xff08;…

【VMware】虚拟机安装centos7

目录 一、创建虚拟机 1、自定义 2、选择需要安装的操作系统 3、选择虚拟机安装位置 4、选择处理器配置&#xff08;可先默认&#xff09; 5、设置虚拟内存&#xff08;一般4096&#xff09; 6、选择网络连接方式 7、选择I/O控制器 8、选择磁盘类型 9、选择磁盘 10、指定磁盘容…

真刑!几行代码端了整个教务系统。。

今天给大家伙分享一个网络安全的案例&#xff0c;程序员和网安同学都可以看看&#xff0c; 前言&#xff1a;本文中涉及到的相关漏洞已报送厂商并得到修复&#xff0c;本文仅限技术研究与讨论&#xff0c;严禁用于非法用途&#xff0c;否则产生的一切后果自行承担 漏洞成因 事…

佩戴舒适的蓝牙耳机哪款比较好用?佩戴舒适度最好的蓝牙耳机推荐

​关于蓝牙耳机佩戴舒适度及音质表现的问题&#xff0c;经常有很多小伙伴在问&#xff0c;或许大家更习惯用价格去界定一个蓝牙耳机的定位。本篇文章主要给大家介绍哪款蓝牙耳机比较好用&#xff0c;很值得入手的蓝牙耳机&#xff0c;一起来看看吧。 一、南卡OE蓝牙耳机&#…

知识小结——HTTP协议相关

目录 TCP/IP URI / URL HTTPS 总结时间&#xff1a; TCP/IP协议簇 对TCP的理解 对UDP的理解 HTTP&#xff08;超文本传输协议&#xff09;是什么&#xff1f; HTTPS&#xff08;安全超文本传输协议&#xff09;是什么&#xff1f; HTTPS的特点&#xff1a; HTTPS协议…

【Linux】linux下使用命令修改jar包内某一个文件中的内容并重新运行jar程序

linux下使用命令修改jar包内某一个文件中的内容并重新运行jar程序 一、背景描述二、vi命令编辑三、启动程序四、拓展--启动脚本 一、背景描述 需求&#xff1a;发现线上的 iotp-irsb-server-v1.0.0.2.jar 包中配置文件的日志级别配置错误&#xff0c;需要在线修改jar包中文件的…

99.实战网页构建定价部分-第二节

上节课我们完成的定价页面是这样的 上节课我们完成的定价页面是这样的 ● 首先我们先给卡片加上背景颜色 .princing-plan {background-color: #fdf2e9;border-radius: 11px;padding: 4.8rem; }● 之后我们调整下框子的大小和位置 ● 接着我们给基础价格再调价一项&#x…

低代码开发平台介绍

低代码开发平台近两年发展迅猛&#xff0c;并迅速渗透到各个细分领域。本文简要介绍低代码开发的概念以及特性&#xff0c;并结合低代码开发的应用场景介绍两个低代码开发平台。 1、低代码开发概念 1.1 低代码开发介绍 低代码开发&#xff08;Low-code Development&#xff0…

SQL调优:让Java内存分担计算

作者: 剽悍一小兔 CSDN前端优质创作者&#xff0c;打破编程小说次元壁第一人《JavaScript百炼成仙》作者&#xff0c;专注Java硬核干货分享&#xff0c;分享创造快乐&#xff0c;技术成就梦想&#xff01; 我们在工作中&#xff0c;经常会因为一条慢sql调半天。这一节&#xff…

无线蓝牙耳机什么牌子好?八大真无线蓝牙耳机排名

蓝牙耳机作为当前热门的数码产品&#xff0c;无论何时都能用上&#xff0c;蓝牙耳机的快速发展逐渐的取代有线耳机&#xff0c;摆脱线条的束缚&#xff0c;更方便携带。当然&#xff0c;随着蓝牙耳机的设计各种各样&#xff0c;导致很多的小伙伴在选购耳机的时候&#xff0c;不…

简易协程工具【Wait! - Easy Coroutines】

Wait! - Easy Coroutines | Utilities Tools | Unity Asset StoreUse the Wait! - Easy Coroutines from Iterant Games on your next project. Find this utility tool & more on the Unity Asset Store.https://prf.hn/l/b3AQw5a 1、概述 Wait - Easy Coroutines&#…

chatgpt赋能python:建立Python文件的完整指南

建立Python文件的完整指南 如果您正在寻找一个易于学习和使用的编程语言&#xff0c;Python就是一个不错的选择。Python的第一印象常常让人感到吃惊&#xff0c;因为它的代码与许多编程语言相比要短得多&#xff0c;然而它的功能非常强大且使用范围广泛。在本文中&#xff0c;…

【位图布隆过滤器海量数据面试题】

文章目录 1 位图2 布隆过滤器 1 位图 首先我们来看看一个腾讯的面试题&#xff1a;给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中。 分析&#xff1a; 40亿个不重复整形数据&#xff0c;大概有160亿字节…

Linux---vim的使用

专栏&#xff1a;Linux 个人主页&#xff1a;HaiFan. 本章为大家带来Linux工具—vim Linux工具 关于rzszyumvim的基本概念vim的基本操作vim正常模式命令集vim末行模式命令集简单vim配置配置文件的位置常用配置选项 关于rzsz 这个工具用于windows机器和Linux机器通过Xshell传输…