React Native 开发心得分享

news2024/9/23 11:20:49

有一段时间没更新了,花了点时间研究了下 React Native(后续用 RN 简称),同时也用该技术作为我的毕设项目(一个校园社交应用,仿小红书),经过了这段时间的疯狂折腾,对 RN 生态有了一定的了解,我想是时候可以分享点一些东西了。

为什么是 RN 而不是 Flutter?

很简单,就是技术栈问题。从开发角度而言,尤其还是对于前端开发人员,会 JS 且搞过 React ,那 RN 上手就十分友好,最起码有关 React 社区的逻辑库或状态库是可以使用的。

虽说 Flutter 的性能是会比 RN 好上不少,但抛开需求不谈,与其比性能不如比开发速度。很显然开发 RN 的效率比 开发 Flutter 高上不少。况且真在意性能的话,那多半就不会考虑跨平台技术了,而是直接考虑原生开发了。

再从需求考量,我所编写的应用更偏向于内容展示的 app,而不是编写一个手机电池监控或者内存监控的app,如果是后者,那这时选择任何跨平台开发都没有意义,像这些系统级别的API在跨平台开发基本不太可能实现的。

对于这两个跨平台技术的选择,应该考虑自身需求、开发成本、技术选型,没有最好的只有最适合的。如果有的选择,谁不会选择原生开发是吧。

但凭我自己接触 RN 以来,国内的 RN 资源甚少,反倒是 Flutter 资源很多,并且从这些相关资料来看,确实 Flutter 优于 RN,但还是那句话,这里就不再过多赘述了。

是否有必要学 react-native?

先说一个结论:RN ≠ 原生,别指望会个 react 就能写出靠谱的原生应用。

就从我的开发经历来说,坑是真的多,但好在RN拥有庞大的线上社区,可以找到的几乎所有问题的答案。但国内的社区好像并不是很好,很多问题我都是在国外论坛中解决的。

如果你学习它是为了扩展其他平台的开发能力,那么还是可以学习一番的,会有另一番的收获。但如果学 RN 只是为了避免不用学 android 和 iOS 等原生技术就能写 app,那便不建议学习。抱着这心态的话前期开发可能不明显,但到了后面会踩很多坑,而且两眼一黑,因为你不懂 native 开发。

我的个人评价是 RN 只能作为 H5 手机页面运行在原生移动设备的一种展示形态。虽然本质不是,但其所展示的效果如同。RN 不仅仅只是 Web,但也止步于 Web。

顺带吐槽一番,React-Native 项目发布4年多了,还没有 1.0 版本么(¬_¬)

如果你想再继续了解 RN,那么就请往下看。

Expo

Expo 是基于 React Native 并整合大量常用的 native module(Expo SDK),像原生的功能如相册,相机,蓝牙等功能,在 expo 都是直接集成的,相当于封装原生的api,暴露给js调用。因此你不用去了解原生开发的许多知识和坑点,上手即用便可。本地配置好应用所需的环境,就直接直接运行 RN 项目,开发十分方便。

此外 Expo 还提供了 Expo Go App,只需要在你的移动端设备中安装它,启动开发服务器并生成 QR 码。在浏览器打开 snack.expo.dev ,点击 MyDevice,扫码并在 Expo app 中查看。

Untitled

会自动将该程序实时运行在你的移动端设备,意味着你更改代码也将会同步到Expo go 中。极大程度上提升 RN 的开发体验,尤其是在真机测试阶段。

Expo 官方还贴心的提供了云服务 Expo Application Services (EAS),意为这你可以你可以将你的 RN 项目在托管在云服务上,来执行构建与发布等流程。

总之如今开发 RN 请毫不犹豫的使用上 Expo。

开发中遇到的一些坑点

实际开发中所遇到的坑点远不止下述所说,这里只列举几个相对有代表,坑比较深的点。甚至有很多坑都不是前端方面的知识了。

在 pnpm 下无法启动 Android

错误提示:Error: Unable to resolve module ./nxode_modules/expo/AppEntry

解决方案:在项目根目录创建 .npmrc ,内容如下

shamefully-hoist=true
node-linker=hoisted

删除 node_modules 与 .expo 文件夹,重新安装依赖即可。

相关链接:https://github.com/expo/expo/issues/9591#issuecomment-1485871356

样式问题

在样式方面与传统的 Web 开发存在一定的区别。在 RN 中有两个主要组件,View 与 Text,可以理解为 Web 的 div 与 span。基本所有的 View 都是 flex 布局,想要让 View 组件占满通常不会使用 width: ’100%’ 或 height: ‘100%’,而是使用 flex: 1,例如一般都会带上这么一个样式。

<View style={{ felx: 1 }}>

如果样式问题就只是这样就好了,同一套样式在不同平台上所展示的效果都可能不大一样,尤其使用原生 Web 的样式,哪怕你用 style 编写,在 Web 网页也能成功显示效果,但是在 IOS 与 Android 中绝大多数情况下是不显示的。这会在后面介绍 Tailwindcss 相关库的时候会额外在提到一点。

文本必须要用 Text 包裹

如果不怎么做的话,会报错,如果只是这样倒还没什么。重点是错误提示并没有堆栈信息!就如下图所示

Untitled

这点对于开发体验而言并不友好。

模拟器无法请求本地 api

由于一开始是在 Web 端进行调试开发的,所以没留意到这个问题,直到切换到安卓模拟器之后发现模拟器无法请求本地后端服务,在IOS 端暂无这问题。因此需要做如下配置:

1、首先将模拟器内网切换到本地。

假设后端 api 地址为 [http://localhost:6001](http://localhost:6001),正常情况下,开发环境下的调试主机可以通过如下方式获取

import Constants from 'expo-constants'

const debuggerHost = Constants.expoConfig?.hostUri
// 192.168.123.233:8081

接着所要做的就是将 192.168.123.233:8081 替换成我们的目标端口 192.168.123.233:6001

这里以 axios 为例, 先为环境变量添加 EXPO_PUBLIC_API_URL=http://localhost:6001,具体替换的代码如下所示

export const client = axios.create({
  baseURL: getApiUrl(),
  timeout: 5000,
})

export function getApiUrl() {
  const apiUrl = process.env.EXPO_PUBLIC_API_URL
  return replaceLocalhost(apiUrl)
}

export function getLocalhost() {
  if (localhost !== undefined) return localhost

  const debuggerHost = Constants.expoConfig?.hostUri
  // 192.168.123.233:8081
  localhost = debuggerHost?.split(':')[0] ?? 'localhost'
  return localhost
}

export function replaceLocalhost(address: string) {
  const PROTOCOL = 'http:'
  const localhostRegex = new RegExp(`${PROTOCOL}\/\/localhost:`, 'g')
  return address.replace(localhostRegex, () => `${PROTOCOL}//${getLocalhost()}:`)
}

2、端口转发

此外还需要执行以下命令转发端口。

adb reverse tcp:6001 tcp:6001

此时安卓模拟器便可正常请求本地后端服务的资源,IOS 端并未有该问题。

组件库的选择

如今在 UI 的选择上,我是毫不犹豫选择 Tailwindcss,在 RN 使用 Tailwindcss 有两个库可以作为选择 nativewind 和 twrnc。

nativewind

nativewind 采用 Web 的 className 属性,其用法如同 Web 开发使用 Tailwindcss 的写法,这里便不过多展示了。

twrnc

twrnc 的写法则有些不同,需要通过 tw 包装,然后填写到 style 中,就如下图所示

import { View, Text } from 'react-native'
import tw from 'twrnc'

const MyComponent = () => (
  <View style={tw`p-4 android:pt-2 bg-white dark:bg-black`}>
    <Text style={tw`text-md text-black dark:text-white`}>Hello World</Text>
  </View>
)

:::danger 重点

但要值得注意的是,由于 RN 的组件样式中并不是完全兼容 Web 端,就比如说你想实现毛玻璃效果,通过 backdrop-blur 原子类就可以轻松实现,但是在原生移动端并不能生效,其原因就是原生组件的 View 并没有毛玻璃效果,想要实现则需要使用 expo-blur 这个库。

:::

事实上有很多 Web 端支持的类,在移动端并不能生效,通常来说只适合用 Tailwindcss 来编写基本的宽高,内外边距等样式。

这两个库的区别

从 Web 开发使用的角度,nativewind 会更好用一些, npm 实际使用量也确实比 twrnc 来的多,但要在一些情况下,比如给第三方组件更改 props 的样式情况下就会没有 twrnc 那么直观了,例如一些第三方组件有 xxxStyle 属性,例如 contentContainerStyle,这时 twrnc 就方便很多。

<FlatList style={tw`flex-1`} contentContainerStyle={tw`p-4`} />

而 nativewind 则繁琐许多,下图例子。

// This component has two 'style' props
function ThirdPartyComponent({ style, contentContainerStyle, ...props }) {
  return <FlatList style={style} contentContainerStyle={contentContainerStyle} {...props} />
}

// Call this once at the entry point of your app
remapProps(ThirdPartyComponent, {
  className: 'style',
  contentContainerClassName: 'contentContainerStyle',
})

// Now you can use the component with NativeWind
<ThirdPartyComponent className="p-5" contentContainerClassName="p-2" />

再者,twrnc 可以使用动态变量,例如在 RN 中经常需要处理安全区域,如下写法在 twrnc 就支持,但 nativewind 则不生效。

const { top } = useSafeAreaInsets();

<View style={tw`pt-[${top}]`}> // twrnc 支持

<View className={`pt-[${top}]`}> // nativewind 不支持

tamagui(不推荐)

我便提一下 tamagui 这个组件库。tamagui 看似很炫酷,但是实际配置的过程异常的繁琐,用起来也没有特别舒服,可以看以下示例代码。

<XStack flex={1} justifyContent="center" alignItems="center" gap="$2">
  <Button size="$3" theme="active">
    Active
  </Button>
  <Button size="$3" variant="outlined">
    Outlined
  </Button>
</XStack>

其效果就是一个容器内包含两个按钮,样式编写上则通过 prop 属性来实现,用过 unocss 的 Attributify Mode 应该会有些许熟悉,但还不那么一样。

并且他的主题系统使用极其的怪,采用 $number 的形式来定义尺寸(官方称 token),重点是宽高和边距采用相同的 token 效果还不一样,贴个图。

Untitled

但他的颜色更是一言难尽了,从 color0 到 color11 的效果就如下图

Untitled

可能是因为我用惯了 Tailwindcss 那套颜色系统,所以很不能理解这套颜色系统,并且在我实际编写组件的过程也是异常的奇怪。

但最让我想吐槽的是官方还为此提供了一个主题系统配置的生成器网站,但只有 tamagui 的赞助者才能够使用,如果想要自己定义一个主题,就需要配置特别多的文件,总之就是很难用就对了。

顺带在贴一张 Provider 嵌套

https://img.kuizuo.cn/2024/0514092451-202405140924689.png

这里我就不得不提到我为啥一开始选用 tamagui 了(现已迁移到 gluestack-ui),说实话我是有点后悔的,在一开始选定 UI 库的时候,我是选择 NativeWind 的,但后面无意刷到了 T4-stack (算是被他坑了),而它所用的便是 tamagui,并且一套代码跑 expo 与 next.js。于是便采用相同的项目结构以及 UI 库了。但事实上在我编写的过程中,想要一套代码就能实现跨三端(web,android,ios) 效果并不佳了,这在下一章便会说到。

gluestack-ui

首先它与 tamagui 相似,也采用 token 的方式来定义尺寸样式,但该库所对标的 token 设计就是Tailwindcss。此外该 UI 提供 NativeWind 的定制方案,意味着你的项目中可以集成了 NativeWind 用 Tailwindcss 的方式编写组件(类似 shadcn/ui),并且还在 X 上表示 gluestack-ui + NativeWind 组合就是 React Native 的 shadcn/ui

因此我个人是比较看好的,不过目前该库目前还处于 Alpha 阶段,可以持续观望中。这个也是我目前最值得推荐的组件库。

React Native 和 Next.js 应用程序共享代码

如果你想要在 React Native 和 Next.js 应用程序共享代码(UI,逻辑),你可以考虑使用 solito。该库的写法上会更偏向于 next 的写法,举个例子。

比如说 Image 组件在 RN 写法如下

import { Image } from 'react-native'

<Image
  style={styles.xxx}
  source={{
    uri: 'https://beatgig.com/image.png',
  }}
/>

next.js 的写法

import Image from 'next/image'

<Image src="https://beatgig.com/image.png" width={100} height={100} />

solito 的写法

import { SolitoImage } from 'solito/image'

<SolitoImage src="https://beatgig.com/image.png" height={100} width={100} />

这样 SolitoImage 会判断当前的仓库是 next.js 项目还是 RN 项目对不同的平台进行渲染,以做到同一个组件跨平台的开发,像 Link、useRouter 都是类似用法。

不过当你想要共享代码时,此时就必须得上 monorepo 了,通常目录结构如下图所示,你也可以到这个仓库中查看。

├── apps
│   ├── expo
│   └── next
├── packages
│   └── app
│       ├── features
│       ├── index.ts
│       ├── layouts
│       ├── package.json
│       ├── provider
│       └── screens
├── turbo.json
└── package.json

packages/app 存放主要的公共业务代码,在 next 和 expo 中则直接通过 @xxx/app 子包来导入,具体可看代码,这里就不做过多介绍了。

处理平台差异

不同平台之间必然会存在一定的开发差异,expo 也提供了相应的解决方案,可以通过给文件添加不同的后缀扩展(.web .android .ios) 以在对应平台执行对应文件,官方文档 Platform specific extensions

一些库分享

这里只会介绍这个库的用途,至于为什么选择这个而不是其他的,不想做过多的篇幅来解释。如果你用过比这更好的库,也可相互交流。

@gorhom/bottom-sheet

底部窗口,效果如图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

@shopify/flash-list

一个高性能的列表,可替代 RN 的 FlatList,其中它还支持如下图布局。

Untitled

react-native-toast-message

toast 消息组件,轻量简单易用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

react-native-gesture-handler

如果你觉得所编写的 RN 应用没有触摸反馈效果,那么可能需要尝试使用 这个库。例如,你可以使用 RectButton 来包装子元素来实现点击按钮波纹反馈效果。如下图所示

https://docs.swmansion.com/react-native-gesture-handler/gifs/samplebutton.gif

此外像拖动组件、滑动删除、放大缩小图片等常见的手势操作,总之这个库都可以实现。

react-native-reanimated

RN 动画库,没啥好说的。

以上组件库可以说基本必装,能为 RN 应用使用体验提升一个档次。

一些案例/组件分析

分享一些我在编写 RN 中的一些案例。该说不说,RN 的生态是真的可以,很多原生的解决办法几乎都有。

React Navigation

在这个库你可以实现几乎所有的原生布局,如底部 tabs,左侧抽屉等,expo 是在此基础上进行包装的。

底部 Tabs

https://docs.expo.dev/static/images/expo-router/tabs.png

Expo 自带案例,实现效果也简单,这里不在赘述了。

左侧抽屉

https://reactnavigation.org/assets/navigators/drawer/drawer.mp4

expo 官方所提供的左侧抽屉是带导航的,也就是说你无法同时使用底部选项和左侧抽屉两个布局效果。因此想要同时使用这两种布局,就要使用 Drawer Layout,这里分享我个人的实现过程。

首先,编写 DrawerContainer 组件,代码如下

import { Drawer } from 'react-native-drawer-layout'
import { useDrawerOpen } from '@/atoms/drawer'
import CustomDrawerContent from './CustomDrawerContent'

export function DrawerContainer({ children }: { children: React.ReactNode }) {
  const [open, setOpen] = useDrawerOpen()

  return (
    <Drawer
      open={open}
      onOpen={() => setOpen(true)}
      onClose={() => setOpen(false)}
      swipeEnabled={false}
      renderDrawerContent={() => <CustomDrawerContent></CustomDrawerContent>}
    >
      {children}
    </Drawer>
  )
}

如果想要定制化左侧菜单就必须使用 CustomDrawerContent,这里贴相关代码

import { DrawerContentScrollView, DrawerItem } from '@react-navigation/drawer'

export default function CustomDrawerContent() {
  return (
    <DrawerContentScrollView
      scrollEnabled={false}
      contentContainerStyle={{
        flexGrow: 1,
      }}
    >
      {/* <DrawerItemList {...props} /> */}

      <View className="flex-1 mx-2">

        <DrawerItem
          label="子项 1"
          onPress={() => { }}
        />
        <DrawerItem
          label="子项 2"
          onPress={() => { }}
        />
        {/* ... */}
      </VStack>
    </DrawerContentScrollView>
  )
}

最后在 app/_layout.tsx 中用 DrawerContainer 包装一下 Stack,如下代码。

import { Stack } from 'expo-router'
import { Provider } from '@/provider'
import { DrawerContainer } from '@/components/DrawerContainer'

export default function RootLayout() {
  return (
    <Provider>
      <DrawerContainer>
        <Stack
          screenOptions={{
            headerShown: false,
          }}
        ></Stack>
      </DrawerContainer>
    </Provider>
  )
}

此时就可以用 useDrawerOpen(这里状态库选用 jotai)来控制左侧菜单的展开了。

TabView

https://reactnavigation.org/assets/libraries/tab-view.gif

同样的,这个效果在 React Navigation 也是有提供的。但在 expo 中有 react-native-pager-view作为平替,并且更兼容原生,但是 react-native-pager-view 是不支持 Web 端的,因此如何选择就看具体需求了。

固定 Header + tab view

先看一张图,很多 app 都有这种类似的效果。

Untitled

这种效果可以使用监听 ScrollY 配合 react-native-reanimated 动画来实现,如果你不想自己实现也可以看看 @codeherence/react-native-header,上图便来自此库。

此外我还留意到 TabbedHeaderPager 这个库(很坑,别用),别看官方 gif 图效果很炫酷,然而实际效果并不达预期,并且十分难用,比如想要更改 tab 样式得像下方这样传递 props 编写。

<TabbedHeaderPager
  tabTextStyle={{
    color: theme.color?.get(),
    padding: 0,
  }}
  tabTextActiveStyle={{
    backgroundColor: 'transparent',
  }}
  tabTextContainerStyle={{
    padding: 0,
  }}
  tabTextContainerActiveStyle={{
    backgroundColor: 'transparent',
  }}
  tabWrapperStyle={{
    paddingVertical: 0,
  }}
  tabUnderlineColor={primaryColor}
  tabsContainerStyle={{
    backgroundColor: bgColor,
    flex: 1,
    maxWidth: Platform.select({
      web: 200,
    }),
    margin: Platform.select({
      web: 'auto',
    }),
  }}
  tabsContainerHorizontalPadding={Platform.select({
    default: 120,
    web: 0,
  })}
  contentContainerStyle={{
    flex: 1,
  }}
/>

RN 原生开发的感悟

在这段的 RN 开发经历,我还有很多 API 还未尝试,有很多开发上的细节没编写到。篇幅有限,未来如果还有机会编写 RN 项目,再做一些分享(我觉得应该不会有了)。

我曾与安卓开发打过两次交道:

一段是在学习安卓逆向的时候,免不了学习一些基础的原生安卓开发的知识。

另一段是在接触自动化开发的时候,看到了 Auto.js 这个库, 可以使用 JavaScript 和 Node.js 实现小型的安卓应用(不支持 IOS),更多是使用这个库来编写一些脚本类相关的应用。现在回看该库的文档,不由得开始莫名的感叹。

Auto.js Pro 移除了自动化测试、图片处理、消息通知等模块,如果你需要实现的是自动化、工作流工具,则不适合 Auto.js Pro。

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

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

相关文章

国际生物多样性科普暨母亲节亲子活动在天河公园举行

引言&#xff1a;"人类是命运共同体&#xff0c;不论是战胜新冠疫情&#xff0c;还是加强生物多样性保护&#xff0c;实现全球可持续发展&#xff0c;唯有团结合作&#xff0c;才能有效应对全球性挑战。生态兴则文明兴。我们应该携手努力&#xff0c;共同推进人与自然和谐…

OpenHarmony标准设备应用开发实战(一)——HelloWorld

本文主要内容包括三个方面&#xff1a; 1. 应用编译环境准备&#xff1b; 2. Hello Openharmony 页面编写&#xff1b; 3. 安装应用到标准设备上面。下面就让我们从零开始学习 OpenHarmony 标准设备应用开发。 一、应用开发环境准备 1.1 下载 DevEco Studio 3.0 Beta2 版本 …

3SRB2516-ASEMI适配大功率充电桩3SRB2516

编辑&#xff1a;ll 3SRB2516-ASEMI适配大功率充电桩3SRB2516 型号&#xff1a;3SRB2516 品牌&#xff1a;ASEMI 封装&#xff1a;SGBJ-5 正向电流&#xff08;Id&#xff09;&#xff1a;25A 反向耐压&#xff08;VRRM&#xff09;&#xff1a;1600V 正向浪涌电流&…

海外静态IP:全球互联的稳定之选

在全球化的商业环境中&#xff0c;企业与个人对于网络的依赖日益加深&#xff0c;而一个稳定、可靠的海外静态IP成为了连接世界的关键。本文将从五个方面深入探讨海外静态IP的重要性、应用场景、技术优势、市场趋势以及选择时的考量因素。 一、海外静态IP的重要性 静态IP地址是…

耐克、肯德基、美宝莲…六大品牌的经典广告语是如何诞生的?

近期&#xff0c;创意翻译公司franklyfluent推出了一个名为“Hard to Make, Easy to Break”的创意户外活动&#xff0c;展示了创意和文字艺术在品牌翻译中的重要性。 “Hard to Make, Easy to Break”的活动于2024年5月份在英国正式发布。这些移动广告牌出现在伦敦的各个体育…

【算法学习】拓扑排序

文章目录 拓扑排序课程表 拓扑排序 算法原理&#xff1a; 1.先找出图中入度为0的点&#xff0c;将该点加入到队列中 2.队列不为空时&#xff0c;拿出队头元素加入到最终结果 3.再遍历该点的邻接阵&#xff0c;将连接该点的点的入度全部减减 4.判断减减的点是否为入度为0&#…

渗压计与水位计的区别:监测工具的关键用途解析

在土木工程和水利工程领域&#xff0c;渗压计和水位计是两种重要的监测工具。它们虽然在外观和一些基本功能上可能相似&#xff0c;但其实各有专长&#xff0c;适用于不同的监测需求。了解它们的区别对于正确选择和应用这些工具至关重要本文将探讨渗压计和水位计的主要区别&…

【挑战全网】最全高德地图充电桩接入指南,流量必火!

分享《一套免费开源充电桩物联网系统&#xff0c;是可以立马拿去商用的&#xff01;》 一、和高德直接互联互通的优势&#xff1a; 1、高德官方直接互联互通&#xff0c;提供给合作商户独立发展自主权&#xff0c;不依赖任何第三方平台; 2、自己控制电站的上线、下线、修改电…

2024年开抖店都需要做哪些准备?这些条件缺一不可

大家好&#xff0c;我是电商花花。 作为目前国内最受欢迎的短视频电商平台&#xff0c;抖音将成为众多创业者的首选平台。 在往年我们都知道抖音小店市场很多&#xff0c;红利很大&#xff0c;利润大&#xff0c;不少人都通过抖音小店实现了脱贫&#xff0c;也有部分上班族获…

VC++6.0 常用的文件对话框和目录选择对话框

1&#xff0c;文件对话框 //1,弹出文件打开对话框CString strFileName "";char szFilter[] {"exe files(*.exe)|*.exe|All Files(*.*)|*.*|"};CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter,NULL);if(dlg.DoModal() …

三清互联:公司已形成“研发-创新-增收-研发”良性循环

三清互联自创立之初便以电力物联网感知层终端及成套设备的研发、设计、生产和销售为核心&#xff0c;致力于为电力行业提供前沿的技术解决方案。多年来&#xff0c;公司主营业务、主要产品及经营模式均保持稳定&#xff0c;不断在电力物联网感知层领域深化探索与创新。 初创期的…

品鉴中的礼仪习俗:如何遵循正确的红酒品鉴礼仪

在品鉴云仓酒庄雷盛红酒时&#xff0c;遵循正确的礼仪习俗不仅能展现个人的修养&#xff0c;还能更好地领略葡萄酒的风味。下面我们将探讨红酒品鉴中的礼仪习俗。 首先&#xff0c;当我们拿起酒杯时&#xff0c;应该注意不要晃动酒杯&#xff0c;以免扰动其中的酒液。同时&…

运营商二次放号查询接口如何对接

运营商二次放号查询接口又叫手机二次放号检测接口&#xff0c;指的是输入手机号和日期&#xff0c;查看在该日期之前是不是二次放号。那么运营商二次放号查询接口如何对接呢&#xff1f; 这边我找到了一家叫数脉API的公司&#xff0c;他们刚好有这个接口&#xff0c;首先注册账…

nmap端口扫描工具——Win10

Nmap安装流程&#xff1a; Nmap官网链接&#xff1a;Download the Free Nmap Security Scanner for Linux/Mac/Windows Nmap参考文档链接&#xff1a;https://nmap.org/book/toc.html Nmap使用流程&#xff1a; Nmap软件主页面&#xff1a; 中文版&#xff1a; nmap -T4 -…

JavaWeb-学习笔记

第一章 Tomcat 介绍 前言 使用Tomcat服务器&#xff0c;必须先安装JDK&#xff0c;因为Tomcat使用的是java语言开发的。 在系统环境变量中&#xff0c;必须包含**%JAVA_HOME%\bin**。否则Tomcat无法启动 环境变量配置&#xff1a; 此电脑 --> 右键 --> 属性高级系统…

代码随想录Day 47|Leetcode|Python|392.判断子序列 ● 115.不同的子序列

392.判断子序列 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&#xff0c;"ace"是"abcde"的…

Lobe Chat–在线AI对话聊天机器人,一键部署,免费开源

现代化设计的开源 ChatGPT/LLMs 聊天应用与开发框架 支持语音合成、多模态、可扩展的&#xff08;function call&#xff09;插件系统 一键免费拥有你自己的 ChatGPT/Gemini/Claude/Ollama 应用 项目演示 支持多种模型接口 支持语音输入输出 支持云端同步 丰富多彩非常实用的应…

第二证券今日投资参考:美宣布对华电动汽车等加征关税 AI应用或加速落地

昨日&#xff0c;两市股指早盘一度拉升&#xff0c;随后震动回落&#xff0c;盘中保持窄幅震动收拾走势。截至收盘&#xff0c;沪指微跌0.07%报3145.77点&#xff0c;深证成指跌0.05%报9668.73点&#xff0c;创业板指跌0.26%报1855.6点&#xff0c;北证50指数涨0.74%&#xff1…

istio资源字段参考文档

virtual service&#xff1a; Istio / Virtual ServiceConfiguration affecting label/content routing, sni routing, etc.https://istio.io/latest/docs/reference/config/networking/virtual-service/

opencv4.8.0 GPU版本各平台编译

一、opencv4.8.0 ubuntu22.04上编译&#xff1a; 用cmake进行编译,需要配置三次。选中world选项&#xff0c;输入opencv_contrib_module路径。 ubuntu22.04上编译&#xff1a; cmake \ -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D BUILD_opencv_p…