国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > JS > 正文

react寫一個select組件的實現代碼

2024-05-06 16:49:30
字體:
來源:轉載
供稿:網友

之前一直用的antd的Select組件,但在有些端并不適用,而原生的select樣式修改不靈活,遂產生自己寫一個組件的想法。觀察select組件:

<select onChange={(value) => {this.value=value}}  <option value='1'>man</option>  <option value='0'>woman</option></select>

可以看出數據都是在option中,有值value和顯示出來的數據一一對應。如果我們寫一個select組件,那么應該有onChange方法,應該要訪問到子元素,而且div是沒有value這個屬性的,所以option應該也是一個組件,有value屬性。下面是我寫的組件的用法:

import {MobileSelect, MobileOption} from '../../components/MobileSelect'; <MobileSelect  disabled={isDisabled}  value={data.clarity || ringResponse.clarity || 'Flawless'}  style={{ width: '132px' }}  onChange={(v) => this.changeDataValue('clarity', v)} >  {   (clarity || []).map((item, i) => {    return (     <MobileOption key={i + ''} value={item.code}>{item.title}</MobileOption>    );   })  } </MobileSelect>

可以看出其和一般的select組件用法差不多。效果如下:

react,select,組件,代碼

下面是組件

import {observable} from 'mobx';import {observer} from 'mobx-react';import React from 'react';import {Icon} from 'antd';import './index.less';interface IProps { disabled?: boolean; onChange?: (value) => void; value?: string | number; style?: React.CSSProperties; className?: string;}@observerexport class MobileSelect extends React.Component<IProps> { @observable showOption = false;   // 是否彈出下拉框 @observable value: any = '';    // 當前選中的value值 @observable text: any = '';     // 選中的value值對應的文本 @observable cell: any;       // 組件的dom節點 componentDidMount(): void {  // 獲取選擇框的ref,當在組件外點擊時的時候收起下拉框  document.addEventListener('click', (e) => {   if (this.cell && this.cell !== e.target && !this.cell.contains(e.target)) {    this.showOption = false;   }  }, true); } componentWillReceiveProps(nextProps: Readonly<IProps>, nextContext: any): void {  // 根據傳入的value值,遍歷children,找到對應值的展示文本  if (nextProps.value !== this.props.value || nextProps.children !== this.props.children) {   React.Children.map(this.props.children, (child, index) => {    if (nextProps.value === child.props.value) {     this.text = child.props.children;    }   });  } } render(): React.ReactNode {  const {children, value} = this.props;  console.log(value);  return (   <div    className={'Mobile-Select ' + this.props.className}    style={this.props.style}    ref={(node) => this.cell = node}   >    <div     className={'select-wrap'}     onClick={() => {      // 禁用不能彈出下拉框      if (!this.props.disabled) {       this.showOption = !this.showOption;      }     }}    >     <Icon type='down' style={this.showOption ? {transform: 'rotate(180deg)'} : {transform: 'rotate(0deg)'}} className={'select-icon'}/>     {this.text}    </div>    <div className={'option-wrap'} style={this.showOption ? {position: 'absolute'} : {display: 'none'}}>     {      React.Children.map(children, (child, index) => {       // 設置選中option和未選中option的樣式       let optionClassName = '';       if (this.props.value === child.props.value) {        optionClassName = child.props.className ? child.props.className + ' option-item selected' : 'option-item selected';       } else {        optionClassName = child.props.className + ' option-item';       }       return (        <div         onClick={() => {     // 為了在父組件給子組件添加onClick事件,包裹了一層div          // 有無onChange事件都能改變值          if (this.props.value && this.props.onChange) {           this.props.onChange(child.props.value);          } else {           this.text = child.props.children;           this.value = child.props.value;          }          console.log(this.value);          this.showOption = !this.showOption;         }}         style={this.props.style}         className={optionClassName}        >{child}</div>       );      })     }    </div>   </div>  ); }}interface OptionProps { value?: string | number; className?: string; style?: React.CSSProperties;}export class MobileOption extends React.Component<OptionProps> { render(): React.ReactNode {  const {children} = this.props;  return (   <div style={this.props.style}>    {children}   </div>  ); }}

下面是組件的樣式

.Mobile-Select { display: inline-block; min-width: 100px; margin: 0 6px; .select-wrap {  border: 1px solid #e0c0a2;  border-radius: 4px;  padding: 5px 11px;  display: flex;  flex-direction: row-reverse;  justify-content: space-between;  align-items: center;  .select-icon {   transition: .3s;   float: right;  } } .option-wrap {  box-shadow: 0 0 5px #333;  z-index: 1000;  border-radius: 5px;  .option-item {   background-color: #fff;   padding: 2px 11px;   min-width: 100px;   &.selected {    background-color: #fbe6d0;   }  } }}

總的來說只實現了select的基本功能。有改進的地方請指點一二。

PS:React Select默認值選中問題

import React from "react";import { render } from "react-dom";class App extends React.Component { constructor(props) {  super(props);  this.state = {   projects: [],   value: ""  }; } componentDidMount() {  // 模擬ajax調用,成功之后把需要改變的默認值賦值給this.state.value  setTimeout(() => {   this.setState({    projects: [     { id: 1, name: "花生" },     { id: 2, name: "蘋果" },     { id: 3, name: "楊桃" }    ],    value: 1   });  }, 3000); } handleClick() {  this.setState({   projects: [    { id: 4, name: "水果" },    { id: 5, name: "西瓜" },    { id: 6, name: "哈哈哈" }   ],   value: 4  }); } handleChange = e => {  this.setState({   value: e.target.value  }); }; render() {  let projects = this.state.projects;  return (   <div>    <button onClick={this.handleClick.bind(this)}>異步拉取數據</button>    {/* 這里不用再去判斷project的長度是否大于0,在ajax里面做判斷就行,如果小于零或者不存在它就是默認值 */}    <select     defaultValue=""     value={this.state.value}     onChange={this.handleChange}    >     {projects.length > 0 &&      projects.map((item, i) => {       return (        <option key={i} value={item.id}>         {item.name}        </option>       );      })}    </select>   </div>  ); }}render(<App />, document.getElementById("root"));

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永兴县| 砚山县| 城步| 黄梅县| 交城县| 沙洋县| 贵定县| 呼伦贝尔市| 永登县| 建平县| 屏南县| 阜宁县| 东山县| 衡南县| 图木舒克市| 高碑店市| 宝应县| 准格尔旗| 南郑县| 张掖市| 武邑县| 双牌县| 峨边| 元氏县| 城市| 陵川县| 深水埗区| 通渭县| 清镇市| 新野县| 西畴县| 临西县| 会东县| 晴隆县| 印江| 象山县| 无棣县| 水富县| 美姑县| 射阳县| 绩溪县|