umi使用教程

2,126 阅读2分钟

模板引用

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)