Ant Design Demo 学习

1.DEMO安装

1.1.前端安装

下载最新的Node

 下载GIT并且安装,安装好后用管理员模式执行git-bash.exe 

 VSCODE导入项目:

1.2.后端安装

需要本机支持Maven,没有需要安装配置好。然后开始下载脚手架:

 STS载入项目:

1.3.数据库安装

导入一个示例SQL脚步:

 

 配置数据库参数:

 1.4.DEMO运行效果

http://localhost:8000,使用admin,1登陆

 

2.DEMO学习

2.1.前端学习-概览

首先建议学习官方知识

https://3x.ant.design/docs/react/introduce-cn

https://v2-pro.ant.design/

React基础学习:

http://caibaojian.com/react/

https://reactjs.org/docs/hello-world.html

http://www.ruanyifeng.com/blog/2015/03/react.html

2.1.1.主要文件

a.config->router.config.js:菜单配置

path:浏览器访问路径
name:菜单中文名称
icon:菜单图标

在官网如下:


routes:子菜单
component:页面对应的js文件,以src/pages/为基准,作为相对路径的起点目录

hideInMenu: true,  不显示改菜单
hideChildrenInMenu: true,  子菜单不显示

首页,一般要写成./System/index.js, 可以简写:./System/index,也可以再简写:./System 

b.src->pages->System->index.js:首页

Card是官方库的内容,可以在官网查找说明如下:

访问地址 : https://3x.ant.design/docs/react/introduce-cn

c.dist   打包后的文件 

输入命令后打包才生成dist目录

d.public   静态资源

 e.src->defaultSettings.js   

项目设置*

f.src->domain.js

请求域名*

g.src->pages

pages               业务组件*

 h.src->pages->System

System            系统管理

i.src->pages->System->Account

个人设置

 j.src->pages->System->Const

常量数据

k.src->pages->System->Role

角色管理

l.src->pages->System->User

用户管理

2.1.2.常用语法

import

根据代码所需导入库、组件、函数等

config/router.config.js:

import {Button} from 'antdlib';

类似于java:

import java.util.List;

 

创建组件class

固定写法

export default class Example extends React.PureComponent {}

类似于java:

public class Controller{}

render

class中需要定义render方法,通过返回一个根节点,用来渲染html中的一块区域

render(){
  return <div />
}

 return后面必须返回一个根节点

componentDidMount

页面载入时触发componentDidMount一次

componentDidMount() {
}

类似于html body onload

<html>
<body onload="">
</body>
</html>

 

数组、对象的解析

从数组、对象中取值

const [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

const params = { a: 'aaa', b: 'bbb' };
const { a, b } = params;
a // "aaa"
b // "bbb"

...params // a: 'aaa', b: 'bbb'

参数默认值

如果没有传参数,可以设置一个默认值

handleSearch = ( params={} )=> {
  ajax({
    ...params
  })
}

无参和有参函数都能调用上面这个函数定义:

  • handleSearch()
  • handleSearch({a:'aaa',b:'bbb'})

箭头函数

省略了 function 和 return 关键字:

const f = v => v;

// 等同于
const f = function (v) {
  return v;
};

 如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分:

const f = () => 5;
// 等同于
const f = function () { return 5 };

const sum = (num1, num2) => num1 + num2;
// 等同于
const sum = function(num1, num2) {
  return num1 + num2;
};

局部变量

设置值

this.setState({
  key:value
})

取值:

const { key } = this.state;
或
this.state.key

2.1.3.布局

a.栅格布局

b.区块间隔

 c.左右偏移

2.2.前端学习-组件

2.2.1.基础组件

a.单选框

  • - 用于在多个备选项中选中单个状态。
  • - 和 Select 的区别是,Radio 所有选项默认可见,方便用户在比较中选择,因此选项不宜过多。


import React from 'react';
import {SmartRadio} from 'antdlib';

export default class Example extends React.PureComponent {

  constructor(props){
    super(props);
    this.state = {
      options: [{
        text: 'A',
        value: 'A',
      },{
        text: 'B',
        value: 'B',
      }],
      value: 'A',
    }
  }

  handleRadio=(value) => {
    console.log(value);
  }

  render() {

    const { options,value } = this.state;

    return (

      <div>
        <SmartRadio options={options} value={value} onChange={this.handleRadio} />
      </div>
    );
  }
}

 b.多选框

  • - 在一组可选项中进行多项选择时;
  • - checkbox 一般用于状态标记


import React from 'react';
import { SmartCheckbox }  from 'antdlib';

export default class Example extends React.Component {

  state = {
    options: [
      { label: 'Apple', value: 'Apple' },
      { label: 'Pear', value: 'Pear' },
      { label: 'Orange', value: 'Orange' },
    ],
    value: ['Apple','Pear'],
  }

  handleCheckbox=(checkedList) => {
    this.setState({
      checkedList
    });
  }

  render () {

    const { options,value } = this.state;

    return (
      <SmartCheckbox options={options} checkedList={value} onChange={this.handleCheckbox} />
    );
  }
}

 

 c.下拉框


import React from 'react';
import {SmartSelect}  from 'antdlib';


export default class Example extends React.Component {

  state = {
    options: [{value:'A',text:'A'},{value:'B',text:'B'},{value:'C',text:'C'}],
    value: 'A,B',
  }

  handleSelect = (value) => {
    console.log('select:',value);
  }

  render () {

    const { options,value } = this.state;

    return (
      <SmartSelect options={options} value={value} onChange={this.handleSelect} />
    );
  }
}

 d.时间段选择


import { message, SmartDatepicker , getTimeDistance } from 'antdlib';
import moment from 'moment';
import React from 'react';

import dateStyle from '@/pages/Style/SmartDatepicker/index.less';


export default class Example extends React.PureComponent {

  state = {
    rangePickerValue: getTimeDistance('today'),
  }

  handleRangePickerChange = rangePickerValue => {
    this.setState({
      rangePickerValue,
    });
    message.success(moment(rangePickerValue[0]).format('YYYY-MM-DD')}+'~'+moment(rangePickerValue[1]).format('YYYY-MM-DD')});
  };

  render () {

    const { rangePickerValue } = this.state;

    return (
      <SmartDatepicker value={rangePickerValue} onChange={this.handleRangePickerChange} className={dateStyle} />
    );
  }
}


e.开关

 


import { message, SmartSwitch } from 'antdlib';
import React from 'react';

export default class Example extends React.PureComponent {

  state = {
    checkedChildren : '开',
    unCheckedChildren: '关',
    switch: undefined,
  }

  handleSwitch = (value) => {
    this.setState({
      switch: value
    }); 
  }

  render () {

    const { checkedChildren,unCheckedChildren } = this.state;

    return (
      <SmartSwitch checkedChildren={checkedChildren} unCheckedChildren={unCheckedChildren} onChange={this.handleSwitch} />
    );
  }
}

 f.级联选择


import { message, SmartCascader } from 'antdlib';
import React from 'react';

export default class Example extends React.PureComponent {

  state = {
    cascaderOptions : [
      {
        value: 'zhejiang',
        label: '浙江',
        children: [
          {
            value: 'hangzhou',
            label: '杭州',
            children: [
              {
                value: 'xihu',
                label: '西湖',
              },
            ],
          },
        ],
      },
      {
        value: 'jiangsu',
        label: '江苏',
        children: [
          {
            value: 'nanjing',
            label: '南京',
            children: [
              {
                value: 'zhonghuamen',
                label: '中华门',
              },
            ],
          },
        ],
      },
    ],
    value: ['jiangsu','nanjing','zhonghuamen']
  }

  handleCascader = (value) => {
    this.setState({
      cascaderOption: value
    },()=>{
      message.success(JSON.stringify(value));
    }); 
  }

  render () {

    const { cascaderOptions,value } = this.state;

    return (
      <SmartCascader options={cascaderOptions} value={value} onChange={this.handleCascader} />
    );
  }
}

 g.分页卡片


import { Avatar, Card, Col, Icon, Row, SmartSection } from 'antdlib';
import React from 'react';

const { Meta } = Card;

export default class Example extends React.PureComponent {

  render () {

    return (
      <div>
        <Row gutter={16}>
          <Col span={12}>
            <SmartSection title="典型卡片">
              <Card title="Default size card" extra={<a href="#">More</a>} style={{ width: 300 }}>
                <p>Card content</p>
                <p>Card content</p>
                <p>Card content</p>
              </Card>
              <br />
              <Card size="small" title="Small size card" extra={<a href="#">More</a>} style={{ width: 300 }}>
                <p>Card content</p>
                <p>Card content</p>
                <p>Card content</p>
              </Card>
              <br />
              <Card style={{ width: 300 }}>
                <p>Card content</p>
                <p>Card content</p>
                <p>Card content</p>
              </Card>
            </SmartSection>
          </Col>
          <Col span={12}>
            <SmartSection title="无边框">
              <div style={{ background: '#ECECEC', padding: '30px' }}>
                <Card title="Card title" bordered={false} style={{ width: 300 }}>
                  <p>Card content</p>
                  <p>Card content</p>
                  <p>Card content</p>
                </Card>
              </div>
            </SmartSection>
            <br />
            <SmartSection title="丰富信息">
              <Card
                style={{ width: 300 }}
                cover={
                  <img
                    alt="example"
                    src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
                  />
              }
                actions={[
                  <Icon type="setting" key="setting" />,
                  <Icon type="edit" key="edit" />,
                  <Icon type="ellipsis" key="ellipsis" />,
              ]}
              >
                <Meta
                  avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
                  title="Card title"
                  description="This is the description"
                />
              </Card>
            </SmartSection>
          </Col>
        </Row>
        <br />
        <Row>
          <SmartSection title="栅格">
            <div style={{ background: '#ECECEC', padding: '30px' }}>
              <Row gutter={16}>
                <Col span={8}>
                  <Card title="Card title" bordered={false}>
                  Card content
                  </Card>
                </Col>
                <Col span={8}>
                  <Card title="Card title" bordered={false}>
                  Card content
                  </Card>
                </Col>
                <Col span={8}>
                  <Card title="Card title" bordered={false}>
                  Card content
                  </Card>
                </Col>
              </Row>
            </div>
          </SmartSection>
        </Row>
      </div>
    );
  }
}

 

h.可编辑表格

 



import { Button, Card, Form, Tabs,SmartEditableTable,ajax } from 'antdlib';
import { connect } from 'dva';
import React from 'react';

@connect(({content, loading}) => ({
  content,
  loading: loading.models.content,
}))
export default class Example extends React.Component {

  componentDidMount(){
    this.searchRoleKV();
    this.handleSearch();
  }

  handleSearch = (params={})=> {
    ajax({
        url:'user.selectByPrimaryKey',
        listKey:'user',
        showAll:true,
        ...params
    });

  }

  searchRoleKV = ()=> {
    ajax({
        url: 'kv/role.selectByPrimaryKey',
        key: 'id',       // key名称 
        value: 'name',   // value名称
        retKey: 'roleKV', // 表名称
    });
  }

  getColumns = () => {
    const { roleKV } = this.props.content;

    return [
      {
        title: '账户',
        dataIndex: 'account',
        editable: true,
        inputType: 'text',
        width: 100,
        required: true,
      },
      {
        title: '名称',
        dataIndex: 'name',
        editable: true,
        inputType: 'text',
        width: 200,
        required: true,
      },
      {
        title: '角色',
        dataIndex: 'roleid',
        editable: true,
        inputType: 'select',
        options: roleKV && roleKV.tv,
        render: (val)=> val && roleKV && roleKV.kv[val],
        width: 300,
        required: true,
      },
    ]
  }

  save = (record, addOrUpdate) => {

    if(addOrUpdate === 'add'){
      ajax({
          url: 'user.insertSelective',
          acountRef:record.account,
          ...record
        },
        () => {
          this.handleSearch();
      });
    }else{
      ajax({
          url: 'user.updateByPrimaryKeySelective',
          acountRef:record.account,
          ...record
        },
        () => {
          this.handleSearch();
      });
    }
  }

  onRef=(ref)=>{
    this.ref= ref;
  }

  add = (e) => {
    this.ref.handleAdd({});
  }

  render () {

    const {
      content: {user={}},
      loading,
    } = this.props;

    const EditableFormTable = Form.create()(SmartEditableTable);
                
    return (
        <Card bordered={false}>
          <Button type="primary" style={{marginBottom:'12px'}} onClick={this.add}>新增</Button>
          <EditableFormTable 
            loading={loading} 
            onRef={this.onRef} 
            outcolumns={this.getColumns()} 
            data={user||{}} 
            save={this.save} 
            handleChange={this.handleSearch}/>
        </Card>
    );
  }
}

i.树结构

 


import React from 'react';
import {Tree,message}  from 'antdlib';

export default class Example extends React.Component {

  onSelect = (value) => {
    message.success(value);
  }

  render () {

    const treeData = [
      {
        title: '江苏',
        key: '320000',
        children: [
          {
            title: '常州',
            key: '320400',
            children: [
              { title: '钟楼', key: '320404' },
              { title: '天宁', key: '320401' },
            ],
          },
          {
            title: '南京',
            key: '320100',
            children: [
              { title: '鼓楼', key: '320101' },
              { title: '建邺', key: '320102' },
            ],
          },
        ],
      },
      {
        title: '上海',
        key: '310000',
        children: [
          { title: '黄埔', key: '310101' },
          { title: '长宁', key: '310104' },
        ],
      },
    ];

    return (
      <div>
        <Tree
          defaultExpandAll
          onSelect={this.onSelect}
          treeData={treeData}
        />
      </div>
    );
  }
}

 

2.2.2.业务组件

a.表单

 


import { Col, Row, SmartForm,Button,ajax,Card } from 'antdlib';
import React from 'react';
import { domain } from '@/domain';
import moment from 'moment';
import { connect } from 'dva';
  
@connect(({ content, loading }) => ({
  content,
  loading: loading.models.content,
}))
  
export default class Example extends React.Component {
  
  state = {
    confirmDirty: false,
    formLayout: 'horizontal', // vertical, horizontal, inline
    cols: 2,
    submitName: '查询',
  }
  
  componentDidMount() {
    this.searchRole();
    this.handleSearch();
  }
  
  getFields = () => {
    
    return  [
      {
        type: 'input',
        label: '输入项',
        field: 'input',
        required: true,
        message: '请输入',
        placeholder: '输入项',
        // initialValue: 1,
      },
    ];
  };
  
  handleSubmit = e => {
    e.preventDefault();
    this.formComp.validateFieldsAndScroll((err, values) => {
      if (!err) {
        console.log('Received values of form: ', values);
      }
    });
  };

  refForm = ref => {
    this.formComp = ref.getForm();
  };

  // 查询表单数据
  handleSearch = (params={})=> {
    // ajax
    ajax({
      url:'user.selectByPrimaryKey',
      listKey:'user',
      showAll:true,
      ...params
    });
  };

  // 查询基础数据 ,固定写法 url: kv/namespace.sqlid
  // key 表示数据库id字段
  // value 表示数据库值字段
  // retKey 要给返回的内容起个名字,取值的时候用这个作变量名
  //        返回的内容为{ tv: [{text:'text',value:'value'}], kv: {id:'name'}}
  searchRole = ()=> {
    // ajax 
    ajax({
      url: 'kv/role.selectByPrimaryKey', 
      key: 'id',       
      value: 'name',   
      retKey: 'roleKV', 
    });
  };
  
  
  render() {
    const {formLayout,cols,submitName} = this.state;
    return (
      <Card>
        <Row>
          <Col>
            <SmartForm 
              onRef={this.refForm}
              onSubmit={this.handleSubmit}
              cols={cols}
              formLayout={formLayout}
              fields={this.getFields()}
              submitName={submitName}
            >
              <Row span={24} gutter={16}>
                <Col span={2} offset={16}>
                  <Button type="primary" htmlType="submit">提交</Button>
                </Col>
                <Col span={2}>
                  <Button onClick={()=>{this.formComp.getForm().resetFields();}}>重置</Button>
                </Col>
              </Row>
            </SmartForm>
          </Col>
        </Row>
      </Card>
    );
  }
}
  

b.表格

 


import { Row, Button, Card, Dropdown, Icon, Menu, Popconfirm, SmartTable,SmartCheckbox,ajax } from 'antdlib';
import { connect } from 'dva';
import React, { Fragment, PureComponent } from 'react';
  
@connect(({ content, loading }) => ({
  content,
  loading: loading.models.content,
}))
  
export default class Example extends PureComponent {
  
  state = {
    selectedRowKeys: [],
    selectedRows: [],
    record: null,
  }
  
  componentDidMount() {
    this.searchRole();
    this.handleSearch();
  }
  
  getColumns = () => {

    // 在此获取key value配置进行翻译
    const { roleKV } = this.props.content;
    return [
      {
        title: '数值',
        dataIndex: 'id',
        needTotal:true,
        sorter:true,
        render: (val)=> val+'元',
      },
      {
        title: '普通值',
        dataIndex: 'account',
      },

      {
        title: '数据格式化',
        dataIndex: 'name',
        align: 'right',
        render: val => <span style={{fontWeight:'900'}}>{val + ' 先生'}</span>,
      },

      {
        title: '状态',
        dataIndex: 'state',
        
        render: (val,record) => {
          return val === 1 ? '正常': '停用';
        }
      },
      {
        title: 'id字段显示为名称',
        dataIndex: 'roleid',
        filters: roleKV && roleKV.tv,
        render: (val,record) => val && roleKV && roleKV.kv[val]
      },
      {title:'操作',align:'center',dataIndex:'',
        render: (text, record, index) => (
          <Fragment>
            <a style={{marginRight:'8px'}} onClick={() => this.setState({visible:true,record})}>修改</a>
            <Popconfirm title="确认删除吗?" onConfirm={()=>this.handleDelete(record)}>
              {index > 0 && <a style={{marginRight:'8px'}} href="">删除</a>}
            </Popconfirm>
          </Fragment>
        ),
      },
    ];
  };
  
  // 查询表格数据
  handleSearch = (params={})=> {
    ajax({
      url:'user.selectByPrimaryKey',
      listKey:'user',
      showAll:true,
      ...params
    });

  }

  // 查询基础数据
  searchRole = ()=> {
    ajax({
      url: 'kv/role.selectByPrimaryKey',
      key: 'id',       // key名称 
      value: 'name',   // value名称
      retKey: 'roleKV', // 表名称
    });
  }
  
  handleDelete = record => {
    if (!record) return;
    // ajax
  };
  
  handleUpdate = record => {
    if (!record) return;
    // ajax
  };
  // 下拉菜单按钮操作处理
  handleMenuClick = e => {
    if (!selectedRows) return;

    const { selectedRows } = this.state;
    
    switch (e.key) {
      case 'remove':
        break;
      default:
        break;
    }
  };

  // 批量操作
  handleDeleteBatch = () => {
    if (!selectedRows) return;

    const { selectedRows } = this.state;
    // ajax

  };

  // 勾选行时触发
  onSelectChange = (selectedRowKeys, selectedRows) => {
    console.log('selectedRowKeys changed: ', selectedRowKeys);
    console.log('selectedRows changed: ', selectedRows);

    this.setState({ selectedRowKeys, selectedRows });
  };
  
  render() {
    const {
      content: { user },
      content,
      loading,
    } = this.props;
    
    const { selectedRows, selectedRowKeys } = this.state;

    // 设置选中行选项
    const rowSelection = {
        selectedRowKeys, // 选中行的key字段
        selectedRows,   // 选中的行记录
        onChange: this.onSelectChange, //选中时触发
        getCheckboxProps: record => ({
          name: record.account,  // 根据哪个字段来判断是否能被选中
          disabled: record.account === 'admin',  // 当条件为true时,记录无法被选中 
        }),
      } || {} ;

    // 下拉菜单按钮
    const menu = (
      <Menu onClick={this.handleMenuClick} selectedKeys={[]}>
        <Menu.Item key="remove">删除</Menu.Item>
        <Menu.Item key="approval">批量审批</Menu.Item>
      </Menu>
    );

    // 行展开内容渲染
    const renderExpand = record => {
      return (
        <p>
          渲染详情:可自由组织数据 {JSON.stringify(record)}
        </p>
      );
    };
    return (
      <Card bordered={false} >

        <div style={{marginBottom: '16px'}}>
          <Button style={{marginRight:'8px'}} icon="plus" type="primary" onClick={() => {}}>
            新建
          </Button>
          
          {selectedRows.length > 0 && (
            <span>
              <Button style={{marginRight:'8px'}}>批量操作</Button>
              <Dropdown overlay={menu}>
                <Button style={{marginRight:'8px'}}>
                  更多操作 <Icon type="down" />
                </Button>
              </Dropdown>
            </span>
          )}
            
        </div>
        <SmartTable
          bordered
          
          rowSelection={rowSelection}
          
          expandedRowRender={renderExpand}
          loading={loading}
          data={user||[]}
          columns={this.getColumns()}
          // scroll={{ x: 800 }}  x表示水平方向的宽度
  
          handleChange={(params)=>this.handleSearch(params)}
        />
        
      </Card>
    );
  }
}
  

2.3.前端学习-交互

2.3.1.数据绑定

 


import { connect } from 'dva';
import React from 'react';

@connect(({content, loading}) => ({
  content,
  loading: loading.models.content,
}))
export default class Example extends React.PureComponent {
  render() {

    const { content:{result} } = this.props;

    return (

      <div>
        {result}
      </div>
    );
  }
}

2.3.2.请求响应


import { message, SmartForm,ajax } from 'antdlib';
import { connect } from 'dva';
import React from 'react';


@connect(({content, loading}) => ({
  content,
  loading: loading.models.content,
}))
export default class Example extends React.PureComponent {

  constructor(props){
    super(props);
    this.state = {
      confirmDirty: false,
  
      formLayout: 'horizontal', // horizontal, inline
      cols: 3,
      
      submitName: '提交',
  
      fields : [
        {
          type: 'input',
          label: '输入项',
          field: 'input',
          required: true,
          message: '请输入',
          placeholder: '输入项',
        },
      ]
    }
  }

  handleSubmit = e => {
    e.preventDefault();
    this.formComp.getForm().validateFieldsAndScroll((err, values) => {
      if (!err) {
        console.log('Received values of form: ', values);

        ajax(
          {
            url:'level.selectByPrimaryKey'
          },
          ()=>{
            message.success('提交form表单数据:'+JSON.stringify(values));
          }
        );
        
      }
    });
  };

  refForm = ref => {
    this.formComp = ref;
  }

  render() {

    const {loading} = this.props;
    const {formLayout,cols,submitName,fields} = this.state;

    return (

      <div>
        <SmartForm 
            loading={loading}
            onRef={this.refForm}
            onSubmit={this.handleSubmit}
            cols={cols}
            formLayout={formLayout}
            fields={fields}
            submitName={submitName && submitName}
          >
        </SmartForm>
      </div>
    );
  }
}

 

 

 

 

 

 

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值