React--》規劃React組件庫編碼規范與標準 — Button篇

目前前端組件化已經成為前端開發的核心思想之一,在這篇文章中將深入探討如何規劃一個規范的Button組件,讓它不僅能高效支持不同的功能需求還能確保跨項目、跨團隊的一致性,拋磚引玉的方式引出后面組件庫的其他組件的開發!

目錄

Button組件搭建

bem命名規范

組件正式編碼

樣式解決方案

組件單元測試

組件文檔搭建?

GitHub Actions

changeset版本

Button組件搭建

????????Button按鈕本質:一個button按鈕之所以有需要樣式的選擇,究其原因就是class名稱的組合,根據賦值的不同類名來實現不同的樣式結果,如下所示:

class="ease-button--primary ease-button--larger is-plain is-disabled"

完成一個組件庫需要考慮的問題有以下幾個方面,根據任務進行需求分析,然后初始化項目確定項目文件結構,接下來就是規范基礎寫法、樣式解決方案以及色彩系統等基礎方面內容了:

代碼結構;樣式解決方案;組件需求分析和編碼;組件測用例和編碼;代碼打包輸出和發布;CI/CD及文檔生成等

像Button組件大部分關注的只是樣式而沒有交互,根據分析我們可以得到如下具體的屬性列表:

type:不同的樣式(default、primary、danager、info、success、warning)
plain:樣式的不同展現模式boolean
round:圓角boolean
circle:圓形按鈕,適合圖標boolean
disabled:禁用boolean
icon:圖標添加
loading:加載樣式添加

? ? ? ? 組件目錄結構:后期所有組件的開發按照如下目錄進行規范進行,styles文件存儲當前組件所有關聯的樣式;types文件存儲當前組件所有關聯的類型;其他tsx文件存儲當前組件所有的核心代碼;index.tsx文件存儲當前組件暴露出去的封裝組件及類型,如下所示:

bem命名規范

????????bem:(Block, Element, Modifier)是一種CSS命名規范,用于使前端代碼更加結構化和可維護,它通過三個主要部分來命名CSS類名,如下所示:

1)Block(塊):代表一個獨立的功能模塊,可以是頁面中的一個組件或者布局的一部分。例如header、button、menu

2)Element(元素):表示一個塊內的子元素,通常是該塊的一部分依賴于塊的存在,例如header__title(title是header塊的元素),button__icon。

3)Modifier(修飾符):用于描述塊或元素的不同狀態或外觀變化,例如button--primary(代表一種主要按鈕樣式),header__title--large(代表較大的標題樣式)

brm的命名規則讓類名具有清晰的層級關系和可讀性,有助于避免命名沖突和使代碼更容易維護,這里我將其抽離到項目的utils文件夾下用來供全局組件進行調用,代碼如下所示:

// block代碼塊 element元素 modifier裝飾 state狀態
/*** 示例:* ease-button--primary* is-checked*/// 創建BEM命名規范
const createBEM = (prefixName: string) => {const block = (blockSuffix: string = '') => _bem(prefixName, blockSuffix, '', '')const element = (element: string) => element ? _bem(prefixName, '', element, '') : ''const modifier = (modifier: string | undefined) => modifier ? _bem(prefixName, '', '', modifier) : ''const be = (blockSuffix: string = '', element: string = '') => blockSuffix && element ? _bem(prefixName, blockSuffix, element, '') : ''const bm = (blockSuffix: string = '', modifier: string = '') => blockSuffix && modifier ? _bem(prefixName, blockSuffix, '', modifier) : ''const em = (element: string = '', modifier: string = '') => element && modifier ? _bem(prefixName, '', element, modifier) : ''const bem = (blockSuffix: string = '', element: string = '', modifier: string = '') => blockSuffix && element && modifier ? _bem(prefixName, blockSuffix, element, modifier) : ''const is = (name: string, state: boolean | undefined) => (state ? `is-${name}` : "")return { block, element, modifier, be, bm, em, bem, is }
};// BEM命名規范實現
const _bem = (prefixName: string, blockSuffix: string, element: string, modifier: string) => {if (blockSuffix) prefixName += `-${blockSuffix}`;if (element) prefixName += `__${element}`;if (modifier) prefixName += `--${modifier}`;return prefixName;
}// 創建命名空間
export const createNameSpace = (name: string) => {const prefixName = `ease-${name}`return createBEM(prefixName)
};

組件正式編碼

????????接下來我們開始對button進行正式代碼書寫,當我們封裝一個對應的原生組件的時候,原生屬性必須要進行考量是否添加好,這里我們可以參考?MDN?官網提供的文檔詳細了解原生組件擁有哪些原生屬性以及其具體的作用是什么:

typescript類型:當我們編寫一個原生組件給其他人使用的時候ts類型尤為重要,只有我們寫了ts類型之后用戶才會知道我們開發的組件到底有哪些核心參數可以使用,這里我們完全可以參考其他熱門組件庫文件提供的一些范例來給我們開發組件庫提供一些思路:

對于一個button按鈕來講,他有許多常量類型供我們選擇、如按鈕類型、形狀、html類型、 尺寸等常量類型,這里我們可以將其抽離出一個constant.ts文件里面用于定義常量類型,如下所示:

友情提示!!!:我們可以定義代碼塊用于快速折疊相似功能代碼:

// #region 規范按鈕組件的常量類型
// 定義包含五種按鈕類型的元組
const _ButtonTypes = ['default', 'primary', 'dashed', 'link', 'text'] as const;
export type ButtonType = (typeof _ButtonTypes)[number]; // 限制組件屬性的取值范圍// 定義包含三種按鈕形狀的元組
const _ButtonShapes = ['default', 'circle', 'round'] as const;
export type ButtonShape = (typeof _ButtonShapes)[number];// 定義包含三種按鈕HTML類型的元組
const _ButtonHTMLTypes = ['submit', 'button', 'reset'] as const;
export type ButtonHTMLType = (typeof _ButtonHTMLTypes)[number];// 定義包含三種按鈕尺寸的元組
const _ButtonSizes = ['large', 'middle', 'small'] as const;
export type ButtonSize = (typeof _ButtonSizes)[number];
// #endregion

定義完常量類型之后,我們在types類型文件夾下的入口index.ts文件中開始引入這些常量類型,然后設置props類型并給其賦值,常見的props類型我們可以參考熱門組件庫文檔給出的范例,最終代碼如下所示:

import React from 'react'
import { ButtonHTMLType, ButtonSize, ButtonShape, ButtonType } from './constant'interface BaseButtonProps {type: ButtonType; // 按鈕類型,默認為 'default'shape: ButtonShape; // 按鈕形狀,默認為 'default'htmlType: ButtonHTMLType; // 按鈕的 HTML 類型,默認為 'button'size: ButtonSize; // 按鈕尺寸,默認為 'middle'plain: boolean; // 是否為樸素按鈕,默認為 falsedisabled: boolean; // 是否禁用狀態,默認為 falseloading: boolean; // 是否為加載中狀態,默認為 falsecolor: string; // 按鈕顏色children: React.ReactNode; // 按鈕內容,默認為 null
}// 合并HTMLAttributes和 ButtonHTMLAttributes的屬性,但不包括type、color、disabled、children屬性
type MergedHTMLAttributes = Omit<React.HTMLAttributes<HTMLElement> &React.ButtonHTMLAttributes<HTMLElement> &React.AnchorHTMLAttributes<HTMLElement>,'type' | 'color' | 'disabled' | 'children'
>;export interface inheritProps extends BaseButtonProps, MergedHTMLAttributes {href: string;autoInsertSpace: boolean;
}// 使所有屬性可選(Partial)且只讀(Readonly)
export type ButtonProps = Readonly<Partial<inheritProps>>;

核心代碼實現:編寫完button組件的ts類型之后,接下來我們開始正式對原生button按鈕進行組件化開發,這里我們定義一個組件的基本結構,通過props傳遞數據,并且借助函數將實例暴露出去,通過bem規范給組件動態設置類名:

import React, { forwardRef, useCallback } from 'react';
import clsx from 'clsx';
import { createNameSpace } from "@ztk63lrd/utils/create"
import type { ButtonProps } from './types';const EButton = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {// #region 組件變量聲明const bem = createNameSpace('button');const { type, shape, htmlType = 'button',  size, disabled, loading, color, children, ...rest } = props;// #endregion// #region 組件樣式構建const classes = clsx( // 使用 clsx 動態構建類名bem.block(), // 基礎類名bem.modifier(type), // type 修改器bem.modifier(shape), // shape 修改器bem.modifier(size), // size 修改器bem.is('disabled', disabled), // disabled 狀態bem.is('loading', loading) // loading 狀態);// #endregion// #region 組件事件處理const handleClick = useCallback((e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement, MouseEvent>) => {if (disabled) {e.preventDefault();return;}props.onClick?.('href' in props? (e as React.MouseEvent<HTMLAnchorElement, MouseEvent>): (e as React.MouseEvent<HTMLButtonElement, MouseEvent>),);}, [props.onClick, disabled]);// #endregionreturn (<buttonclassName={classes} // 直接應用動態類名type={htmlType}disabled={disabled || loading}onClick={handleClick}ref={ref}{...rest}>{children}</button>);
});export default EButton;

接下來我們在組件文件夾的入口文件index.tsx處將封裝組件及其類型暴露出去,然后在packages文件夾下的入口文件將所有components文件夾下寫的所有組件再暴露一遍出去就可以了:

接下來我們開始在根目錄終端執行pnpm run build即可,打包后就會在packages文件下生成build文件目錄,并且會按照問你設置的組件目錄結構生成相應的js文件和.d.ts類型聲明文件,如下:

接下來我們終端運行pnpm run dev命令來執行review文件下測試組件項目的代碼,在該文件下設置如下代碼來查看我們編寫的組件情況,如果我們直接導入ease-reactify就是我們打包好的實際組件代碼,如果導入@ztk63lrd/components/button就是我們實時編寫的組件代碼:

import EButton from "@ztk63lrd/components/button"
// import { EButton } from "ease-reactify";const ButtonView = () => {return (<div><EButton size="middle" type="primary" shape="round" disabled>按鈕</EButton></div>)
}export default ButtonView

通過上面我們給封裝好的button組件添加類型限制之后,我們的bem規范已經被成功執行并且也出現在我們的運行項目上面了:

樣式解決方案

????????大家都知道作為一個組件庫我們要采用什么樣的色彩是尤為重要的,每一個熱門的組件庫都有它一套特定的色譜或者說是色彩系統,所以這時候我們就需要了解一下顏色對一個組件庫的構成模式,這里我們可以參考antd的對于色彩的一些講解:地址?文章還是比較詳細的介紹了系統色以及產品色的一些概念內容,對我們設計組件庫顏色方案給到了一個很好的啟發:

? ? ? ? 了解好樣式解決方案之后,接下來我們可以訪問?地址?來選擇我們開發組件的一個默認樣式:

? ? ? ? 除上面我們可以選擇顏色內容之后,我們也可以訪問如下網站來設計一下我們的button組件:

確認好最終的一個樣式方案之后,接下來我們開始正式對組件進行樣式的調整,這里我們采用的css預處理scss進行樣式調整,后期有精力的話也按照antd來設計全部用ts來寫樣式,目前的方案還是采用css處理器解決樣式問題,目前的話還是根據不同的作用劃分css文件,然后定義一些常用的方法和變量名來實現css樣式內容:

然后根據我們要設計的組件,給button設計不同狀態下的css樣式,其中用到了封裝好的公共的變量和css方法,如下所示:

最終我們在預覽界面中實現的效果如下所示:

組件單元測試

????????當我們編寫完組件之后,為了確保后期組件的穩定性,即使后面項目的迭代和變更也不會影響原組件的功能,這里我們需要借助組件的單元測試來確保組件的穩定性,我們組件開發使用單元測試的重要性主要有以下幾點原因:

1)高質量代碼

2)更早的發現bug,減少成本

3)讓重構和升級變得更加容易和可靠

4)讓開發流程更加敏捷

? ? ? ? 單元測試的方法有很多,因為我們采用的是vite作為打包器進行構建項目,所以這里我們也采用vite一派的單元測試工具 vitest 進行操作,詳情可以參考我之前的文章:地址?,vitest是兼容Jest的,所以說Vitest的api與Jest非常相似,用戶從Jest遷移到Vitest基本上沒啥學習成本:

接下來我們終端執行如下命令安裝測試插件:

pnpm install -D vitest

安裝完成之后,我們在vite的配置文件當中配置一下單元測試的一些關鍵配置:

當我們在相關組件下新建tests文件夾,就可以實現對組件的一些單元測試了:

瀏覽器模式與框架無關因此不提供任何渲染組件的方法。不過可以使用框架的測試工具包,這里我們采用如下的包進行組件測試,終端執行如下命令安裝:

pnpm install @testing-library/react @testing-library/jest-dom @testing-library/user-event -D

然后這里我們使用該三方庫中的render函數來測試渲染的組件庫內容,如下可以看到我們給按鈕設置的名稱通過函數拿到按鈕的文本,測試案例也正常通過了:

當然testing library旗下還有許多其他的工具,通過地址我們可以了解更多的測試工具的使用:

了解了一些工具的使用之后,接下來我們開始正式的對EButton組件進行單元測試,如下:

import { expect, test, describe, it, vi } from "vitest";
import { render, fireEvent } from "@testing-library/react"
import EButton, { ButtonProps } from "../index";
import '@testing-library/jest-dom'const defaultProps = {onClick: vi.fn()
}
const testProps: ButtonProps = {type: "primary",size: 'large',className: 'ease-test',
}
const disabledProps: ButtonProps = {disabled: true,onClick: vi.fn()
}describe("test EButton components", () => {it("應呈現正確的默認按鈕", () => {const wrapper = render(<EButton {...defaultProps}>測試按鈕</EButton>);const element = wrapper.getByText("測試按鈕") as HTMLButtonElement; // 獲取文本為"測試按鈕"的元素expect(element).toBeInTheDocument(); // 斷言該元素存在于文檔中expect(element.tagName).toBe("BUTTON"); // 斷言該元素的標簽名為"BUTTON"expect(element).toHaveClass("ease-button"); // 斷言該元素具有類名"ease-button"expect(element.disabled).toBeFalsy(); // 斷言該元素未被禁用fireEvent.click(element);expect(defaultProps.onClick).toHaveBeenCalled(); // 斷言onClick函數被調用});it("應根據不同的props渲染正確的組件", () => {const wrapper = render(<EButton {...testProps}>測試按鈕</EButton>);const element = wrapper.getByText("測試按鈕");expect(element).toBeInTheDocument();expect(element).toHaveClass("ease-button ease-button--primary ease-button--large ease-test");});it("禁用時應呈現禁用按鈕設置為true", () => {const wrapper = render(<EButton {...disabledProps}>測試按鈕</EButton>);const element = wrapper.getByText("測試按鈕") as HTMLButtonElement;expect(element).toBeInTheDocument(); // 斷言該元素存在于文檔中expect(element.disabled).toBeTruthy(); // 斷言該元素已被禁用expect(disabledProps.onClick).not.toHaveBeenCalled(); // 斷言onClick函數未被調用})
});

最終可以看到我們的測試用例代碼都通過了:

組件文檔搭建?

????????項目采用組件文檔進行代碼和具體相關展示,組件庫文檔有很多選擇,可以參考文章了解一下其他組件庫插件的實現,這里我們還是以vite衍生的組件庫文檔vitePress來實現,VitePress可以單獨使用也可以安裝到現有項目中,在這兩種情況下都可以使用以下方式安裝它:

npm add -D vitepress
npx vitepress init

安裝完插件之后根據自身情況進行選擇即可,如果正在構建一個獨立的VitePress站點可以在當前目錄 (./) 中搭建站點,但是如果在現有項目中與其他源代碼一起安裝VitePress,建議將站點搭建在嵌套目錄(例如 ./docs)中以便它與項目的其余部分分開:

安裝好插件之后,vitepress會自動幫助我們配置好環境命令,我們直接運行即可:

pnpm install markdown-it markdown-it-container markdown-it-mathjax3 -D

然后根據具體的一些官網配置進行調配即可:

GitHub Actions

????????GitHub Actions:是GitHub提供的一個自動化工具,它可以幫助開發者自動執行構建、測試、部署等任務,通過GitHub Actions開發者可以定義一系列的工作流(workflow),并且這些工作流可以在GitHub上的代碼庫發生特定事件時觸發,比如推送代碼、發起 pull 請求、發布版本等。

一個工作流通常由多個步驟(steps)組成,每個步驟可以執行不同的命令或者運行一個自定義的腳本,工作流是由yaml文件描述的,存放在項目的.github/workflows 目錄中,其特點主要包括:

1)自動化流程:自動執行重復的任務減少手動操作

2)GitHub緊密集成:可以直接在GitHub上定義和管理工作流

3)多平臺支持:支持Linux、macOS 和 Windows環境

4)自定義工作流:可以根據自己的需求創建自定義的工作流和步驟

5)與其他工具服務集成:可以與其他工具API或者云服務集成,擴展功能

此次我們組件庫的工作流,目前主要有兩個,如下所示:

部署組件庫文檔:該工作流設置了名稱,通過on來構建觸發工作流的時機是提交代碼

name: 'Deploy Docs'  # 工作流名稱on:push:branches:- masterjobs:build-and-deploy:runs-on: ubuntu-latestpermissions:contents: write  # 添加寫入權限steps:- name: 讀取倉庫內容uses: actions/checkout@v4  # 必須有uses來獲取代碼- name: 安裝pnpmuses: pnpm/action-setup@v2  # 添加這一步安裝pnpm- name: 安裝依賴run: pnpm install --no-frozen-lockfile   # 運行pnpm install來安裝依賴- name: 項目測試run: pnpm run test  # 運行pnpm測試項目- name: 構建項目run: pnpm run docs:build  # 運行構建文檔的命令- name: 部署GitHub Pagesuses: JamesIves/github-pages-deploy-action@v4  # 使用GitHub Actions來部署到gh-pageswith:branch: gh-pages  # 指定部署的分支folder: 'docs/dist'  # 指定構建后的文件夾路徑clean: true  # 清理舊的部署文件

發布npm平臺:該工作流設置了名稱,通過on來構建觸發工作流的時機是package發生變化

name: Release Packageon:push:branches:- masterpaths:- 'packages/package.json'  # 如果是 monorepo,監聽所有子包的 package.jsonjobs:release:runs-on: ubuntu-lateststeps:- name: 讀取倉庫內容uses: actions/checkout@v4with:fetch-depth: 0  # 獲取完整歷史,用于版本計算- name: Setup Node.jsuses: actions/setup-node@v3with:node-version: 21registry-url: https://registry.npmjs.org/- name: 安裝pnpmuses: pnpm/action-setup@v2- name: 安裝依賴(跳過鎖文件檢查)run: pnpm install --no-frozen-lockfile- name: 項目測試run: pnpm run test- name: 構建項目run: pnpm run build- name: 檢查待發布的包run: npx changeset status- name: 創建版本號run: npx changeset version --snapshot ${{ github.event.inputs.release-type }}- name: 登錄到npmrun: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc- name: 發布到npmrun: npx changeset publish --only ease-reactifyenv:NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

當我們提交代碼的時候就會觸發自動化流程,GitHub Actions就會自動幫我們執行對應的部署:

changeset版本

與git結合使用的一個特定文件或目錄結構,用于跟蹤和管理代碼的變更集,這通常出現在需要對代碼進行分組提交的場景或者在使用某些自動化工具、工作流、或 CI/CD過程中,終端執行如下命令進行安裝:

pnpm add @changesets/cli -D

其常用命令如下所示:

# 初始化
npx changeset init# 添加 changeset
npx changeset add
npx changeset# 版本
npx changeset version# 發布
npx changeset publish

這里我將其命令放在package中的配置腳本中,想要發布的時候執行如下命令即可:

目前部署的組件庫文檔:地址?,后期內容會不斷完善!

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

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

相關文章

中科米堆CASAIM金屬件自動3d測量外觀尺寸三維檢測解決方案

金屬零部件的外觀尺寸檢測直接關系到產品的裝配精度和使用性能。CASAIM基于激光掃描技術的自動化三維掃描系統&#xff0c;為金屬加工行業提供了高效的自動3D測量解決方案&#xff0c;有效解決了傳統檢測方式效率低、覆蓋面有限等問題。激光掃描技術在金屬件測量中優勢明顯。與…

開源數據同步中間件,支持MySQL、Oracle

DBSyncer&#xff08;英[dbs??k??(r)]&#xff0c;美[dbs??k??(r) 簡稱dbs&#xff09;是一款開源的數據同步中間件&#xff0c;提供MySQL、Oracle、SqlServer、PostgreSQL、Elasticsearch(ES)、Kafka、File、SQL等同步場景。支持上傳插件自定義同步轉換業務&#xff0…

中英混合的語音識別XPhoneBERT 監督的音頻到音素的編碼器結合 f0 特征LID

完整項目包獲取點擊文末名片完成一個 Code-Switching&#xff08;中英混合&#xff09;的語音識別系統&#xff0c;整個流程如下思路進行&#xff1a; 163. (Step 1) 訓練音頻到音素的編碼器&#xff08;Audio → Phoneme Encoder&#xff09; 你已經完成了此部分。核心思路是利…

Param關鍵字的使用

1&#xff1a;當一個方法的某一個參數個數不固定的時候&#xff0c;可以使用Param2:可變的方法參數必須定義為數組類型3&#xff1a;該參數必須放在方法參數的最后&#xff0c;應且只有一個4&#xff1a;參數必須為一維數組5&#xff1a;params不能和ref和out組合使用namespace…

京東云輕量云服務器與騰訊云域名結合配置網站及申請SSL證書流程詳解

京東云輕量云服務器與騰訊云域名結合配置網站及申請SSL證書流程詳解 1. 需求及實現效果 1.1. 需求 先說一下我當前情況&#xff0c;我目前有一個京東云服務器和一個在騰訊云旗下買的域名&#xff08;不要問為啥一個在京東云&#xff0c;一個在騰訊云&#xff0c;那自然是哪個…

Python入門Day14:面向對象編程初步(OOP入門)

學習目標&#xff1a;理解面向對象編程&#xff08;OOP&#xff09;的基本思想&#xff1a;類&#xff0c;對象掌握類的定義&#xff0c;構造方法&#xff0c;實例屬性和方法熟悉self的含義與作用學會用類組織和封裝代碼&#xff0c;初步構建自己的“對象世界”一、什么是面向對…

日志和指標標簽規范化方案

好的&#xff0c;設計一個有效的日志和指標標簽規范化方案對于構建可觀測性強、易于維護、關聯分析順暢的系統至關重要。混亂的標簽命名會極大增加查詢、聚合、告警和故障排除的難度。 以下是一個綜合性的標簽規范化方案建議&#xff0c;結合了行業最佳實踐&#xff1a; 核心目…

Windows和Linux的tree工具

目錄 1.前言 2.Linux的tree工具 2.1.安裝tree 2.2.常用命令與參數 2.3.常見應用場景 2.4.注意事項 3.Windows的tree工具 3.1.基礎語法 3.2.核心參數詳解 3.3.常見應用場景 3.4.局限性與增強方案 4.Windows 與 Linux tree 的核心差異 5.tree工具優勢 5.總結 相關…

[echarts] 更新數據

option {title: { text: 銷售數據 },tooltip: { trigger: axis },legend: { data: [銷量, 庫存] },xAxis: {type: category,data: [襯衫, 羊毛衫, 雪紡衫]},yAxis: { type: value },series: [{ name: 銷量, type: bar, data: [5, 20, 36] },{ name: 庫存, type: line, data: […

通過el-image實現點擊文字查看圖片,及其圖片列表

場景一&#xff1a;表格中有時候會有點擊文字查看圖片的功能&#xff08;因為表格的一個單元格不方便顯示多個圖片&#xff09;如下圖所示&#xff1a;對于這個需求&#xff0c;我們可以應對的方案是&#xff1a;在文字旁邊寫一個el-image圖默認顯示多張圖片中的第一張&#xf…

003 實習(前端jquery之輪播圖,學校網頁)

web前端,查詢官網:w3schoolHTML:負責網頁結構&#xff08;頁面元素和內容&#xff09;CSS:負責網頁的表現&#xff08;網頁元素的外觀、位置等頁面樣式&#xff0c;如顏色&#xff0c;大小&#xff09;JAVAScript:負責網頁的行為&#xff08;交互效果&#xff09;<a>:超鏈…

Mysql group by

臨時表與內存表 內存表是 Memory 引擎表&#xff0c;表的數據行都在內存。 臨時表可以使用各種引擎。 臨時表是線程私有表&#xff0c;其他線程不可見&#xff0c;不需考慮重名問題。 session 結束時臨時表會被自動刪除。 如果 Binlog_format row&#xff0c;則臨時表語句不進…

Linux(15)——進程間通信

目錄 一、進程間通信的介紹 ??進程間通信的目的 ??進程間通信的本質 進程間通信的分類 ??管道 ??System V IPC ??POSIX IPC 二、管道 &#x1f9e0;什么是管道 ??匿名管道 &#x1f4dd;匿名管道的原理 &#x1f4dd;pipe函數 &#x1f4dd;匿名管道…

【Flutter】雙路視頻播放方案

最近在做雙路視頻播放&#xff0c;就是在一個頁面播放兩個視頻。我遇到的問題就是音頻焦點沖突問題&#xff0c;在下面說明。什么是雙路視頻播放&#xff08;來自AI&#xff09;雙路視頻播放&#xff08;Dual-Video Playback&#xff09;&#xff0c;從字面上理解&#xff0c;就…

筆試——Day25

文章目錄第一題題目思路代碼第二題題目&#xff1a;思路代碼第三題題目&#xff1a;思路代碼第一題 題目 笨小猴 思路 模擬 統計每個字符出現的次數&#xff0c;用最大減最小&#xff0c;判斷是不是質數&#xff1b; 質數的判斷使用試除法&#xff1b; 代碼 第二題 題目&…

【C#學習Day15筆記】拆箱裝箱、 Equals與== 、文件讀取IO

前言在C#第15天的學習中&#xff0c;我深入探索了類型轉換機制、對象比較原理和文件操作技術三大核心主題。這些知識是構建高效、健壯程序的關鍵基礎。本文完整保留我的課堂實踐代碼和命名體系&#xff0c;通過結構化梳理幫助大家掌握這些核心概念。所有代碼示例均來自我的實際…

發電類電力業務許可證申請條件

基本條件&#xff1a;法人資格&#xff1a;申請人必須是依法注冊的企業法人。 財務能力&#xff1a;應具有與所申請從事的電力業務相適應的財務能力。 專業人員要求&#xff1a;生產運行負責人、技術負責人、安全負責人和財務負責人需具備至少3年以上與申請從事的電力業務相關的…

JavaScript 高效入門指南:從基礎到實戰(VSCode 版)

廢話不多說&#xff0c;直接上干貨&#x1f600; 一、先搞定工具&#xff1a;VSCode 配置成「JS 開發神器」 工欲善其事&#xff0c;必先利其器。用 VSCode 寫 JavaScript&#xff0c;這幾個配置能讓你效率翻倍&#xff1a; 1. 必裝插件&#xff08;直接在 VSCode 插件商店搜…

《人形機器人的覺醒:技術革命與碳基未來》——類人關節設計:柔性驅動革命之液壓人工肌肉

目錄&#xff1a;一、人工肌肉的種類及人形機器人適用情況二、人形機器人用人工肌肉科研機構及其最新成果進展三、液壓人工肌肉種類及工作機制四、液壓人工肌肉適用人形機器人的性能要求和局限性五、液壓人工肌肉材料技術進展及其限制與突破六、波士頓動力Spot的液壓靜液傳動系…

26數據結構-順序表

&#x1f4cc;有序順序表的合并 #define MAX_SIZE 20 struct SeqList {int data[MAX_SIZE];int length; }; void mergeArray(SeqList &L1,SeqList &L2,SeqList &L) {int i0,j 0;while(i<L1.length && j<L2.length){if(L1.data[i]<L2.data[j])L.da…