目录
在做项目时引入一些现成的UI组件,但是如果和设计图冲突太大,更改时很麻烦,如果自己写一个通用组件其实也就几十分钟或者几个小时,而且更具UI设计更改也比较好更改,下面是两个简单的通用组件。
采用 react+ts+scss 进行开发。
如果你没有react+ts+scss项目,请看这个文章。
react项目https://blog.csdn.net/zxy19931069161/article/details/140117004?spm=1001.2014.3001.5501react项目这个文章顶部有一个现成的后台项目,可以这个基础上测试组件。
下面开始测试组件:
在src文件夹下新建components文件夹,用来放所有组件。
一、带输入框的Modal
效果如下,自行更改特别方便,内容:
在components文件夹下新建文件夹modalInput,modalInput文件夹下新建文件index.tsx和index.scss。
组件代码:
index.tsx
import './index.scss';
// 需要一个x,关闭图片,记得将图片放在这个路径下assets/images/,图片叫这个名字 icon-delete.png
import Delete from '../../assets/images/icon-delete.png'
import { useState } from "react";
function ModalInput(props: any) {
// 输入的文字,初始值为父元素传过来的值 props.systemNameData
// const [inputValueData, setInputValue] = useState(props.systemNameData)
// 输入的文字,初始值为空字符串
const [inputValueData, setInputValue] = useState('')
/**
* 取消
*/
function cancleClick() {
//执行父组件方法,关闭弹窗并将用户输入的值传给父组件
props.sendValueToFather(false, '');
setInputValue('')
}
/**
* 确定
*/
function sureClick() {
props.sendValueToFather(false, inputValueData);
setInputValue('')
}
/**
* 获得输入框输入的文字
* @param event input输入事件
*/
function inputValue(event: any) {
setInputValue(event.target.value)
}
return (
<div className='modal-input-box'>
<div className="modal-input-content">
<div className="modal-title">应用名称</div>
<img className="modal-delete" src={Delete} alt="关闭" onClick={cancleClick} />
<div className="modal-line"></div>
<div className="modal-content">
<div className="content-title">应用名称</div>
<input className="content-input" type="text" placeholder='请输入应用名称' onChange={inputValue} value={inputValueData} />
</div>
<div className="modal-cacle" onClick={cancleClick}>取消</div>
<div className="modal-sure" onClick={sureClick}>确定</div>
</div>
</div>
);
}
export default ModalInput;
index.scss
.modal-input-box {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.4);
z-index: 99;
.modal-input-content {
width: 560px;
padding: 24px 24px 58px 24px;
border-radius: 12px;
background: #FFF;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-sizing: border-box;
.modal-title {
color: #1E201F;
font-size: 16px;
line-height: 24px;
letter-spacing: -0.01px;
font-weight: bold;
}
.modal-delete {
width: 24px;
height: 24px;
position: absolute;
top: 24px;
right: 24px;
cursor: pointer;
}
.modal-line {
width: 560px;
height: 1px;
background: #EFF2F9;
position: absolute;
top: 64px;
left: 0;
}
.modal-content {
width: 512px;
padding: 32px 0;
position: relative;
.content-title {
font-size: 14px;
color: #505553;
margin-left: 38px;
padding-top: 8px;
}
.content-input {
width: 360px;
height: 34px;
line-height: 34px;
font-size: 14px;
position: absolute;
top: 32px;
left: 114px;
padding: 2px 10px 0px 10px;
margin: 0;
border-radius: 6px;
border: 1px solid #E8ECEB;
}
input:focus {
outline: 1px solid #00b498;
border-radius: 4px;
}
input:hover {
outline: 1px solid #00b498;
border-radius: 4px;
}
input::placeholder {
color: #A7AAA8;
}
}
.modal-cacle {
display: inline-block;
padding: 6px 24px;
border-radius: 6px;
border: 1px solid #DCDFE6;
font-size: 14px;
position: absolute;
bottom: 24px;
right: 112px;
cursor: pointer;
&:hover {
color: #00B498;
border: 1px solid #00B498;
}
}
.modal-sure {
display: inline-block;
padding: 6px 24px;
border-radius: 6px;
border: 1px solid #00B498;
font-size: 14px;
position: absolute;
bottom: 24px;
right: 24px;
background-color: #00B498;
color: #fff;
cursor: pointer;
&:hover {
background: #1BCEB2;
}
}
}
}
父组件引用时:
import ModalInput from "../.././components/modalInput";
import { useState } from "react";
function Home() {
// 系统名称输入弹窗是否显示
const [isShowModal, setIsShowModal] = useState(false)
// 系统名称
const [systemName, setSystemName] = useState('');
/**
* 系统名称输入弹窗,子元素给父元素传的,用户输入的内容
* @param param 是否关闭弹窗
* @param data 用户输入的内容
*/
function getValueFromSon(param: boolean, data: string) {
setIsShowModal(param);
if (data !== '') {
setSystemName(data);
// 传给后端,并刷新获取信息数据接口
}
}
return (
<div>
{isShowModal ? <ModalInput isShow={isShowModal} systemNameData={systemName} sendValueToFather={getValueFromSon}></ModalInput> : ''}
</div>
);
}
export default Home;
二、提示框Modal
在components文件夹下新建文件夹modalTip,modalTip文件夹下新建文件index.tsx和index.scss。
组件代码:
index.tsx
import './index.scss';
// 替换成自己的提示图标
import Delete from '../../assets/images/icon-delete.png' //右上角关闭图标
import Question from '../../assets/images/icon-question.png'//左上角弹窗类型,提问
import Error from '../../assets/images/icon-error.png'//左上角弹窗类型,错误
function ModalInput(props: any) {
// 提示弹窗类型,可以自行添加
//error 错误
//question 提问
//none 没有
// 父元素传过来的值
let data = {
type: props.type,// 弹窗类型,根据类型显示图标(错误/提问)
title: props.title,// 标题
content: props.content,//内容
}
/**
* 取消
*/
function cancleClick() {
props.sendValueToFather(false);
}
/**
* 确定
*/
function sureClick() {
props.sendValueToFather(true);
}
return (
<div className='modal-input-box'>
<div className="modal-input-content">
<div className="left-title">
{data.type === "question" ? <img className="modal-tip" src={Question} alt="提示标志" /> : " "}
{data.type === "error" ? <img className="modal-tip" src={Error} alt="提示标志" /> : " "}
<div className="modal-title">{data.title}</div>
</div>
<img className="modal-delete" src={Delete} alt="关闭" onClick={cancleClick} />
<div className="modal-content">
<div className="content-text">{data.content}</div>
</div>
<div className="modal-cacle" onClick={cancleClick}>取消</div>
<div className="modal-sure" onClick={sureClick}>确定</div>
</div>
</div>
);
}
export default ModalInput;
index.scss
.modal-input-box {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.4);
z-index: 99;
.modal-input-content {
width: 400px;
padding: 24px 24px 58px 24px;
border-radius: 12px;
background: #FFF;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-sizing: border-box;
.left-title {
height: 24px;
line-height: 24px;
.modal-tip {
width: 24px;
height: 24px;
margin-right: 6px;
float: left;
}
.modal-title {
display: inline;
color: #1E201F;
font-size: 16px;
letter-spacing: -0.01px;
font-weight: bold;
float: left;
}
}
.modal-delete {
width: 24px;
height: 24px;
position: absolute;
top: 24px;
right: 24px;
cursor: pointer;
}
.modal-content {
width: 512px;
padding: 14px 0 24px 0;
position: relative;
.content-text {
width: 348px;
font-size: 14px;
color: #666;
padding-top: 8px;
word-break: break-all;
text-align: justify;
text-justify: inter-word;
line-height: 22px;
}
}
.modal-cacle {
display: inline-block;
padding: 6px 24px;
border-radius: 6px;
border: 1px solid #DCDFE6;
font-size: 14px;
position: absolute;
bottom: 24px;
right: 112px;
cursor: pointer;
&:hover {
color: #00B498;
border: 1px solid #00B498;
}
}
.modal-sure {
display: inline-block;
padding: 6px 24px;
border-radius: 6px;
border: 1px solid #00B498;
font-size: 14px;
position: absolute;
bottom: 24px;
right: 24px;
background-color: #00B498;
color: #fff;
cursor: pointer;
&:hover {
background: #1BCEB2;
}
}
}
}
组件调用:
import ModalTip from "../.././components/modalTip";
import { useState } from "react";
function Home() {
// 系统名称输入弹窗是否显示
const [isShowModal, setIsShowModal] = useState(false)
/**
* 子元素传给父元素的结果
* @param param 取消/确定
*/
function getValueFromSon(param: boolean) {
setIsShowModal(false);
if (param) {
//用户点击确定
}else{
//用户点击取消
}
}
return (
<div>
{isShowModal ? <ModalTip type={'question'} title={"确定删除吗?"} content={"删除后不可恢复哦~"} sendValueToFather={getValueFromSon}></ModalTip> : ''}
</div>
);
}
export default Home;
三、搜索栏Search
在components文件夹下新建文件夹search,search文件夹下新建文件index.tsx和index.scss。
组件代码:
index.tsx
import './index.scss';
import { useState } from "react";
// 搜索图标,记得添加
import SearchIcon from "../../assets/images/icon-search.png";
function Search(props: any) {
const [inputValueData, setInputValue] = useState("")
/**
* 获得输入框输入的文字
* @param event input输入事件
*/
function inputValue(event: any) {
setInputValue(event.target.value)
}
/**
* 用户点击了键盘回车按钮
* @param e 元素信息
*/
function search(e: any) {
if (e.keyCode === 13) {
toFather()
// 用户按下回车后,让input元素失去焦点
var inputElement: any = document.getElementById('myInput');
inputElement.blur();
}
}
/**
* 将用户输入的内容传给父元素
*/
function toFather() {
props.searchValue(inputValueData)
}
return (
<div>
<input id="myInput" className="edu-Manage-input" type="text" placeholder={props.placeholder} onChange={inputValue} value={inputValueData} onKeyUp={search} />
<img className="edu-Manage-search" src={SearchIcon} alt="搜索" onClick={toFather} />
</div>
);
}
export default Search;
index.scss
.edu-Manage-input {
width: 240px;
height: 34px;
line-height: 34px;
font-size: 14px;
padding: 2px 0px 0px 34px;
margin: 0;
border-radius: 6px;
border: 1px solid #E8ECEB;
cursor: pointer;
}
.edu-Manage-search {
width: 14px;
height: 14px;
position: absolute;
left: 28px;
top: 28px;
cursor: pointer;
z-index: 99;
&:hover {
input {
outline: 1px solid #00b498;
border-radius: 4px;
}
}
}
input:focus {
outline: 1px solid #00b498;
border-radius: 4px;
}
input:hover {
outline: 1px solid #00b498;
border-radius: 4px;
}
input::placeholder {
color: #A7AAA8;
}
组件调用:
import Search from "../.././components/search";
function Home() {
/**
* 搜索组件返回用户搜索的字符串
* @param value 用户搜索的字符串
*/
function getSearchData(value: string) {
console.log(value)
}
return (
<div>
<Search placeholder="请输入姓名" searchValue={getSearchData}></Search>
</div>
);
}
export default Home;