UmiJs uses the React framework, which is more advanced and convenient than Creat-React. Antd and global less; And multilingualism; Basic layout;
prepare
Initialize the project
yarn create @umijs/umi-app
Copy the code
After installing dependencies, run start to start the project. For example, yarn start, the following directory structure is obtained
Tree. / SRC ├ ─. Umi │ ├ ─. Cache │ │ └ ─ Babel - loader │ ├ ─ core │ ├ ─ the plugin - helmet │ ├ ─ plugin - initial state │ │ └ ─ models │ ├ ─ the plugin - model │ └ ─ the plugin - request └ ─ pagesCopy the code
.UMI can be ignored temporarily (without affecting programming)Copy the code
Now it’s up and running, just two lines of command to start a project. At this point, there is only index. TSX under Pages, so let’s add a landing page
Can refer to project actual combat
Reductive route
Routing, we use contracted routing, which is automatically generated from the files under Pages, without manual management.
Route configuration, remove manual route, use reductive route, find in the root directory. Umirc.ts delete the following code
- layout: {},
Copy the code
Let’s add a login. TSX, assuming the page number is written and we need to make a request, let’s configure the request.
To do that, create a new layout /index.tsx under SRC. See below
import { IRouteComponentProps } from 'umi'
import request from 'umi-request'
export default function Layout ({ children, location, route, history, match }: IRouteComponentProps) {
request.extendOptions({
prefix: 'https://xxxxx.com'
})
return children
}
Copy the code
The above is the configuration of prefix, but we need to deal with authorization, such as setting token after successful login, such as modifying return value, etc. We can write a middleware, the use code is also very simple, add use, token sample code is as follows
request.use(async(ctx, next) => { ctx.req.options.headers = { ... ctx.req.options.headers,'token': localStorage.token || ' '
}
await next()
})
Copy the code
Umi-request Detailed documents
At this point you can start using the request on the page as follows
import styles from './index.less';
import { history } from 'umi'
import fetch from 'umi-request'
import { useEffect } from 'react';
export default function IndexPage () {
useEffect(() => {
const init = async () => {
const res = await fetch.post('/api/v2/main/auth/xxx', { data: { accountaddress: "xx" } })
console.log(res)
}
init()
}, [])
return (
<div>
<h1 className={styles.title}>Page index</h1>
</div>
);
}
Copy the code
Package compiled
└./dist./dist ├─ index.html ├─ um.css ├─ um.jsCopy the code
start
With a basic environment completed above, it’s time to start the theme. Let’s open up our fast-building landing page and menu bar and list.
plugin-locale
Rely on @ ant – design/pro – layout
Open the configuration
locale: {
// default lang
default: 'en-US'.antd: true.// default true, when it is true, will use `navigator.language` overwrite default
baseNavigator: true,},Copy the code
global
import { useIntl } from 'umi'
const intl = useIntl();
window.intl = intl
Copy the code
FormattedMessage or intl.formatMessage({id: ‘pages.login.successfully’})
type
type intl = {
formatMessage (option: { id: string; defaultMessage? :string}) :string;
}
Copy the code
Global less
SRC /global.less will do, but note that you need to restart the project
On the left side of the bar
Layout /index.tsx, custom left and right columns,
({ children, location, route, history, match }) => {
const { routes = [] } = route;
const { breadcrumb, menuData } = getMenuData(routes);
// -- Render the left column according to menuData
return location.pathname === '/user/login' ? children : <div className={styles.box}>
<ProLayout
style={{ flexDirection: 'row', height: '100vh'}}title={"' | |intl.formatMessage({ id: 'component.globalHeader.title'})}logo={<Logo width={150}></Logo>}
menuRender={menuRender}
headerRender={headerRender}
>
{children}
</ProLayout>
</div>
}
Copy the code
If you use an indeterminate route, the menu bar is basically unchanged and breadcrumbs are generated automatically, but the indeterminate route needs to be handled manually
Multilanguage switching can be done with the
Implementation of the list page
import styles from './_nftHandle.less'
import { Input, Pagination, Spin } from 'antd'
import { NFTCheckStatus } from './type';
import { useEffect, useState } from 'react';
import request from 'umi-request';
import { ImgFit } from '@/components/ImgFit';
const { Search } = Input
function showTotal (total: number) {
return `Total ${total} items`;
}
interface INFTCheckHandle {
type: NFTCheckStatus
}
export default function NFTCheckHandle ({ type }: INFTCheckHandle) {
const onSearch = (value: string) = > console.log(value)
const list: { src: string; name: string} [] =new Array(20).fill({ src: ' '.name: 'name' })
const [loading, setloading] = useState(true)
useEffect(() = > {
const init = async() = > {// const res = await request.post('/api/v2/main/auth/xxx', { data: { accountaddress: "xx" } })
await new Promise((ok) = > setTimeout(ok, 500))
setloading(false)
}
init()
}, [])
return <div>
<Spin spinning={loading} tip="Loading...">
<div style={{ width: 500}} >
<Search
placeholder={intl.formatMessage({ id: 'component.input.searchPlaceholder'})}allowClear
enterButton={intl.formatMessage({ id: 'component.input.search'})}size="large"
onSearch={onSearch}
/>
</div>
<div className={styles.row}>
{list.map((e, index) => <div key={index} className={[styles.item, 'flex'].join(' ')} >
<div>
<ImgFit src={e.src} width={260} height={262} />
</div>
<p>{type} {e.name}</p>
</div>)}
</div>
</Spin>
<Pagination
size="small"
total={50}
disabled={false}
showTotal={showTotal}
showSizeChanger
showQuickJumper
/>
</div>
}
Copy the code
Using pro table
The update
preview
A link to the
Umi-request Network request path umiJS document umiJS plugin-locale