chore: app 模式不再使用 react router,方便后续开发调试 (#3244)

* chore: app 模式不再使用 react router,方便后续开发调试

* chore: app 模式不再使用 react router,方便后续开发调试
This commit is contained in:
吴多益 2021-12-22 12:37:45 +08:00 committed by GitHub
parent e1f892de0e
commit 2db00c441c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 254 additions and 48 deletions

View File

@ -12,7 +12,7 @@ order: 99
## 基本用法 ## 基本用法
类型定义为 `app`,通过 pages 定义页面,支持层级,支持内嵌 schema或者 通过 schemaApi 远程拉取页面,完整用法请参考 [amis-admin](https://github.com/aisuda/amis-admin) 项目 类型定义为 `app`,通过 pages 定义页面,支持层级,支持内嵌 schema或者 通过 schemaApi 远程拉取页面,完整用法请参考 [amis-admin](https://github.com/aisuda/amis-admin) 项目里的代码示例,需要修改 `env`
```json ```json
{ {
@ -21,7 +21,6 @@ order: 99
"pages": [ "pages": [
{ {
"label": "分组1", "label": "分组1",
"children": [ "children": [
{ {
"label": "父页面", "label": "父页面",

View File

@ -276,7 +276,7 @@ amis.embed(
默认 JSSDK 不是 hash 路由,如果你想改成 hash 路由模式,请查看此处代码实现。只需要修改 env.isCurrentUrl、env.jumpTo 和 env.updateLocation 这几个方法即可。 默认 JSSDK 不是 hash 路由,如果你想改成 hash 路由模式,请查看此处代码实现。只需要修改 env.isCurrentUrl、env.jumpTo 和 env.updateLocation 这几个方法即可。
参考https://github.com/baidu/amis/blob/master/examples/components/Example.tsx#L551-L575 参考https://github.com/baidu/amis/blob/master/examples/components/Example.jsx#L551-L575
### 销毁 ### 销毁
@ -436,7 +436,7 @@ class MyComponent extends React.Component<any, any> {
render() { render() {
let amisScoped; let amisScoped;
let theme = 'cxd'; let theme = 'cxd';
// 请勿使用 React.StrictMode目前还不支持 // 请勿使用 React.StrictMode目前还不支持
return ( return (
<div> <div>

96
examples/app/index.html Normal file
View File

@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>amis app 模式</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link type="image/x-icon" rel="shortcut icon" href="./static/favicon.png" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1"
/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<link rel="stylesheet" href="../static/iconfont.css" />
<link rel="stylesheet" href="@fortawesome/fontawesome-free/css/all.css" />
<link
rel="stylesheet"
href="@fortawesome/fontawesome-free/css/v4-shims.css"
/>
<!--DEPENDENCIES_INJECT_PLACEHOLDER-->
<!--STYLE_PLACEHOLDER-->
<style>
.app-wrapper,
.schema-wrapper {
position: relative;
width: 100%;
height: 100%;
}
</style>
<script type="text/x-jsx">
let theme = localStorage.getItem('amis-theme') || 'cxd';
if (theme === 'default') {
theme = 'cxd';
}
// 非 IE 模式
if (window.navigator.userAgent.indexOf('Trident') === -1) {
document.write(
`<link rel="stylesheet" title="ang" ${
theme !== 'ang' ? 'disabled' : ''
} href="${__uri('../../scss/themes/ang.scss')}" />`
);
document.write(
`<link rel="stylesheet" title="cxd" ${
theme !== 'cxd' ? 'disabled' : ''
} href="${__uri('../../scss/themes/cxd.scss')}" />`
);
document.write(
`<link rel="stylesheet" title="dark" ${
theme !== 'dark' ? 'disabled' : ''
} href="${__uri('../../scss/themes/dark.scss')}" />`
);
document.write(
`<link rel="stylesheet" title="antd" ${
theme !== 'antd' ? 'disabled' : ''
} href="${__uri('../../scss/themes/antd.scss')}" />`
);
} else {
document.write(
`<link rel="stylesheet" title="ang" ${
theme !== 'ang' ? 'disabled' : ''
} href="${__uri('../../scss/themes/ang-ie11.scss')}" />`
);
document.write(
`<link rel="stylesheet" title="cxd" ${
theme !== 'cxd' ? 'disabled' : ''
} href="${__uri('../../scss/themes/cxd-ie11.scss')}" />`
);
document.write(
`<link rel="stylesheet" title="dark" ${
theme !== 'dark' ? 'disabled' : ''
} href="${__uri('../../scss/themes/dark-ie11.scss')}" />`
);
document.write(
`<link rel="stylesheet" title="antd" ${
theme !== 'antd' ? 'disabled' : ''
} href="${__uri('../../scss/themes/antd-ie11.scss')}" />`
);
}
</script>
<!--ignore-->
<link rel="stylesheet" href="../../scss/helper.scss" />
<!--ignore-->
</head>
<body>
<div id="root" class="app-wrapper"></div>
<script src="../mod.js"></script>
<script type="text/javascript">
/* @require ./index.jsx 标记为同步依赖,提前加载 */
amis.require(['./index.jsx'], function (app) {
var initialState = {};
app.bootstrap(document.getElementById('root'), initialState);
});
</script>
</body>
</html>

140
examples/app/index.jsx Normal file
View File

@ -0,0 +1,140 @@
/**
* @file app 模式示例
*/
import APPSchema from './app';
import {createHashHistory} from 'history';
import {embed} from '../embed';
const history = createHashHistory({});
function normalizeLink(to, location = history.location) {
to = to || '';
if (to && to[0] === '#') {
to = location.pathname + location.search + to;
} else if (to && to[0] === '?') {
to = location.pathname + to;
}
const idx = to.indexOf('?');
const idx2 = to.indexOf('#');
let pathname = ~idx
? to.substring(0, idx)
: ~idx2
? to.substring(0, idx2)
: to;
let search = ~idx ? to.substring(idx, ~idx2 ? idx2 : undefined) : '';
let hash = ~idx2 ? to.substring(idx2) : location.hash;
if (!pathname) {
pathname = location.pathname;
} else if (pathname[0] != '/' && !/^https?\:\/\//.test(pathname)) {
let relativeBase = location.pathname;
const paths = relativeBase.split('/');
paths.pop();
let m;
while ((m = /^\.\.?\//.exec(pathname))) {
if (m[0] === '../') {
paths.pop();
}
pathname = pathname.substring(m[0].length);
}
pathname = paths.concat(pathname).join('/');
}
return pathname + search + hash;
}
function isCurrentUrl(to, ctx) {
if (!to) {
return false;
}
const pathname = history.location.pathname;
const link = normalizeLink(to, {
...location,
pathname,
hash: ''
});
if (!~link.indexOf('http') && ~link.indexOf(':')) {
let strict = ctx && ctx.strict;
return match(link, {
decode: decodeURIComponent,
strict: typeof strict !== 'undefined' ? strict : true
})(pathname);
}
return decodeURI(pathname) === link;
}
const APPENV = {
updateLocation: (location, replace) => {
location = normalizeLink(location);
if (location === 'goBack') {
return history.goBack();
} else if (
(!/^https?\:\/\//.test(location) &&
location === history.location.pathname + history.location.search) ||
location === history.location.href
) {
//
return;
} else if (/^https?\:\/\//.test(location) || !history) {
return (window.location.href = location);
}
history[replace ? 'replace' : 'push'](location);
},
jumpTo: (to, action) => {
if (to === 'goBack') {
return history.goBack();
}
to = normalizeLink(to);
if (isCurrentUrl(to)) {
return;
}
if (action && action.actionType === 'url') {
action.blank === false
? (window.location.href = to)
: window.open(to, '_blank');
return;
} else if (action && action.blank) {
window.open(to, '_blank');
return;
}
if (/^https?:\/\//.test(to)) {
window.location.href = to;
} else if (
(!/^https?\:\/\//.test(to) &&
to === history.pathname + history.location.search) ||
to === history.location.href
) {
// do nothing
} else {
history.push(to);
}
},
isCurrentUrl: isCurrentUrl
};
export function bootstrap(mountTo) {
const amisInstance = embed(
mountTo,
APPSchema,
{
location: history.location
},
APPENV
);
history.listen(state => {
amisInstance.updateProps({
location: state.location || state
});
});
}

View File

@ -84,7 +84,7 @@ import Tab1Schema from './Tabs/Tab1';
import Tab2Schema from './Tabs/Tab2'; import Tab2Schema from './Tabs/Tab2';
import Tab3Schema from './Tabs/Tab3'; import Tab3Schema from './Tabs/Tab3';
import TestComponent from './Test'; import TestComponent from './Test';
import APP from './APP/index';
import {normalizeLink} from '../../src/utils/normalizeLink'; import {normalizeLink} from '../../src/utils/normalizeLink';
export const examples = [ export const examples = [
@ -577,49 +577,17 @@ export const examples = [
{ {
label: 'APP 多页应用', label: 'APP 多页应用',
icon: 'fa fa-cubes', icon: 'fa fa-cubes',
path: '/examples/app', path: '/app/',
component: makeSchemaRenderer(APP, false, { component: () => {
session: 'app', // gh-pages
jumpTo: (to: string) => { if (/^\/amis/.test(window.location.pathname)) {
location.hash = to; window.open(`/amis/app/`, '_blank');
}, } else {
updateLocation: (to, replace) => { window.open(`/examples/app/`, '_blank');
if (to === 'goBack') {
return window.history.back();
}
if (replace && window.history.replaceState) {
window.history.replaceState(
'',
document.title,
normalizeLink(to)
);
return;
}
window.history.pushState('', document.title, normalizeLink(to));
},
isCurrentUrl: (to: string, ctx: any) => {
if (!to) {
return false;
}
const pathname = location.hash ? location.hash.substring(1) : '/';
const link = normalizeLink(to, {
...location,
pathname,
hash: ''
});
if (!~link.indexOf('http') && ~link.indexOf(':')) {
return match(link, {
decode: decodeURIComponent,
strict: ctx?.strict ?? true
})(pathname);
}
return pathname === encodeURI(link);
} }
})
return null;
}
} }
// { // {

View File

@ -54,6 +54,7 @@ fis.set('project.files', [
'/scss/helper.scss', '/scss/helper.scss',
'/scss/themes/*.scss', '/scss/themes/*.scss',
'/examples/*.html', '/examples/*.html',
'/examples/app/*.html',
'/examples/*.tpl', '/examples/*.tpl',
'/examples/static/*.png', '/examples/static/*.png',
'/examples/static/*.svg', '/examples/static/*.svg',
@ -906,7 +907,7 @@ if (fis.project.currentMedia() === 'publish') {
const DocNavCN = ret.src['/examples/components/DocNavCN.ts']; const DocNavCN = ret.src['/examples/components/DocNavCN.ts'];
const Components = ret.src['/examples/components/Components.tsx']; const Components = ret.src['/examples/components/Components.tsx'];
const DocCSS = ret.src['/examples/components/CssDocs.tsx']; const DocCSS = ret.src['/examples/components/CssDocs.tsx'];
const ExampleJs = ret.src['/examples/components/Example.tsx']; const ExampleJs = ret.src['/examples/components/Example.jsx'];
const pages = []; const pages = [];
const source = [ const source = [

View File

@ -1,3 +1,5 @@
rewrite ^\/examples\/app\/$ /examples/app/index.html
rewrite ^\/(?:zh-CN|en-US)?\/?(?:examples|docs|components|style)(?:\/[a-z0-9\-_\/]+)?$ /examples/index.html rewrite ^\/(?:zh-CN|en-US)?\/?(?:examples|docs|components|style)(?:\/[a-z0-9\-_\/]+)?$ /examples/index.html
rewrite ^\/play$ /examples/index.html rewrite ^\/play$ /examples/index.html