ReactNative【實戰系列教程】我的小紅書 8 -- 我(含左側彈窗菜單,右下角圖標等)

最終效果

在這里插入圖片描述

點左上角菜單按鈕,彈出左側菜單后

在這里插入圖片描述

代碼實現

app/(tabs)/mine.tsx

import icon_add from "@/assets/icons/icon_add.png";
import mine_bg from "@/assets/images/mine_bg.png";
import Heart from "@/components/Heart";
import articleList from "@/mock/articleList";
import SideMenu, { SideMenuRef } from "@/modules/mine/components/SideMenu";
import Entypo from "@expo/vector-icons/Entypo";
import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
import { useRouter } from "expo-router";
import { useCallback, useRef, useState } from "react";
import {Dimensions,Image,LayoutChangeEvent,ScrollView,StyleSheet,Text,TouchableOpacity,View,
} from "react-native";
import icon_no_collection from "../../assets/icons/icon_no_collection.webp";
import icon_no_favorate from "../../assets/icons/icon_no_favorate.webp";
import icon_no_note from "../../assets/icons/icon_no_note.webp";
import Empty from "../../components/Empty";
const { width: SCREEN_WIDTH } = Dimensions.get("window");
const EMPTY_CONFIG = [{ icon: icon_no_note, tips: "快去發布今日的好心情吧~" },{ icon: icon_no_collection, tips: "快去收藏你喜歡的作品吧~" },{ icon: icon_no_favorate, tips: "喜歡點贊的人運氣不會太差哦~" },
];
export default function MineScreen() {const sideMenuRef = useRef<SideMenuRef>(null);const router = useRouter();const [bgImgHeight, setBgImgHeight] = useState<number>(400);const [tabIndex, setTabIndex] = useState<number>(0);const onArticlePress = useCallback((article: ArticleSimple) => () => {router.push(`/articleDetail?id=${article.id}`);},[]);const renderTitle = () => {const styles = StyleSheet.create({titleLayout: {width: "100%",height: 48,flexDirection: "row",alignItems: "center",},menuButton: {height: "100%",paddingHorizontal: 16,justifyContent: "center",},menuImg: {width: 28,height: 28,resizeMode: "contain",},rightMenuImg: {marginRight: 14,},});return (<View style={styles.titleLayout}><TouchableOpacitystyle={styles.menuButton}onPress={() => {sideMenuRef.current?.show();}}><Entypo name="menu" size={24} color="white" /></TouchableOpacity><View style={{ flex: 1 }} /><Entypostyle={styles.rightMenuImg}name="shopping-cart"size={24}color="white"/><Entypostyle={styles.rightMenuImg}name="share"size={24}color="white"/></View>);};const renderInfo = () => {const userInfo = {avatar:"https://img0.baidu.com/it/u=919979501,2820948992&fm=253&app=120&f=JPEG?w=800&h=800",nickName: "清禾",redBookId: "635942",desc: "鐘愛編程,偏前端開發,歡迎私信我加入EC盡享編程俱樂部共同學習,交流成長!",sex: "female",};const { avatar, nickName, redBookId, desc, sex } = userInfo;const styles = StyleSheet.create({avatarLayout: {width: "100%",flexDirection: "row",alignItems: "flex-end",padding: 16,},avatarImg: {width: 96,height: 96,resizeMode: "cover",borderRadius: 48,},addImg: {width: 28,height: 28,marginLeft: -28,marginBottom: 2,},nameLayout: {marginLeft: 20,},nameTxt: {fontSize: 22,color: "white",fontWeight: "bold",},idLayout: {flexDirection: "row",alignItems: "center",marginTop: 16,marginBottom: 20,},idTxt: {fontSize: 12,color: "#bbb",},qrcodeImg: {width: 12,height: 12,marginLeft: 6,tintColor: "#bbb",},descTxt: {fontSize: 14,color: "white",paddingHorizontal: 16,},sexLayout: {width: 32,height: 24,backgroundColor: "#ffffff50",borderRadius: 12,marginTop: 12,marginLeft: 16,justifyContent: "center",alignItems: "center",},sexImg: {width: 12,height: 12,resizeMode: "contain",},infoLayout: {width: "100%",paddingRight: 16,flexDirection: "row",alignItems: "center",marginTop: 20,marginBottom: 28,},infoItem: {alignItems: "center",paddingHorizontal: 12,},infoValue: {fontSize: 18,color: "white",},infoLabel: {fontSize: 12,color: "#ddd",marginTop: 6,},infoButton: {height: 32,paddingHorizontal: 16,borderWidth: 1,borderColor: "white",borderRadius: 16,justifyContent: "center",alignItems: "center",marginLeft: 16,},editTxt: {fontSize: 14,color: "#ffffff",},settingImg: {width: 20,height: 20,tintColor: "#ffffff",},});return (<ViewonLayout={(e: LayoutChangeEvent) => {const { height } = e.nativeEvent.layout;setBgImgHeight(height);}}><View style={styles.avatarLayout}><Image style={styles.avatarImg} source={{ uri: avatar }} /><Image style={styles.addImg} source={icon_add} /><View style={styles.nameLayout}><Text style={styles.nameTxt}>{nickName}</Text><View style={styles.idLayout}><Text style={styles.idTxt}>小紅書號:{redBookId}</Text><MaterialCommunityIconsstyle={{marginLeft: 6,}}name="qrcode"size={12}color="white"/></View></View></View><Text style={styles.descTxt}>{desc}</Text><View style={styles.sexLayout}><MaterialCommunityIconsname={sex === "male" ? "gender-male" : "gender-female"}size={14}color="white"/></View><View style={styles.infoLayout}><View style={styles.infoItem}><Text style={styles.infoValue}>1</Text><Text style={styles.infoLabel}>關注</Text></View><View style={styles.infoItem}><Text style={styles.infoValue}>65</Text><Text style={styles.infoLabel}>粉絲</Text></View><View style={styles.infoItem}><Text style={styles.infoValue}>625</Text><Text style={styles.infoLabel}>獲贊與收藏</Text></View><View style={{ flex: 1 }} /><TouchableOpacity style={styles.infoButton}><Text style={styles.editTxt}>編輯資料</Text></TouchableOpacity><TouchableOpacity style={styles.infoButton}><MaterialIcons name="settings" size={20} color="white" /></TouchableOpacity></View></View>);};const renderTabs = () => {const styles = StyleSheet.create({titleLayout: {width: "100%",height: 48,flexDirection: "row",alignItems: "center",justifyContent: "center",backgroundColor: "white",paddingHorizontal: 16,borderTopLeftRadius: 12,borderTopRightRadius: 12,borderBottomWidth: 1,borderBottomColor: "#eee",},icon: {width: 28,height: 28,},line: {width: 28,height: 2,backgroundColor: "#ff2442",borderRadius: 1,position: "absolute",bottom: 6,},tabButton: {height: "100%",flexDirection: "column",alignItems: "center",justifyContent: "center",paddingHorizontal: 14,},tabTxt: {fontSize: 17,color: "#999",},tabTxtSelected: {fontSize: 17,color: "#333",},});return (<View style={styles.titleLayout}><TouchableOpacitystyle={styles.tabButton}onPress={() => {setTabIndex(0);}}><Text style={tabIndex === 0 ? styles.tabTxtSelected : styles.tabTxt}>筆記</Text>{tabIndex === 0 && <View style={styles.line} />}</TouchableOpacity><TouchableOpacitystyle={styles.tabButton}onPress={() => {setTabIndex(1);}}><Text style={tabIndex === 1 ? styles.tabTxtSelected : styles.tabTxt}>收藏</Text>{tabIndex === 1 && <View style={styles.line} />}</TouchableOpacity><TouchableOpacitystyle={styles.tabButton}onPress={() => {setTabIndex(2);}}><Text style={tabIndex === 2 ? styles.tabTxtSelected : styles.tabTxt}>贊過</Text>{tabIndex === 2 && <View style={styles.line} />}</TouchableOpacity></View>);};const renderList = () => {const noteList: ArticleSimple[] = [];const collectionList: ArticleSimple[] = [];const favorateList: ArticleSimple[] = articleList.filter((item) => item.isFavorite);const currentList = [noteList, collectionList, favorateList][tabIndex];if (!currentList?.length) {const config = EMPTY_CONFIG[tabIndex];return <Empty icon={config.icon} tips={config.tips} />;}const styles = StyleSheet.create({listContainer: {width: "100%",flexDirection: "row",flexWrap: "wrap",backgroundColor: "white",},item: {width: (SCREEN_WIDTH - 18) >> 1,backgroundColor: "white",marginLeft: 6,marginBottom: 6,borderRadius: 8,overflow: "hidden",marginTop: 8,},titleTxt: {fontSize: 14,color: "#333",marginHorizontal: 10,marginVertical: 4,},nameLayout: {width: "100%",flexDirection: "row",alignItems: "center",paddingHorizontal: 10,marginBottom: 10,},avatarImg: {width: 20,height: 20,resizeMode: "cover",borderRadius: 10,},nameTxt: {fontSize: 12,color: "#999",marginLeft: 6,flex: 1,},heart: {width: 20,height: 20,resizeMode: "contain",},countTxt: {fontSize: 14,color: "#999",marginLeft: 4,},itemImg: {width: (SCREEN_WIDTH - 18) >> 1,height: 240,},});return (<View style={styles.listContainer}>{currentList.map((item, index) => {return (<TouchableOpacitykey={`${item.id}-${index}`}style={styles.item}onPress={onArticlePress(item)}><Image style={styles.itemImg} source={{ uri: item.image }} /><Text style={styles.titleTxt}>{item.title}</Text><View style={styles.nameLayout}><Imagestyle={styles.avatarImg}source={{ uri: item.avatarUrl }}/><Text style={styles.nameTxt}>{item.userName}</Text><Heartvalue={item.isFavorite}onValueChanged={(value: boolean) => {console.log(value);}}/><Text style={styles.countTxt}>{item.favoriteCount}</Text></View></TouchableOpacity>);})}</View>);};return (<View style={styles.page}><Imagestyle={[styles.bgImg, { height: bgImgHeight + 64 }]}source={mine_bg}/>{renderTitle()}<ScrollView style={styles.scrollView}>{renderInfo()}{renderTabs()}{renderList()}</ScrollView><SideMenu ref={sideMenuRef} /></View>);
}
const styles = StyleSheet.create({scrollView: {width: "100%",flex: 1,},page: {width: "100%",height: "100%",backgroundColor: "white",},bgImg: {position: "absolute",top: 0,width: "100%",height: 400,},
});

相關組件

modules/mine/components/SideMenu.tsx

左側彈窗菜單

import icon_browse_histroy from "@/assets/icons/icon_browse_history.png";
import icon_community from "@/assets/icons/icon_community.png";
import icon_coupon from "@/assets/icons/icon_coupon.png";
import icon_create_center from "@/assets/icons/icon_create_center.png";
import icon_draft from "@/assets/icons/icon_draft.png";
import icon_exit from "@/assets/icons/icon_exit.png";
import icon_fid_user from "@/assets/icons/icon_find_user.png";
import icon_free_net from "@/assets/icons/icon_free_net.png";
import icon_nice_goods from "@/assets/icons/icon_nice_goods.png";
import icon_orders from "@/assets/icons/icon_orders.png";
import icon_packet from "@/assets/icons/icon_packet.png";
import icon_red_vip from "@/assets/icons/icon_red_vip.png";
import icon_scan from "@/assets/icons/icon_scan.png";
import icon_service from "@/assets/icons/icon_service.png";
import icon_setting from "@/assets/icons/icon_setting.png";
import icon_shop_car from "@/assets/icons/icon_shop_car.png";
import icon_wish from "@/assets/icons/icon_wish.png";
import { remove } from "@/utils/Storage";
import { useRouter } from "expo-router";
import React, {forwardRef,useCallback,useImperativeHandle,useState,
} from "react";
import {Dimensions,Image,LayoutAnimation,Modal,ScrollView,StyleSheet,Text,TouchableOpacity,View,
} from "react-native";
const MENUS = [[{ icon: icon_fid_user, name: "發現好友" }],[{ icon: icon_draft, name: "我的草稿" },{ icon: icon_create_center, name: "創作中心" },{ icon: icon_browse_histroy, name: "瀏覽記錄" },{ icon: icon_packet, name: "錢包" },{ icon: icon_free_net, name: "免流量" },{ icon: icon_nice_goods, name: "好物體驗" },],[{ icon: icon_orders, name: "訂單" },{ icon: icon_shop_car, name: "購物車" },{ icon: icon_coupon, name: "卡券" },{ icon: icon_wish, name: "心愿單" },{ icon: icon_red_vip, name: "小紅書會員" },],[{ icon: icon_community, name: "社區公約" },{ icon: icon_exit, name: "退出登陸" },],
];
const BOTTOM_MENUS = [{ icon: icon_setting, txt: "設置" },{ icon: icon_service, txt: "幫助與客服" },{ icon: icon_scan, txt: "掃一掃" },
];
export interface SideMenuRef {show: () => void;hide: () => void;
}
const { width: SCREEN_WIDTH } = Dimensions.get("window");
const ContentWidth = SCREEN_WIDTH * 0.75;
// eslint-disable-next-line react/display-name
export default forwardRef((props: any, ref) => {const [visible, setVisible] = useState<boolean>(false);const [open, setOpen] = useState<boolean>(false);const router = useRouter();const show = () => {setVisible(true);setTimeout(() => {LayoutAnimation.easeInEaseOut();setOpen(true);}, 100);};const hide = () => {LayoutAnimation.easeInEaseOut();setOpen(false);setTimeout(() => {setVisible(false);}, 300);};useImperativeHandle(ref, () => {return {show,hide,};});const onMenuItemPress = useCallback((item: any) => async () => {if (item.name === "退出登陸") {hide();await remove("userInfo");router.replace("/login");}},[]);const renderContent = () => {return (<View style={[styles.content, { marginLeft: open ? 0 : -ContentWidth }]}><ScrollViewstyle={styles.scrollView}contentContainerStyle={styles.container}showsVerticalScrollIndicator={false}>{MENUS.map((item, index) => {return (<View key={`${index}`}>{item.map((subItem, subIndex) => {return (<TouchableOpacitykey={`${index}-${subIndex}`}style={styles.menuItem}onPress={onMenuItemPress(subItem)}><Imagestyle={styles.menuItemIcon}source={subItem.icon}/><Text style={styles.menuItemTxt}>{subItem.name}</Text></TouchableOpacity>);})}{index !== MENUS.length - 1 && (<View style={styles.divideLine} />)}</View>);})}</ScrollView><View style={styles.bottomLayout}>{BOTTOM_MENUS.map((item) => {return (<TouchableOpacitykey={`${item.txt}`}style={styles.bottomMenuItem}><View style={styles.bottomMenuIconWrap}><Image style={styles.bottomMenuIcon} source={item.icon} /></View><Text style={styles.bottomMenuTxt}>{item.txt}</Text></TouchableOpacity>);})}</View></View>);};return (<Modaltransparent={true}visible={visible}statusBarTranslucent={false}animationType="fade"onRequestClose={hide}><TouchableOpacity style={styles.root} onPress={hide} activeOpacity={1}>{renderContent()}</TouchableOpacity></Modal>);
});
const styles = StyleSheet.create({root: {width: "100%",height: "100%",backgroundColor: "#000000C0",flexDirection: "row",},content: {height: "100%",width: ContentWidth,backgroundColor: "white",},scrollView: {width: "100%",flex: 1,},bottomLayout: {width: "100%",flexDirection: "row",paddingTop: 12,paddingBottom: 20,},bottomMenuItem: {flex: 1,alignItems: "center",},bottomMenuIconWrap: {width: 44,height: 44,backgroundColor: "#f0f0f0",borderRadius: 22,justifyContent: "center",alignItems: "center",},bottomMenuIcon: {width: 26,height: 26,},bottomMenuTxt: {fontSize: 13,color: "#666",marginTop: 8,},divideLine: {width: "100%",height: 1,backgroundColor: "#eee",},menuItem: {width: "100%",height: 64,flexDirection: "row",alignItems: "center",},menuItemIcon: {width: 32,height: 32,resizeMode: "contain",},menuItemTxt: {fontSize: 16,color: "#333",marginLeft: 14,},container: {paddingTop: 10,paddingHorizontal: 28,paddingBottom: 12,},
});

components/Heart.tsx

import AntDesign from "@expo/vector-icons/AntDesign";
import React, { useEffect, useRef, useState } from "react";
import { Animated, TouchableOpacity } from "react-native";
type Props = {value: boolean;onValueChanged?: (value: boolean) => void;size?: number;color?: string;
};
// eslint-disable-next-line react/display-name
export default (props: Props) => {const { value, onValueChanged, size = 20, color = "black" } = props;const [showState, setShowState] = useState<boolean>(false);const scale = useRef<Animated.Value>(new Animated.Value(0)).current;const alpha = useRef<Animated.Value>(new Animated.Value(0)).current;useEffect(() => {setShowState(value);}, [value]);const onHeartPress = () => {const newState = !showState;setShowState(newState);onValueChanged?.(newState);if (newState) {alpha.setValue(1);const scaleAnim = Animated.timing(scale, {toValue: 1.8,duration: 300,useNativeDriver: false,});const alphaAnim = Animated.timing(alpha, {toValue: 0,duration: 400,useNativeDriver: false,delay: 200,});Animated.parallel([scaleAnim, alphaAnim]).start();} else {scale.setValue(0);alpha.setValue(0);}};return (<TouchableOpacity onPress={onHeartPress}>{showState ? (<AntDesign name="heart" size={size} color="red" />) : (<AntDesign name="hearto" size={size} color={color} />)}<Animated.Viewstyle={{width: size,height: size,borderRadius: size / 2,borderWidth: size / 20,position: "absolute",borderColor: "#ff2442",transform: [{ scale: scale }],opacity: alpha,}}/></TouchableOpacity>);
};

components/Empty.tsx

import React from "react";
import { Image, StyleSheet, Text, View } from "react-native";
type Props = {icon: number;tips: string;
};
// eslint-disable-next-line react/display-name
export default ({ icon, tips }: Props) => {return (<View style={styles.root}><Image style={styles.icon} source={icon} /><Text style={styles.tipsTxt}>{tips}</Text></View>);
};
const styles = StyleSheet.create({root: {alignItems: "center",paddingTop: 120,},icon: {width: 96,height: 96,resizeMode: "contain",},tipsTxt: {fontSize: 14,color: "#bbb",marginTop: 16,},
});

模擬數據

mock/articleList.ts

const articleList: ArticleSimple[] = [{id: 1,title: "讓我抱抱,一起溫暖,真的好治愈",userName: "小飛飛愛貓咪",avatarUrl:"https://img2.baidu.com/it/u=902203086,3868774028&fm=253&app=138&f=JPEG?w=500&h=500",image:"http://gips2.baidu.com/it/u=195724436,3554684702&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960",favoriteCount: 325,isFavorite: true,},{id: 2,title: "不愧是網友給的配方,真的香迷糊了",userName: "大廚師小飛象",avatarUrl:"https://pic.rmb.bdstatic.com/bjh/events/eeae3b71dabc9a372afd7f9e112287086428.jpeg@h_1280",image:"http://gips0.baidu.com/it/u=3602773692,1512483864&fm=3028&app=3028&f=JPEG&fmt=auto?w=960&h=1280",favoriteCount: 1098,isFavorite: true,},{id: 3,title: "一覺醒來,滿樹的柑橘爬上了我的窗",userName: "小小風箏",avatarUrl:"https://img1.baidu.com/it/u=1811602911,3261262340&fm=253&app=138&f=JPEG?w=500&h=500",image:"http://gips3.baidu.com/it/u=1537137094,335954266&fm=3028&app=3028&f=JPEG&fmt=auto?w=720&h=1280",favoriteCount: 18700,isFavorite: false,},{id: 4,title: "滿床清夢壓星河",userName: "失憶",avatarUrl:"https://img1.baidu.com/it/u=3505470809,2700212068&fm=253&app=138&f=JPEG?w=500&h=500",image:"https://gips3.baidu.com/it/u=1014935733,598223672&fm=3074&app=3074&f=PNG?w=1440&h=2560",favoriteCount: 8700,isFavorite: true,},{id: 5,title: "手機拍出來的星星,沒想到那么多人喜歡",userName: "慢慢",avatarUrl:"https://img1.baidu.com/it/u=1924685292,2387273894&fm=253&app=138&f=JPEG?w=500&h=500",image:"https://img2.baidu.com/it/u=2585843050,3523947274&fm=253&app=138&f=JPEG?w=1422&h=800",favoriteCount: 2655,isFavorite: false,},{id: 6,title: "告白如同田野間的風在青春里轟然",userName: "瀟瀟",avatarUrl:"https://img1.baidu.com/it/u=3843254675,2187553494&fm=253&app=120&f=JPEG?w=800&h=800",image:"https://img1.baidu.com/it/u=1926713654,274347830&fm=253&app=138&f=JPEG?w=1422&h=800",favoriteCount: 2655,isFavorite: false,},
];
export default articleList;

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/88449.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/88449.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/88449.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++性能優化實戰:從理論到落地的五大核心策略

在當今這個對計算效率要求極高的時代&#xff0c;C作為系統級編程語言的王者&#xff0c;其性能優化能力依然是無可替代的核心競爭力。本文將分享我在大型分布式系統開發中積累的C性能優化實戰經驗&#xff0c;這些經驗幫助我們將關鍵組件的吞吐量提升了300%&#xff0c;延遲降…

字節 Seed 團隊聯合清華大學智能產業研究院開源 MemAgent: 基于多輪對話強化學習記憶代理的長文本大語言模型重構

&#x1f525; 最新動態!!! [2025/07] 我們提供了快速啟動腳本&#xff0c;讓使用MemAgent變得超級簡單&#xff0c;詳情請見下方"快速入門"部分。[2025/06] 我們發布了RL-MemAgent-14B和RL-MemAgent-7B模型&#xff0c;在350萬token上下文任務中實現了近乎無損的性…

【unitrix】 4.20 類型級二進制數減法實現解析(sub.rs)

一、源碼 這段代碼實現了一個用于統計二進制補碼整數位數的系統&#xff0c;支持多種自定義數值類型&#xff08;Z0、P1、N1、B0、B1&#xff09;。 use core::mem::size_of; use crate::number::{Z0, P1, N1, B0, B1, Var};/// 統計二進制位數的 trait pub trait BitLength {f…

手把手教你安全刪除Anaconda虛擬環境(避坑指南)

文章目錄一、刪除前必看清單&#xff08;超級重要&#xff09;二、三種刪除方法對比&#xff08;建議收藏&#xff09;方法1&#xff1a;官方推薦命令&#xff08;最安全&#xff09;方法2&#xff1a;暴力刪除大法&#xff08;快速但需謹慎&#xff09;方法3&#xff1a;核彈級…

Effective Modern C++ 條款7:區分使用 `()` 和 `{}` 創建對象

在 C11 及以后的版本中&#xff0c;初始化對象的方式變得更加靈活&#xff0c;但也帶來了選擇上的困惑。() 和 {} 是兩種常見的初始化語法&#xff0c;它們在語義、行為和適用場景上有顯著差異。本文將通過具體示例&#xff0c;深入解析這兩種初始化方式的區別&#xff0c;并探…

Java基礎-String常用的方法

String常用的三種構造方法 public static void main(String[] args) {//1.使用常量字符串構造String s1 "1.Hello world";System.out.println(s1);//2.使用new關鍵字構造String s2 new String("2.Hello world");System.out.println(s2);//3。使用字符數組…

數學建模:多目標規劃:ε約束法、 理想點法

一、ε約束法定義ε約束法通過將部分目標函數轉化為約束條件&#xff0c;保留一個主要目標進行優化。1、選擇一個主要目標 fk?(x) 進行優化。2、其他目標 fi?(x) 轉化為約束 fi?(x)≤εi?&#xff0c;其中 εi? 是決策者設定的容許閾值。??原理????目標選擇??&…

linux kernel struct regmap_config結構詳解

在 Linux 內核中&#xff0c;struct regmap_config 是 ?Regmap 子系統的核心配置結構體&#xff0c;用于定義如何與底層硬件寄存器進行交互。Regmap&#xff08;Register Map&#xff09;子系統通過抽象不同總線&#xff08;如 I2C、SPI、MMIO 等&#xff09;的寄存器訪問細節…

【Python3教程】Python3高級篇之CGI編程

博主介紹:?全網粉絲23W+,CSDN博客專家、Java領域優質創作者,掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域? 技術范圍:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大數據、物聯網、機器學習等設計與開發。 感興趣的可…

docker安裝Consul筆記

安裝過程 詳細步驟如下&#xff1a; 首先拉取Consul的Docker鏡像&#xff1a; docker pull hashicorp/consul:1.18.1創建Consul的配置文件和數據目錄&#xff1a; mkdir -p /srv/docker/consul/data mkdir -p /srv/docker/consul/config在config目錄下創建一個config.json配置文…

.net數據脫敏

.NET數據脫敏技術&#xff1a;保障數據安全的有效手段 在當今數字化時代&#xff0c;數據安全至關重要。尤其是涉及到用戶的敏感信息&#xff0c;如密碼、手機號碼等&#xff0c;必須采取有效的措施進行保護。數據脫敏就是這樣一種技術&#xff0c;它能夠在不影響數據可用性的…

【openp2p】 學習2:源碼閱讀P2PNetwork和P2PTunnel

【openp2p】 學習1:P2PApp和優秀的go跨平臺項目已經做了初步分析。閱讀原版工程,感覺工程是一個暴露內網服務端口,讓外部可以用的一個實現是一個完整的、跨平臺的可商業化的應用。感謝作者需要學習作者的設計思路工程構建 F:\GolandProjects\openp2p\core\p2pnetwork.go通常…

網安學習NO.14

防火墻基礎實驗 傳統防火墻配置實驗拓撲圖PC&#xff1a; ip 192.168.10.1 255.255.255.0 192.168.10.254 ip dns 114.114.114.114二層交換機 vl 10 ex int e0/0 sw mo ac sw ac vl 10 ex inr e0/1 sw tr en do sw mo tr三層交換機 vl 10 ex int g0/0 sw tr en do sw mo tr ex …

ESP32語音喚醒

兩種喚醒方式AfeWakeWord與EspWakeWord對比 底層技術 AfeWakeWord&#xff1a;基于ESP-IDF的AFE框架&#xff08;esp_afe_sr_iface_t&#xff09;&#xff0c;高性能模式&#xff08;AFE_MODE_HIGH_PERF&#xff09;EspWakeWord&#xff1a;基于WakeNet接口&#xff08;esp_wn_…

借助 Wisdom SSH AI 助手,輕松安裝 CentOS 8 LNMP 環境

打開Wisdom SSH軟件&#xff0c;在AI對話區輸入“在CentOS 8服務器安裝LNMP環境”&#xff0c;AI助手會按以下步驟分析并執行安裝&#xff1a; 安裝Nginx 分析&#xff1a;CentOS 8默認軟件源可能沒有Nginx&#xff0c;所以要先啟用Nginx官方軟件源&#xff0c;然后才能安裝Ngi…

WD0407 40V 7A 超級肖特基二極管,應用于開關汽車工業控制

WD0407 40V 7A 超級肖特基二極管說明? 產品概述? WD0407 是一款性能卓越的超級肖特基二極管&#xff0c;專為滿足現代電子設備對高效、可靠電源管理的需求而設計。它采用先進的半導體制造工藝&#xff0c;在諸多關鍵性能指標上表現出色&#xff0c;能夠為各類電路提供穩定、高…

盧比危機下的金融破局:科倫坡交易所技術升級作戰圖

&#x1f30f; 今日南亞風暴眼 印度雙重上市機制加速落地&#xff1a;印度國家證券國際交易所&#xff08;NSE IX&#xff09;與科倫坡證券交易所&#xff08;CSE&#xff09;達成技術對接協議&#xff0c;斯企可通過印度GIFT City吸引美元資本&#xff0c;交易時段覆蓋全球22小…

upload-labs靶場通關詳解:第20關 /.繞過

一、分析源代碼// 初始化上傳狀態標記&#xff0c;默認為false&#xff0c;即文件未上傳 $is_upload false; // 初始化消息變量&#xff0c;用于存儲錯誤信息 $msg null;// 檢查是否通過POST方式提交了表單&#xff08;點擊上傳按鈕&#xff09; if (isset($_POST[submit])) …

企業用云狀態評估

云部署形態及其策略規劃成熟度 單云部署&#xff1a; 主要業務負載運行在單一公有云或私有云上 多云/混合云部署 —有清晰戰略規劃與實施&#xff1a; 業務負載運行在多個云&#xff08;公有云或混合云&#xff09;上&#xff0c;并且企業擁有清晰的多云/混合云戰略規劃&#x…

STM32G473串口通信-USART/UART配置和清除串口寄存器狀態的注意事項

USART和UART配置的區別 如果USART使用的是異步通信&#xff0c;那么UART與USART配置基本相同。 USART配置如下:UART配置如下&#xff1a;如果USART使用的是同步通信&#xff0c;那么UART配置就有差異。首先通信雙方都是使用USART的同步通信&#xff0c;一個主機&#xff0c;一個…