模板引用
mkdir myapp && cd myapp
npx @umijs/create-umi-app
// yarn create @umijs/umi-app
yarn install
yarn start
// 直接选择脚手架
npm create umi
配置
/* 配置文件: .umirc.ts 或者 config/config.ts, 其中.umirc.ts的优先级更高 */
// 以 @umijs/preset-、@umijs/plugin-、umi-preset- 和 umi-plugin- 开头的依赖会被自动注册为插件或插件集。
// 具体参考: https://umijs.org/zh-CN/config
/* =================== config/config.ts 的配置如下 =========================== */
import { defineConfig } from 'umi';
import defaultSettings from './defaultSettings';
import routes from './routes'
export default defineConfig({
// 配置是否让生成的文件包含 hash 后缀
hash: true,
// 使用antd
antd: {},
// dva的热更新
dva: {
hmr: true,
},
// 哈希路由模式,默认是浏览器模式
history: {
type: 'hash',
// type: 'browser'
},
// 支持按需导入
dynamicImport: {
// 设置懒加载loading组件
loading: '@/components/PageLoading/index',
},
targets: {
ie: 11,
},
routes: routes,
// ant-design 主题色
// https://ant.design/docs/react/customize-theme-cn
theme: {
'primary-color': defaultSettings.primaryColor,
},
// umi build的时候,给所有文件路径加前缀
// publicPath: './',
manifest: {
basePath: '/',
},
// 在开发环境使用esbuild进行打包
esbuild: {},
})
/* 路由 */
// 嵌套路由, exact, component, path, redirect, wrappers
// routes api
import { history, Link } from 'umi'
history.push('/list?a=b')
history.push({
pathname: '/list,
query: {a: 'b'}
})
history.goBack()
export default function(props) {
console.log(props.routes)
return <Link to="/user'>to user</Link>
}
/* 约定式路由: */
// 通过文件的形式生成路由,可以参考:https://umijs.org/zh-CN/docs/convention-routing
/* 多环境配置 */
// touch .umirc.js, .umirc.cloud.js, .umirc.local.js
// 通过制定 UMI_ENV=cloud 或者 UMI_ENV=local 或者 不配置UMI_ENV 来指定不同环境
// 参考: https://umijs.org/zh-CN/docs/config
dva
const apiRequest = new Promise(resolve => {
setTimeout(() => resolve({ name: 'tomas'}), 100)
})
// 定义模型
const PersonModel = {
// 必填, 一个标记索引
namespace: 'person',
// 必填, 这是初始化数据
state: {
name: 'woyao',
},
// 异步的action
effects: {
// ({ payload: any, type: string} as action, { call, put, select}):generator
// 第一个参数是一个action: { type: string, payload: any }
// 第二个参数中:
// put的作用是发出一个action, call是执行异步函数, select可以拿到所有模型下的state
*getUserName({ payload }, { call, put, select }) {
// call 执行异步函数
const data = yield call(apiRequest)
// 发出一个 Action,类似于 dispatch
yield put({
type: 'updateUserName',
payload: data,
})
// select 可以拿到所有的模型的state
const currentUserName = yield select(state => state.person.name)
}
},
// reducer
reducers: {
updateUserName(initState, action) {
return {
...initState,
name: action.payload?.name || '',
}
}
}
}
// 定义组件
const Person = (props) => {
const { person, loading } = props;
return (
<div>
{
loading ?
<span>Loading</span>
:
<h5>hello, {person.name}</h5>
}
</div>
)
}
// dva会自带一个loading参数,通过loading.effects参数,来监听一个action的触发
// 这里当getUserName这个effect被执行的时候,loading为true
export default connect(({person, loading}) => ({
user: person,
loading: loading.effects['person/getUserName']
}))(Person)