react結(jié)合typescript?封裝組件實例詳解
項目環(huán)境搭建
項目依賴
創(chuàng)建支持 TypeScript 的 React 項目
npx create-react-app my-demo --template typescript
根據(jù) typescript 官網(wǎng)文檔的說明,還可以使用下面的命令
npx create-react-app my-demo --scripts-version=react-scripts-ts
css樣式初始化的插件
npm install --save normalize.css
處理scss文件
npm install node-sass --save
一個簡單的、有條件的綁定多個 className 的 JavaScript 實用函數(shù)
npm install classnames
@types 支持全局和模塊類型定義
npm install @types/classnames --save
項目目錄結(jié)構(gòu)
my-demo |—— node_modules |—— public | └─ favicon.ico | └─ index.html | └─ manifest.json |—— src | └─ ... |─ .gitignore |─ package.json |─ package-lock.json |─ README.md └─ tsconfig.json //文件中指定了用來編譯這個項目的根文件和編譯選項
創(chuàng)建一個組件
在項目中 刪除src目錄下除src/index.tsx之外所有的文件
import React from 'react';
import ReactDOM from 'react-dom/client';
import Hello from './src/Hello'
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<div>hellow TS</div>
);
在src下創(chuàng)建 Hello.tsx文件
import React form 'react'
//聲明 Hello 組件 props 接口類型
interface BaseProps {
message?:string //可選填 string 類型
}
const Hello:FunctionComponent<BaseProps> =(props) => {
/*
FunctionComponent<BaseProps> 接口,接收一個泛型
+ 使用 interface 定義的 BaseProps j接口作為泛型值
+ 組件還可以接收 props.chilren 屬性接收組件實例傳入的子節(jié)點
+ 使用 defaultProps 為 props 對象中屬性設置初始化值
+ React.FunctionComponent 可以簡寫為 const Hello: FC<BaseProps> = (props) => {}
*/
return <h1>{props.message}</h1>
}
在終端執(zhí)行 npm start啟動項目查看結(jié)果
封裝一個Button組件
Button按鈕需求分析

依賴
classnames: 一個簡單的 JavaScript 實用程序,用于有條件地將 classNames 連接在一起
$ npm install classnames --save
$ npm install @types/classnames --save //@types 支持全局和模塊類型定義
用于編譯css
npm install node-sass --save
classnames 使用示例
/* 與Node.js、Browserify或webpack 一起使用: */
var classNames = require('classnames');
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
/* // lots of arguments of various types */
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'
// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
/* 與 React.js 一起使用 */
/* 這個包是 的官方替代品classSet,它最初是在 React.js 插件包中提供的。
它的主要用例之一是使動態(tài)和條件className道具更易于使用(尤其是比條件字符串操作更簡單)。因此,您可能有以下代碼來className為<button>React 中的a生成道具: */
class Button extends React.Component {
// ...
render () {
var btnClass = 'btn';
if (this.state.isPressed) btnClass += ' btn-pressed';
else if (this.state.isHovered) btnClass += ' btn-over';
return <button className={btnClass}>{this.props.label}</button>;
}
}
/* 您可以將條件類更簡單地表示為一個對象: */
var classNames = require('classnames');
class Button extends React.Component {
// ...
render () {
var btnClass = classNames({
btn: true,
'btn-pressed': this.state.isPressed,
'btn-over': !this.state.isPressed && this.state.isHovered
});
return <button className={btnClass}>{this.props.label}</button>;
}
}
/*因為您可以將對象、數(shù)組和字符串參數(shù)混合在一起,所以支持可選的classNameprops 也更簡單,因為結(jié)果中只包含真實的參數(shù): */
var btnClass = classNames('btn', this.props.className, {
'btn-pressed': this.state.isPressed,
'btn-over': !this.state.isPressed && this.state.isHovered
});
在src新建components/Button/buttom.tsx組件
import React,{ ButtonHTMLAttributes, AnchorHTMLAttributes, FC } from 'react'
import classNames form 'classnames'
//聲明按鈕尺寸-枚舉
export enum ButtonSize {
Large = 'lg',
Small = 'sm'
}
//聲明按鈕樣式-枚舉
export enum ButtonType{
Primary = 'primary',
Default = 'default',
Danger = 'danger',
Link = 'link'
}
//聲明按鈕組件 props 接口
interface BaseButtonProps {
className?: string;
/*設置 Button的禁用*/
disabled?:boolean;
/*設置 Button的尺寸*/
size?:ButtonSize;
/*設置 Button 的類型*/
btnType?:ButtonType;
children: React.ReactNode; //ReactNode reactnode節(jié)點
/*設置A標簽href的類型*/
href?:string;
}
//聲明按鈕與超鏈接標簽的原生事件
type NativeButtonProps = BaseButtonProps & ButtonHTMLAttributes<HTMLElement>
type AnchorButtonProps = BaseButtonProps & AnchorHTMLAttributes<HTMLElement>
export type ButtonProps = Partial<NativeButtonProps & AnchorButtonProps>
export conast Button:FC<ButtonProps> = (props) =>{
const {
btnType, //傳遞進來按鈕樣式屬性
className, //傳遞進來自定義樣式屬性
disabled, //傳遞進來是否禁用屬性
size,
children,
href,
...restProps //解析按鈕與超鏈接的原生事件屬性
} = props;
/*樣式拼接處理*/
const classes = classNames('btn', className, {
/*[`btn-${btnType}`] : boolean
boolean:
+ 為真返回 [`btn-${btnType}`]
+ 為假 不返回任何內(nèi)容
*/
[`btn-${btnType}`]: btnType,
[`btn-${size}`]:size,
'disabled':(btnType === 'link') && disabled //如果傳遞btnType的屬性值為link并設置disabled屬性,按鈕就是禁用狀態(tài)。
});
if(btnType === "link" && href){
return (
<a
className={classes}
href={href}
{...restProps} //解析按鈕與超鏈接的原生事件屬性
>
{children}
</a>
)
}else{
return(
<button
className={classes}
disabled={disabled}
{...restProps}
>
{children}
</button>
)
}
}
/*定義 props 的默認值*/
Button.defaultProps = {
disabled:false,
btntype:ButtonType.Default,
btntype:ButtonSize.Large,
}
export default Button;
添加默認樣式
npm install --save normalize.css
在src目錄先新建styles文件夾,在styles文件夾下新建index.css | index.scss文件
在styles/index.css文件中引入normalize.css & components/Button/buttom.css
在src/index.tsx文件中引入styles/index.css
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.scss'
import App from './App';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
在src新建components/Button/buttom.css | buttom.scss組件
.btn {
position: relative;
display: inline-block;
font-weight: 400;
line-height: 1.5;
white-space: nowrap;
text-align: center;
vertical-align: middle;
background-image: none;
border: 1px solid transparent;
border-radius: 0.25rem;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
cursor: pointer;
}
.btn-danger {
color: #fff;
background: #dc3545;
border-color: #dc3545;
}
.btn-primary {
color: #fff;
background: #0d6efd;
border-color: #0d6efd;
}
.btn-lg {
padding: 0.5rem 1rem;
font-size: 1.25rem;
border-radius: 0.3rem;
}
.btn-sm {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
border-radius: 0.2rem;
}
.btn-xxx {
width:200px;
height:200px;
}
.btn-link {
font-weight: 400;
color: #0d6efd;
text-decoration: none;
box-shadow: none;
}
.disabled,
.btn[disabled]{
cursor: not-allowed;
opacity: 0.65;
box-shadow: none;
}
在scr/App.tsx組件中引入Button組件
import React from 'react';
// 導入Button 組件
import Button,{ButtonType,ButtonSize} from './conponents/Button/button';
/*Button組價可選屬性
組件類型
ButtonType.Primary = 'primary'
ButtonType.Default = 'default'
ButtonType.Danger = 'danger'
ButtonType.Link = 'link'
組件大小
ButtonSize.Large = 'lg'
ButtonSize.Small = 'sm'
*/
function App() {
return (
<div className="App">
<Button autoFocus>Hello</Button>
<Button className='btn-xxx'>Hello</Button>
<Button disabled>Disabled Button</Button>
<Button btnType={ButtonType.Primary} size={ButtonSize.Large}>Primary-Lrage-Button</Button>
<Button btnType={ButtonType.Danger} size={ButtonSize.Small}>Danger-Small-Button</Button>
<Button btnType={ButtonType.Link} disabled>被禁用的按鈕</Button>
<Button btnType={ButtonType.Link} target='target'>在新窗口打開</Button>
</div>
);
}
export default App;
在當前項目終端組輸入npm start啟動項目查看結(jié)果


以上就是react結(jié)合typescript 封裝組件實例詳解的詳細內(nèi)容,更多關于react typescript 封裝組件的資料請關注腳本之家其它相關文章!
相關文章
React18從0實現(xiàn)dispatch?update流程
這篇文章主要為大家介紹了React18從0實現(xiàn)dispatch?update流程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01
React-hooks面試考察知識點匯總小結(jié)(推薦)
這篇文章主要介紹了React-hooks面試考察知識點匯總,Hook?使你在無需修改組件結(jié)構(gòu)的情況下復用狀態(tài)邏輯,本文結(jié)合示例代碼給大家介紹的非常詳細,需要的朋友可以參考下2022-10-10
React + Threejs + Swiper 實現(xiàn)全景圖效果的完整代碼
全景圖效果非常漂亮給人帶來極好的用戶體驗效果,那么基于前端開發(fā)如何實現(xiàn)這種效果呢,下面小編給大家?guī)砹薘eact + Threejs + Swiper 實現(xiàn)全景圖效果,感興趣的朋友一起看看吧2021-06-06
引入代碼檢查工具stylelint實戰(zhàn)問題經(jīng)驗總結(jié)分享
eslint的配置引入比較簡單,網(wǎng)上有比較多的教程,而stylelint的教程大多語焉不詳。在這里,我會介紹一下我在引入stylelint所遇到的坑,以及解決方法2021-11-11
更強大的React 狀態(tài)管理庫Zustand使用詳解
這篇文章主要為大家介紹了更強大的React 狀態(tài)管理庫Zustand使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
forwardRef?中React父組件控制子組件的實現(xiàn)代碼
forwardRef 用于拿到父組件傳入的 ref 屬性,這樣在父組件便能通過 ref 控制子組件,這篇文章主要介紹了forwardRef?-?React父組件控制子組件的實現(xiàn)代碼,需要的朋友可以參考下2024-01-01

