|  
 
 一、项目初始化 
 创建并进入目录mkdir umijs
 cd umujs
创建umi项目yarn create @umijs/umi-app
 npx @umijs/create-umi-app
安装依赖yarn
启动项目yarn start
打包,部署发布yarn build (构建后项目中会多一个dist项目)
本地验证yarn global add serve - - 或 - - npm install http-server -g
 serve ./dist - - 或 - - http-server ./dist
获取镜像源yarn config get registry
 
 二、基本了解2.1.路由配置 
 .umirc.ts 
import { defineConfig } from 'umi';
export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  hash:true,  
  
  
                   
                   
  
  title:'UmiJS标题',   
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  routes: [   
    { path: '/', component: '@/pages/index',title:'首页' },
    { path: '/list', redirect:'/user/one' },   
    
    { 
      path:'/user',
      component:'@/layouts/index',
      
      
      wrappers:[   
        '@/wrappers/auth',
      ],
      routes:[    
        
        
        
        { path: '/user/one', component: '@/pages/user2',title:'用户页面2'},  
        { path: '/user/two', component: '@/pages/user',title:'用户页面'},
        { component:'@/pages/404'}  
      ]
    },
    { component:'@/pages/404'}  
  ],
  fastRefresh: {},
});
  
 layouts.index.tsx import React from 'react';
import { Link, NavLink } from 'umi';
import './index.less';
const Index = (props: any) => {
  return (
    <div>
      <h2>Header</h2>
      {}
      {}
      <NavLink to={'/user/one'}>用户1</NavLink>
      <NavLink to={'/user/two'}>用户2</NavLink>
      {}
      {props.children}
      <h2>Footer</h2>
    </div>
  );
};
export default Index;
  
 pages/index.less .active {
  color: red;
  font-size: 33px;
}
  
 pages/index.tsx import styles from './index.less';
import { DatePicker } from 'antd';
export default function IndexPage(props: any) {
  
  console.log('dnlsbd', props.match.params);
  console.log('dnlsbd', props.match.params.id);
  return (
    <div>
      <h1 className={styles.title}>Page index</h1>
      <DatePicker />
    </div>
  );
}
  
 pages/user2.tsx 
import React from 'react';
const User = () => {
  return <div>User Page2</div>;
};
export default User;
  
 pages/user1.tsx 
import React from 'react';
import { Button } from 'antd';
const User = (props: any) => {
  return (
    <div>
      <span>User Page1</span>
      <Button
        onClick={() => {
          props.history.push('/');
        }}
      >
        点我回首页
      </Button>
    </div>
  );
};
export default User;
  
 pages/404.tsx import React from 'react';
const NotFound = () => {
  return (
    <div>
      <h1>404</h1>
    </div>
  );
};
export default NotFound;
  
 wrappers/auth.tsx 
import { Redirect } from 'umi';
export default (props: any) => {
  const isLogin = true;
  if (isLogin) {
    
    return <div>{props.children}</div>;
  } else {
    
    return <Redirect to="/login" />;
  }
};
 2.2.Html模板 
 在node_modules/@umijs/core/lib/Html/document.ejs中,里面是将组件挂载到页面上由于模板代码在node_modules中,一般提交版本代码时是不会提交node_modules的,所以不要在模板上进行修改
 <!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
</head>
<body>
<div id="<%= context.config.mountElementId || 'root' %>"></div>
</body>
</html>
  
 新建 src/pages/document.ejs,umi 约定如果这个文件存在,会作为默认模板 <!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <title>自定义模板</title>
  
  <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.6.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <h3>自定义模板</h3>
  <button class="btn btn-success">bootstrap</button>
  <div id="root"></div>
</body>
</html>
 2.3.Mock数据 
 Mock数据是前后端分离开发的关键步骤,通过跟服务器预先约定好的接口,模拟请求数据和逻辑在mock文件夹下写的js或ts文件都会被认为是mock文件可以引入Mock.js第三方库提升Mock数据能力
 mock:false   
"start:nomock": "MOCK=none umi dev" 
  
 mock/index.ts 
import mockjs from 'mockjs'
export default {
  
  
  'GET /api/index' : {
    id: 1,
    name: 'Tom',
    age: 12
  },
  'GET /api/person' : {
    id: 2,
    name: 'LiLi',
    age: 21
  },
  'GET /api/tags' : mockjs.mock({
    
    'list|100':[{name:'@city','value|1-100':50,'type|0-2':1}]
  }) 
}
  
 pages/index.tsx import styles from './index.less';
import { DatePicker, Button } from 'antd';
import { useEffect } from 'react';
import { history, request } from 'umi';
export default function IndexPage(props: any) {
  
  
  
  useEffect(() => {
    setTimeout(() => {
      
      
      history.push('/user/one');
    }, 2000);
  });
  
  const getData = () => {
    request('/api/index').then((res) => {
      console.log(res);
    });
  };
  
  const getData2 = async () => {
    const data = await request('/api/person');
    console.log(data);
  };
  
  const getData3 = async () => {
    const data = await request('/api/tags');
    console.log(data);
  };
  return (
    <div>
      <h1 className={styles.title}>Page index</h1>
      <Button onClick={getData3}>点击获取数据</Button>
      <DatePicker />
    </div>
  );
}
 2.4.DvaJS 
 umi已经给我们提供plugin-dva插件了dva的作用就是让我们更方便的使用redux约定式的model文件src/models下的文件(推荐使用),src/pages/models目录下的文件,src/pages/model.ts文件
 会有校验内容是否是有效的dva model
  
 1.创建ui组件 src/pages/tags.tsx(记得配置路由)2.创建model src/models/tags.ts3.使用connect将ui组件和model进行连接
  
 .umirc.ts {path:'/tags',component:'@/pages/tags'},
  
 pages/tags.tsx import React from 'react';
import { connect } from 'umi';
import { Button } from 'antd';
const Tags = (props) => {
  const { dispatch } = props;
  const tagslist = props.tags.tagsList.list || [];
  const getTagsList = () => {
    
    dispatch({
      type: 'tags/fetchTagsList', 
      payload: null, 
    });
  };
  return (
    <div>
      <h3>Dva的使用</h3>
      <Button onClick={getTagsList}>点击获取TagsList</Button>
      {tagslist.map((item, index) => {
        return <p key={index + item}>{item.name}</p>;
      })}
    </div>
  );
};
export default connect(({ tags }) => ({ tags }))(Tags);
  
 src/models/tags.ts import {request} from 'umi'
const getTags = () => {
  return request('/api/tags')
}
export default{
  
  namespace:'tags', 
  
  state:{
    tagsList:[]
  },     
  
  effects:{
    
    
    
    
    
    *fetchTagsList({payload,callback},{put,call}){
      
      const tagsList = yield call(getTags)
      
      yield put({
        type: 'setTagsList',    
        payload: tagsList    
      })
    }
  },   
  
  reducers:{
    
    
    setTagsList(state,action){
      console.log("skanbdjad",state)
      console.log("skanbdjad",action)
      return {...state,tagsList:action.payload}
    }
  }  
}
 2.5.运行时配置 
 运行时配置:约定写在src/app.tsx中 import { history } from 'umi';
let extraRoutes;
export function patchRoutes({ routes }) {
  
  routes.unshift({
    path: '/foo',
    title: 'foo',
    
    component: require('@/pages/user1').default, 
  });
  
  
  extraRoutes.map((item) => {
    
    routes.unshift({
      path: item.path,
      component: require(`@/pages${item.component}`).default,
    });
  });
}
export function render(oldRender) {
  
  
  
  
  
  extraRoutes = [{ path: '/server', component: '/user2' }];
  
  
  
  const isLogin = true;
  if (!isLogin) {
    history.push('/login');
  }
  
  oldRender();
}
export function onRouteChange({ location, routes, action, matchedRoutes }) {
  console.log(location); 
  
  console.log(location.pathname);
  
  console.log('jhbad vsd', matchedRoutes);
  console.log('jhbad vsd', matchedRoutes.length);
  
  if (matchedRoutes.length) {
    
    document.title =
      '郑州师范 ' + (matchedRoutes[matchedRoutes.length - 1].route.title || '');
  }
  console.log(routes); 
  console.log(action); 
}
 2.6.Umi-UI 
 安装umi-ui的依赖yarn add @umijs/preset-ui -D
在项目package.json中配置linux:“start:umi-ui”: “UMI_UI=1 umi dev”
 windows:“start:umi-ui”: “set UMI_UI=1 && umi dev”
运行:yarn start:umi-ui
  
 打开项目后,点击右下角Umi UI的可视化编程根据,解决以下问题在项目根目录下创建一个.env文件,里面进行以下配置:HOST=0.0.0.0
 
   
 通过点击引入相关的Umi-Ui的模板或区块,引入区块中的布局,点击添加到项目中,项目中pages下会出现一个LayoutSide组件需要进行调整,在src下创建一个layouts文件夹,将LayoutSide组件放到layouts下面,并修改.umirc.ts下的路由配置
 import { defineConfig } from 'umi';
export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  routes: [
    {
      name: '注册页',
      path: '/userregister',
      component: './UserRegister',
    },
    {
      name: '模板组件',
      title: '数字郑州',
      path: '/',
      component: '@/layouts/LayoutSide/index',
      routes: [
        {
          name: '空白页面',
          path: '/user',
          component: '@/pages/User/index',
        },
        {
          name: '首页',
          path: '/index',
          component: '@/pages/index',
        },
      ],
    },
  ],
  fastRefresh: {},
  dva: {  
    immer: true,
    hmr: false,
  },
  locale: {   
    default: 'zh-CN',
    antd: false,
    title: false,
    baseNavigator: true,
    baseSeparator: '-',
  }
});
 三、项目优化3.1.配置项 
 将原来的.umirc.ts文件的内容拆分为以下几个文件,在项目根目录先新建一个config文件夹,下面放四个文件 3.1.1.config.ts 
 相当于.umirc.ts下的配置 
import { defineConfig } from 'umi';
import routes from './routes'
import defaultSetting from './defaultSetting';
import proxy from './proxy'
export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  hash:true,  
  
  routes,
  title:defaultSetting.title, 
  theme: {   
    '@primary-color': defaultSetting.PrimaryColor,    
  },
  fastRefresh: {},
  targets:{
    ie:11    
  },
  proxy:proxy['dev'],  
  locale:{   
    default:'zh-CN',
    antd:false,
    title:false,
    baseNavigator:true,
    baseSeparator:'-',
  },
  dva:{   
    immer:true,
    hmr:false,
  }
});
 3.1.2.defaultSetting.ts 
 一些默认配置 export default {
  PrimaryColor: '#1DA57A',
  title:'UmiJS标题',
}
 3.1.3.proxy.ts 
 代理配置 
export default [
  
  dev:{
    '/api': {   
      'target': 'http://jsonplaceholder.typicode.com/',   
      'changeOrigin': true,
      'pathRewrite': { '^/api' : '' },
    },
  },
  
  test:{
    '/api': {   
      'target': 'http://jsonplaceholder.typicode.com/',   
      'changeOrigin': true,
      'pathRewrite': { '^/api' : '' },
    },
  }
]
 3.1.4.routes.ts 
 路由配置 
export default [
  [   
    { 
      path: '/', 
      component: '@/layouts/index',  
      title:'首页',
      routes:[
        {path:'/',component:'@/pages/index'},
        { 
          path:'/user',    
          wrappers:[   
            '@/wrappers/auth',
          ],
          routes:[    
            
            { path: '/user/one', component: '@/pages/user1',title:'用户页面1'},
            { path: '/user/two', component: '@/pages/user2',title:'用户页面2'},
            { component:'@/pages/404'}  
          ]
        },
        {path:'/tags',component:'@/pages/tags'},
        {path:'/login',component:'@/pages/login'},
      ]
    },
    
    { component:'@/pages/404'}  
  ],
]
 3.1.5.utils/request.ts 
 对request进行封装,可以做一些拦截器,方便在services中使用 
import request from 'umi-request'
import {message} from 'antd'
request.interceptors.request.use((url, options) => {
  return {
    url: `${url}`,
    
    options: { ...options, interceptors: true, headers: {Hello: 'hello'} },
  };
});
request.interceptors.response.use(response => {
  
  if(response.status > 400){
    const codeMaps = {
      404:'未找到资源。',
      502: '网关错误。',
      503: '服务不可用,服务器暂时过载或维护。',
      504: '网关超时。',
    };
    message.error(codeMaps[response.status]);
  }
  return response;
});
export default request;
 3.1.6.services/tags.ts 
 在src下创建目录,组件叫什么名字,服务就叫什么名字,将对后端或者models中的请求分离出来 
import request from "../utils/request"
export const getTags = () => {
  return request('/api/tags')
}
 3.2.目录结构 
 public:一些静态资源,打包时原样复制出去src/.umi:缓存,每次运行会重新生成,不会进版本库
 src/assets:本地静态资源
 src/components:公共组件
 src/pages/页面组件/components:页面相关的组件
 src/services:对后端数据的请求
 src/utils:工具类
 四、Antd Pro4.1.创建Antd Pro项目 
 创建Antd Pro项目(基于umi配置的) 查看yarn的目录 查看全局目录 清缓存 创建Antd Pro项目报错 yarn config set global-folder “D:\Develop\yarnConfig\yarn_global”yarn config set cache-folder “D:\Develop\yarnConfig\yarn_cache”
 
 |