• 前端004/React常用UI组件


    每天进步一点点〜

    Ant Design of React //蚂蚁金服设计平台。需要应用何种类型组件可参考API

    React + mobx + nornj 开发模式文件说明:

    【1】。A.t.html (.html / .scss / .js  /  文件包路径:src/web/pages)

              -->html代码 (页面设计,各种标签。标签有哪些属性及用法参考“Ant Design of React”) /

    【2】。A.m.scss

              -->样式 (页面显示样式统一管理)  /

    【3】。A.js

              --> javascript代码,事件操作。  /

    【4】。AStore.js  (src/stores/pages包下面)

              -->路由页面 (用于与后端交互,获取数据,并将数据返回给A.js,render渲染到页面)/

    (一)。Modal对话框:

    项目需求:注册一个用户,当用户点击“注册”按钮时,会将之前注册的数据替换掉。因此,需要提示两次,以警示用户“确定要注册!”

    该代码实现:较验文本数据必填 & 正则 |  比较密码输入是否一致 | 弹出提示框

    实现代码/html :

     1 <!--注册用户-->
     2 <template name="registUser">
     3   <ant-Modal width={668} visible="{certificateregistList.showRegistUser}" footer={null} onCancel={onAddModalCancel}>
     4     <ant-Tabs>
     5       <ant-TabPane tab="注册用户" />     
     6     </ant-Tabs>  
     7     <fj-Row class="{styles.btn}">
     8       <fj-Col offset="2"  l="8" >
     9         <ant-Form  onSubmit={handleRegister}>
    10           <ant-FormItem  label="用户名"   {...formItemParams()}>
    11             <#userID>
    12               <ant-input class="{styles.input}" placeholder="请输入用户名!"/>
    13             </#userID>  
    14           </ant-FormItem>
    15           <ant-FormItem  label="密码"   {...formItemParams()}>
    16             <#userPwd>
    17               <ant-input type="password" class="{styles.input}" placeholder="请输入用户密码!"/>
    18             </#userPwd>  
    19           </ant-FormItem>
    20           <ant-FormItem  label="确认密码"   {...formItemParams()}>
    21             <#userConfirmPwd>
    22               <ant-input type="password" class="{styles.input}" placeholder="请再次输入密码!"/>
    23             </#userConfirmPwd>  
    24           </ant-FormItem>
    25           <ant-FormItem  label="最大次数"   {...formItemParams()}>
    26             <#maxNum>
    27               <ant-input class="{styles.input}" placeholder="可以重复申请的最大次数!"/>
    28             </#maxNum>  
    29           </ant-FormItem>
    30           <div class="{styles.deploy_button}">
    31             <ant-Button style="margin-left:168px;" type="primary" class="btn" htmlType="submit" disabled="{certificateregistList.showRegistBtn}">注册</ant-Button> 
    32           </div>
    33         </ant-Form>
    34       </fj-Col>
    35     </fj-Row>
    36   </ant-Modal>
    37 </template>
    View Code

    实现代码/js :

      1 //注册用户
      2 @registerTmpl('RegistUser')
      3 @inject('store')
      4 @Form.create()
      5 @observer
      6 export class RegistUser extends Component{
      7     // 用户名
      8     userID(options) {
      9         return this.props.form.getFieldDecorator('userID', {
     10             rules: [{ required: true, message: '请填写用户名!' }],
     11         })(options.result());
     12     }
     13 
     14     // 用户密码
     15     userPwd(options) {
     16         return this.props.form.getFieldDecorator('userPwd', {
     17             rules: [{ required: true, message: '请填写用户密码!' },
     18                     {pattern:/^[a-zA-Z]w{5,19}$/,message: '密码只能以字母开头,长度在6~20,只能包含字母、数字和下划线!' },],
     19         })(options.result());
     20     }
     21 
     22     // 重复用户密码
     23     userConfirmPwd(options) {
     24         return this.props.form.getFieldDecorator('userConfirmPwd', {
     25             rules: [{ required: true, message: '请确认用户密码!' },
     26                     {pattern:/^[a-zA-Z]w{5,19}$/,message: '密码只能以字母开头,长度在6~20,只能包含字母、数字和下划线!' },
     27                     {validator: this.verifyPassword,}],
     28         })(options.result());
     29     }
     30 
     31     //重复申请证书的最大次数
     32     maxNum(options){
     33         return this.props.form.getFieldDecorator('maxNum', {
     34         rules: [{ required: true, message: '请填写申请证书最大次数!' },
     35                 {pattern:/^([1-9]|10)$/,message: '请输入>0且<=10的正整数数字!' }],
     36         })(options.result());
     37     }
     38 
     39     //较验两次输入密码是否一致
     40     verifyPassword = (rule, value, callback) => {
     41         const form = this.props.form;
     42         if (value && value !== form.getFieldValue('userPwd')) {
     43           callback('两次输入密码不一致!');
     44         } else {
     45           callback();
     46         }
     47     }
     48 
     49     //取消【遮罩】
     50     @autobind
     51     onAddModalCancel() {
     52         this.props.store.certificateregistList.setShowRegistUser(false);
     53     }
     54 
     55     //注册提交
     56     @autobind
     57     handleRegister(e){
     58         const { store: { certificateregistList } } = this.props;
     59         e.preventDefault(); //阻止未填项
     60         this.props.form.validateFields((err, values) => {
     61             if (!err) {
     62                 var attrs=[{
     63                     "Name":"hf.Revoker",
     64                     "Value":"true",
     65                 }]
     66 
     67                 let param={
     68                     "ID":  values.userID,
     69                     "Type": "user", //用户类型,要求固定值为user
     70                 }
     71                 
     72                 //弹出框警告提示
     73                 Modal.confirm({
     74                     title: '注册后,已有用户将会被覆盖!!!',
     75                     content: '',
     76                     onOk() {  //确认后再提示。。
     77                         Modal.confirm({
     78                             title: '确认注册新用户!!!',
     79                             content: '已有用户将会被覆盖...',
     80                             onOk() {  //确认后注册
     81                                 const closeLoading = Message.loading('正在保存数据...', 0);
     82                                 certificateregistList.setShowRegistBtn(true); //控制注册按钮显示
     83                                 Promise.all([
     84                                     certificateregistList.getRegister(param), //注册用户
     85                                 ]).then(()=> {
     86                                     certificateregistList.setShowRegistBtn(false);
     87                                     closeLoading();
     88                                 });
     89                             },
     90                             onCancel() {},
     91                         });
     92                     },
     93                     onCancel() {},
     94                 });
     95             }
     96         });
     97     }
     98 
     99     render() {
    100         const { store: { certificateregistList } } = this.props;
    101         return tmpls.registUser(this.props, this, {
    102             styles,
    103             certificateregistList,
    104         });
    105     }
    106 } 
    View Code

    (二)。Tag标签:

    业务需求:数据动态加载,每行后追加一个Tag标签,点击Tag标签后,对应显示文本框,可以录入值并将值进行显示。。。

    效果:

    代码如下所示:

    【1】。html

     1 <template name="storageExpand">
     2   <ant-Form onSubmit={handleSubmit} layout="vertical">
     3   <p><b>存储名称:</b>{xx.xx.name}</p>
     4   <#each {{nodeList}}>
     5     <p>
     6       <b>Node{{@index | +(1)}}:</b><br/>
     7         <#each {{xx}}>
     8           {{this}},
     9         </#each>
    10         </b>&nbsp;&nbsp;IP:
    11         <#each {{xx}}>
    12           {{this}},
    13         </#each>
    14         </b>&nbsp;&nbsp;设备:
    15         <#each {{xx}}>
    16           {{this}},
    17         </#each>
    18         
    19         <!--tag标签值-->
    20         <#each {{tags}}>
    21           <#if {{isLongTag}}>
    22             <ant-Tooltip title={@item} key={@item}>
    23               {tagItem(@item,@index)}
    24             </ant-Tooltip>
    25             <#else>
    26               {tagItem(@item,@index)}
    27             </#else>
    28           </#if>
    29         </#each>
    30 
    31         <!--控制显示tag标签还是文本框,初始显示tag标签-->
    32         <#if {{inputVisible}}>
    33             {inputItem(@index)}
    34           <#else>
    35             {addItem(@index)}
    36           </#else>
    37         </#if>
    38     </p>
    39   </#each>
    40   <p><b>存储:</b>{xx || ""}</p>
    41   <p><b>Master:</b>{{xx ? ('', '') }}</p>
    42   <div class="{styles.btnArea}">
    43       <ant-Button class="{styles.btn}" type="primary" htmlType="submit" disabled="{showExpand}">扩容</ant-Button>
    44   </div>
    45   </ant-Form>
    46 </template>
    View Code

    【2】。js

      1 import React, { Component } from 'react';
      2 import { findDOMNode } from 'react-dom';
      3 import { observable, computed, toJS } from 'mobx';
      4 import { observer, inject } from 'mobx-react';
      5 import nj from 'nornj';
      6 import { registerTmpl } from 'nornj-react';
      7 import { autobind } from 'core-decorators';
      8 import Input from 'flarej/lib/components/antd/input';
      9 import Icon from 'flarej/lib/components/antd/icon';
     10 import Tag from 'flarej/lib/components/antd/tag';
     11 import Message from 'flarej/lib/components/antd/message';
     12 import Form from 'flarej/lib/components/antd/form';
     13 import Notification from '../../../utils/notification';
     14 import styles from './storageManager.m.scss';
     15 import tmpls from './storageManager.t.html';
     16 
     17 //存储扩容功能
     18 @registerTmpl('StorageExpand')
     19 @inject('store')
     20 @Form.create()
     21 @observer
     22 export default class StorageExpand extends Component{
     23   @observable nodeList=[]; //获取设备信息,组成新数组对象。
     24   @observable obj = {
     25     inputVisible: false,
     26     tags: [],
     27   }
     28   @observable inputVisible=false; //控制显示tag标签 OR 文本框
     29   @observable inputValue='';   //文本框输入值
     30   @observable isLongTag = false; //是否是长字符,控制是否显示Tooltip
     31   @observable showExpand=false;  //控制显示【扩容】按钮
     32 
     33   componentWillMount() {
     34     const { store: { storageManager } } = this.props;  
     35     this.nodeList = storageManager && storageManager.xx && storageManager.xx.xx;
     36     this.nodeList = this.nodeList.map((value, key)=>{
     37       return value = {...value, ...this.obj};
     38     });
     39   }
     40 
     41   componentDidUpdate() {
     42    
     43   }
     44 
     45   //当inputVisible=false时,显示tag标签.(即初始进入显示tag标签)
     46   addItem = (index) => (
     47     <Tag  
     48       onClick={()=>this.showInput(index)}><Icon type="plus" />添加
     49     </Tag> 
     50   )
     51 
     52   //点击tag标签,添加时,显示文本框。
     53   showInput = (index) => {
     54     this.nodeList[index].inputVisible=true;
     55   }
     56 
     57   //点击tag标签,显示文本框供用户录入数据
     58   inputItem = (index) => (
     59     <Input
     60         type="text"
     61         size="small"
     62         style={{"width": 78}}
     63         value={this.inputValue}
     64         onChange={this.handleInputChange}
     65         onBlur={()=>this.handleInputConfirm(index)}
     66         onPressEnter={()=>this.handleInputConfirm(index)}
     67     />
     68   )
     69 
     70   handleInputChange = (e) => {
     71     this.inputValue=e.target.value;
     72     this.isLongTag = this.inputValue.length >= 20 ? true : false;
     73   }
     74 
     75   handleInputConfirm = (index) => {
     76     const inputValues = this.inputValue;
     77     let newTags = this.nodeList[index].tags ? [...this.nodeList[index].tags] : []
     78     if (inputValues && newTags.indexOf(inputValues) === -1) {
     79       newTags = [...newTags, inputValues];
     80     }
     81     this.nodeList[index].tags=newTags;
     82     this.inputValue='';
     83     this.nodeList[index].inputVisible=false;
     84   }
     85 
     86   //文本框失去焦点后,将值赋给tag标签,用于在页面显示。
     87   tagItem = (tag, index) => {
     88     return (
     89       <Tag 
     90         key = {tag} 
     91         closable = {index !== -1} 
     92         afterClose = {() => this.handleClose(tag, index)}
     93       >
     94         {this.isLongTag ? `${tag.slice(0, 20)}...` : tag}
     95       </Tag>
     96     )
     97   };
     98   
     99 
    100   //移出添加的标签内容
    101   handleClose = (removedTag, index) => {
    102     const newTags = this.nodeList[index].tags.filter(tag => tag !== removedTag); 
    103     this.nodeList[index].tags=newTags;
    104   }
    105 
    106   //扩容触发事件
    107   @autobind
    108   handleSubmit(e){
    109     const { store: { storageManager } } = this.props;
    110     e.preventDefault();
    111     var storageContent=[];
    112     this.nodeList.map((value, key)=>{
    113       var option = {
    114         "manage":[],
    115         "storage":[],
    116         "devices":[],
    117         "zone": 1
    118       };
    119       option.manage.push(this.nodeList[key].manage[0]);    //节点名
    120       option.storage.push(this.nodeList[key].storage[0]);  //IP
    121       option.devices.push(this.nodeList[key].devices[0]);
    122       for(let i=0;i<this.nodeList[key].tags.length;i++){
    123         option.devices.push(this.nodeList[key].tags[i]);  //设备-新添加
    124       }      
    125       storageContent.push(option);
    126     });
    127     let param={
    128       "xx":xx
    129     };
    130     this.showExpand=true; //控制按钮不可用
    131     const closeLoading = Message.loading('正在保存数据...', 0);
    132     Promise.all([
    133       storageManager.getSaveStorage(param), //保存数据
    134     ]).then(() => {
    135       this.showExpand=false;
    136       closeLoading();
    137     });
    138   }
    139   
    140   render() {
    141     const { store: { storageManager } } = this.props;
    142     return tmpls.storageExpand(this.state, this.props, this, {
    143       styles,
    144       storageManager,
    145     });
    146   }
    147 }
    View Code
  • 相关阅读:
    Python3之json模块
    How To Enable EPEL Repository in RHEL/CentOS 7/6/5?
    安装CentOS 6.x出现Disk sda contains BIOS RAID metadata
    详解hdparm: linux下的硬盘测速工具
    {转载}需要同时设置 noatime 和 nodiratime 吗?
    ubuntu17.10安装LAMP并测试部署php探针系统
    shell监控网卡状态,故障时自动重启网卡
    L2TP/IPSec一键安装脚本
    Linux系统下用find命令查找最近修改过的文件
    Hyper-V 手动导入虚机配置实例(转载)
  • 原文地址:https://www.cnblogs.com/kaixinyufeng/p/9288982.html
Copyright © 2020-2023  润新知