今天小编给大家分享一下react结合typescript封装组件的方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
项目环境搭建
项目依赖
创建支持 TypeScript 的 React 项目
npx create-react-app my-demo --template typescript
根据 typescript 官网文档的说明,还可以使用下面的命令
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 实用函数
npm install classnames
@types 支持全局和模块类型定义
npm install @types/classnames --save
项目目录结构
my-demo |—— node_modules |——public | └─ favicon.ico | └─ index.html | └─ manifest.json|—— src| └─ ... |─ .gitignore |─ package.json |─ package-lock.json |─ README.md └─ tsconfig.json //文件中指定了用来编译这个项目的根文件和编译选项
创建一个组件
在项目中 删除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下创建 Hello.tsx文件
import React form 'react'//声明 Hello 组件 props 接口类型interface BaseProps { message?:string //可选填 string 类型}const Hello:FunctionComponent<BaseProps> =(props) => { return <h2>{props.message}</h2> }
在终端执行 npm start启动项目查看结果
封装一个Button组件
Button按钮需求分析
依赖
classnames: 一个简单的 JavaScript 实用程序,用于有条件地将 classNames 连接在一起
$ npm install classnames --save
$ npm install @types/classnames --save //@types 支持全局和模块类型定义
用于编译css
npm install node-sass --save
classnames 使用示例
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'classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'// other falsy values are just ignoredclassNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1' 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>;}}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; disabled?:boolean; size?:ButtonSize; btnType?:ButtonType; children: React.ReactNode; //ReactNode reactnode节点 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}`]: btnType, [`btn-${size}`]:size, 'disabled':(btnType === 'link') && disabled //如果传递btnType的属性值为link并设置disabled属性,按钮就是禁用状态。 }); if(btnType === "link" && href){ return ( <a className={classes} href={href} {...restProps} //解析按钮与超链接的原生事件属性 > {children} </a> ) }else{ return( <button className={classes} disabled={disabled} {...restProps} > {children} </button> ) }}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';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} href='http://www.xxx.com' disabled>被禁用的按钮</Button> <Button btnType={ButtonType.Link} href='http://www.xxx.com' target='target'>在新窗口打开</Button> </div> );}export default App;
在当前项目终端组输入npm start启动项目查看结果
以上就是“react结合typescript封装组件的方法是什么”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。