route refactoring

This commit is contained in:
daizhan 2018-11-07 13:37:06 +08:00
parent 08046e4a2b
commit b2e18dfe4c
19 changed files with 201 additions and 444 deletions

View File

@ -52,7 +52,7 @@
"scripts": {
"start": "node scripts/start.js",
"_build": "node scripts/build.js",
"build":"PUBLIC_URL=https://tencent.github.io/omi/packages/omi-router/examples/spa/build npm run _build",
"build": "PUBLIC_URL=https://tencent.github.io/omi/packages/omi-router/examples/spa/build npm run _build",
"fix": "eslint src --fix"
},
"jest": {

View File

@ -1,11 +1,6 @@
import route from 'omi-router'
import { define, WeElement } from 'omi'
import logo from './logo.png'
import style from './_index.css'
import normalizeStyle from '../../assets/_normalize.css'
import navInfo from './nav'
import '../views/not-found'
import route from '../../route'
import '../common/app-frame'
define('my-app', class extends WeElement {
static get data() {
@ -16,247 +11,23 @@ define('my-app', class extends WeElement {
data = {
pageTitle: '',
pageContainerClass: [],
routeParams: null,
navInfo: [],
showPageLoading: false
}
css() {
return normalizeStyle + style
}
initRoute(routeInfo) {
let routeList = []
for (let mainNav of navInfo) {
if (mainNav.children) {
for (let childNav of mainNav.children) {
let childRouteList = []
if (childNav.children && childNav.children.length) {
for (let pageNav of childNav.children) {
childRouteList.push({
title: pageNav.label,
labelbList: [mainNav.label, childNav.label, pageNav.label],
path: '/' + [mainNav.code, childNav.code, pageNav.code].join('/'),
tag: [mainNav.code, childNav.code, pageNav.code].join('-')
})
}
}
if (childRouteList.length) {
if (!mainNav.path) {
mainNav.path = childRouteList[0].path
}
if (!childNav.path) {
childNav.path = childRouteList[0].path
}
routeList = routeList.concat(childRouteList)
} else {
if (!childNav.path) {
childNav.path = '/' + mainNav.code + '/' + childNav.code
routeList.push({
title: childNav.label,
labelbList: [mainNav.label, childNav.label],
path: childNav.path,
tag: [mainNav.code, childNav.code].join('-')
})
}
if (!mainNav.path) {
mainNav.path = '/' + mainNav.code + '/' + childNav.code
}
}
}
} else {
mainNav.path = '/' + mainNav.code
routeList.push({
title: mainNav.label,
labelbList: [mainNav.label],
path: '/' + mainNav.code,
tag: mainNav.code
})
}
}
route('/', params => {
route.to(routeList[0].path, params)
})
for (let item of routeList) {
route(item.path, params => {
window.document.title = item.title
this.data.tag = item.tag
this.data.pageContainerClass = []
this.data.routeParams = params
this.data.pageTitle = item.labelbList
this.updateFramework(this.data.navInfo, item.path.slice(1).split('/'))
})
}
route('/home-page', params => {
window.document.title = 'home-page'
this.data.tag = 'home-page'
this.data.pageContainerClass = ['no-page-title', 'no-side-nav']
this.data.routeParams = null
this.data.pageTitle = ''
this.updateFramework(this.data.navInfo, [], true)
this.data.navInfo[0].selected = true
})
route('*', () => {
if (location.hash === '') {
this.data.tag = 'home-page'
this.data.pageContainerClass = ['no-page-title', 'no-side-nav']
} else {
window.document.title = '404 NotFound'
this.data.tag = 'not-found'
this.data.pageContainerClass = ['no-page-title', 'no-side-nav']
this.data.routeParams = null
this.data.pageTitle = ''
this.updateFramework(this.data.navInfo, [], true)
}
})
route.before = event => {
if (event.newURL.match('/#/nav1/module2/page1')) {
this.data.showPageLoading = true
}
}
routeList: []
}
install() {
this.data.navInfo = navInfo
this.initRoute(navInfo)
}
onPageLoaded() {
this.data.showPageLoading = false
}
updateFramework(navInfo, navPath, isClear = false) {
let foundPath = false
if (!isClear) {
if (!Array.isArray(navPath) || !navPath.length) {
return false
}
this.data.routeList = route(this)
// show home page if hash is empty
if (location.hash === '') {
location.hash = '/'
}
if (!Array.isArray(navInfo) || !navInfo.length) {
return false
}
for (let mainNav of navInfo) {
if (isClear || mainNav.code !== navPath[0]) {
mainNav.selected = false
this.updateFramework(mainNav.children, navPath.slice(1), true)
} else {
foundPath = true
if (
(!Array.isArray(mainNav.children) || mainNav.children.length) &&
navPath.length === 1
) {
mainNav.selected = true
} else {
mainNav.selected = this.updateFramework(
mainNav.children,
navPath.slice(1)
)
}
}
}
return foundPath
}
getRenderedNav(props, data) {
let mainNav = []
let subNav = []
for (let nav of this.data.navInfo) {
mainNav.push(
<li class={nav.selected ? 'selected' : ''}>
<a href={'#' + nav.path}>{nav.label}</a>
</li>
)
if (nav.selected && nav.children && nav.children.length) {
for (let childNav of nav.children) {
subNav.push(
<li class={childNav.selected ? 'selected' : ''}>
<a href={'#' + childNav.path}>{childNav.label}</a>
</li>
)
}
if (subNav.length) {
subNav = [
<nav class="sub-nav">
<ul>{subNav}</ul>
</nav>
]
}
}
}
return {
mainNav,
subNav
}
}
getRenderedPageTitle(props, data) {
let parentTitle = []
let currentTitle = ''
if (Array.isArray(this.data.pageTitle) && this.data.pageTitle.length) {
parentTitle = this.data.pageTitle.slice(0, -1)
currentTitle = this.data.pageTitle[this.data.pageTitle.length - 1]
return (
<h2 class="page-title">
{parentTitle.join(' / ')} {parentTitle.length > 0 && '/'} <strong>{currentTitle}</strong>
</h2>
)
}
return ''
}
render(props, data) {
let { mainNav, subNav } = this.getRenderedNav(props, data)
let pageTitle = this.getRenderedPageTitle(props, data)
return (
<div class="app">
<header class="app-header">
<h1 class="app-title">
<a href="#/">
<img src={logo} class="app-logo" alt="logo" />
Omi SPA
</a>
</h1>
<nav class="main-nav">
<ul>{mainNav}</ul>
</nav>
<div class="user-info">
<a href="#/not-found">
<p class="username">
username
<img src={logo} class="avatar" />
</p>
</a>
</div>
</header>
<div>
{subNav}
<div
class={'page-container ' + this.data.pageContainerClass.join(' ')}
>
{pageTitle}
<div class="page-content">
<this.data.tag
params={this.data.params}
onPageLoaded={e => this.onPageLoaded(e)}
/>
<div
class={
'page-shade-layer ' +
(this.data.showPageLoading ? 'show' : '')
}
>
<p>页面加载中...</p>
</div>
</div>
</div>
</div>
<footer>
<p>Omi router sample with omi-cli</p>
</footer>
</div>
<app-frame routeList={this.data.routeList}>
<this.data.tag slot="page-content" params={this.data.params} />
</app-frame>
)
}
})

View File

@ -1,71 +0,0 @@
import '../views/nav1/module1/page1'
import '../views/nav1/module2/page1'
import '../views/nav2/module1/page1'
import '../views/nav2/module2/page1'
import '../views/home-page'
export default [
{
label: 'Home',
code: 'home-page',
selected: true
},
{
label: 'nav one',
code: 'nav1',
selected: false,
children: [
{
label: 'module one',
code: 'module1',
selected: false,
children: [
{
label: 'page one',
code: 'page1'
}
]
},
{
label: 'module two',
code: 'module2',
selected: false,
children: [
{
label: 'page one',
code: 'page1'
}
]
}
]
},
{
label: 'nav two',
code: 'nav2',
selected: false,
children: [
{
label: 'module one',
code: 'module1',
selected: false,
children: [
{
label: 'page one',
code: 'page1'
}
]
},
{
label: 'module two',
code: 'module2',
selected: false,
children: [
{
label: 'page one',
code: 'page1'
}
]
}
]
}
]

View File

@ -72,84 +72,17 @@
margin-left: 10px;
}
.sub-nav {
float: left;
background-color: white;
width: 200px;
}
.sub-nav a {
display: block;
height: 48px;
line-height: 48px;
padding-left: 30px;
color: rgba(0,0,0,0.65);
}
.sub-nav a:hover {
color: #1890FF;
}
.sub-nav li.selected a {
color: #1890FF;
}
.sub-nav li.selected{
position: relative;
background: #E6F7FF;
}
.sub-nav li.selected::after{
content: '';
position: absolute;
display: block;
top: 0;
right: 0;
bottom: 0;
width: 4px;
background-color: #1890FF;
}
.page-container {
margin-left: 200px;
padding: 0 20px 20px;
padding: 20px;
background: #F0F2F5;
}
.page-container.no-side-nav {
margin-left: 0;
}
.page-container.no-page-title {
padding-top: 20px;
}
.page-title {
line-height: 48px;
height: 48px;
color: rgba(0,0,0,0.45);
}
.page-title strong {
color: rgba(0,0,0,0.65);
}
.page-content {
position: relative;
background: #fff;
min-height: 500px;
padding: 20px;
}
.page-shade-layer {
display: none;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
}
.page-shade-layer.show {
display: block;
}
.page-shade-layer p{
width: 100%;
text-align: center;
color: rgba(0,0,0,0.45);
position: absolute;
top: 45%;
}
footer {
clear: both;

View File

@ -0,0 +1,71 @@
import { define, WeElement } from 'omi'
import logo from './logo.png'
import style from './_index.css'
import normalizeStyle from '../../../assets/_normalize.css'
define('app-frame', class extends WeElement {
static get data() {
return { name: '' }
}
static observe = true
data = {
name: 'Omi SPA'
}
css() {
return normalizeStyle + style
}
install() {}
getRenderedNav(props, data) {
let mainNav = []
for (let nav of props.routeList) {
if (nav.path !== '*') {
mainNav.push(
<li class={nav.selected ? 'selected' : ''}>
<a href={'#' + nav.path}>{nav.label}</a>
</li>
)
}
}
return mainNav
}
render(props, data) {
let mainNav = this.getRenderedNav(props, data)
return (
<div class="app">
<header class="app-header">
<h1 class="app-title">
<a href="#/">
<img src={logo} class="app-logo" alt="logo" />
{this.data.name}
</a>
</h1>
<nav class="main-nav">
<ul>{mainNav}</ul>
</nav>
<div class="user-info">
<a href="#/not-found">
<p class="username">
username
<img src={logo} class="avatar" />
</p>
</a>
</div>
</header>
<div class="page-container">
<div class="page-content">
<slot name="page-content" />
</div>
</div>
<footer>
<p>Omi router sample SPA</p>
</footer>
</div>
)
}
})

View File

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 145 KiB

View File

@ -7,10 +7,17 @@ define('home-page', class extends WeElement {
css() {
return (
normalizeStyle +
'p { text-align: center; padding-top: 100px; font-size: 20px; }'
'div { text-align: center; padding-top: 100px; font-size: 20px; }' +
'a { color: #1890FF; font-size: 14px;}'
)
}
render() {
return <p>Home</p>
return (
<div>
<p>Hi Welcome to Omi.</p>
<p>the Next Generation Web Framework in 4kb JavaScript</p>
<a href="https://github.com/Tencent/omi">learn more about Omi</a>
</div>
)
}
})

View File

@ -1,15 +0,0 @@
import { define, WeElement } from 'omi'
import normalizeStyle from '../../../../assets/_normalize.css'
define('nav1-module1-page1', class extends WeElement {
static observe = true
install() {
this.fire('pageloaded')
}
css() {
return normalizeStyle
}
render() {
return <p>page one is here</p>
}
})

View File

@ -1,17 +0,0 @@
import { define, WeElement } from 'omi'
import normalizeStyle from '../../../../assets/_normalize.css'
define('nav1-module2-page1', class extends WeElement {
static observe = true
install() {
setTimeout(() => {
this.fire('pageloaded')
}, 3000)
}
css() {
return normalizeStyle
}
render() {
return <p>page one is here</p>
}
})

View File

@ -0,0 +1,24 @@
import { define, WeElement } from 'omi'
import normalizeStyle from '../../../../assets/_normalize.css'
define('omi-weui-page', class extends WeElement {
static observe = true
install() {}
css() {
return (
normalizeStyle +
'div { text-align: center; padding-top: 100px; font-size: 20px; }' +
'a { color: #1890FF; font-size: 14px;}'
)
}
render() {
return (
<div>
<p>WeUI Components build with Omi is coming soon</p>
<a href="https://github.com/omijs/omi-weui">
learn more about omi-weui
</a>
</div>
)
}
})

View File

@ -1,15 +0,0 @@
import { define, WeElement } from 'omi'
import normalizeStyle from '../../../../assets/_normalize.css'
define('nav2-module1-page1', class extends WeElement {
static observe = true
install() {
this.fire('pageloaded')
}
css() {
return normalizeStyle
}
render() {
return <p>page one is here</p>
}
})

View File

@ -1,15 +0,0 @@
import { define, WeElement } from 'omi'
import normalizeStyle from '../../../../assets/_normalize.css'
define('nav2-module2-page1', class extends WeElement {
static observe = true
install() {
this.fire('pageloaded')
}
css() {
return normalizeStyle
}
render() {
return <p>page one is here</p>
}
})

View File

@ -0,0 +1,29 @@
import { define, WeElement } from 'omi'
import normalizeStyle from '../../../../assets/_normalize.css'
define('omi-router-page', class extends WeElement {
static observe = true
install() {}
css() {
return (
normalizeStyle +
'div { text-align: center; padding-top: 100px; font-size: 20px; }' +
'a { color: #1890FF; font-size: 14px;}'
)
}
render() {
return (
<div>
<p>
omi-router is the Omi official router plugin of Omi.
<br />
it's lightweight, easy and powerful to build Omi's SPA(Single Page
Application)
</p>
<a href="https://github.com/Tencent/omi/tree/master/packages/omi-router">
learn more about omi-router
</a>
</div>
)
}
})

View File

@ -1,7 +1,7 @@
import { define, WeElement } from 'omi'
import normalizeStyle from '../../../assets/_normalize.css'
define('not-found', class extends WeElement {
define('not-found-page', class extends WeElement {
static observe = true
css() {

View File

@ -0,0 +1,9 @@
import '../elements/views/not-found-page'
export default [
{
label: '404 not-found',
path: '*',
tag: 'not-found-page'
}
]

View File

@ -0,0 +1,16 @@
import route from 'omi-router'
import routeList from './route'
export default function(omiElement) {
for (let item of routeList) {
route(item.path, params => {
window.document.title = item.label
omiElement.data.pageTitle = item.label
omiElement.data.tag = item.tag
omiElement.data.routeParams = params
routeList.forEach(routeItem => (routeItem.selected = false))
item.selected = true
})
}
return routeList
}

View File

@ -0,0 +1,7 @@
import '../elements/views/nav1/omi-weui-page'
export default {
label: 'omi-weui',
path: '/omi-weui',
tag: 'omi-weui-page'
}

View File

@ -0,0 +1,9 @@
import '../elements/views/nav2/omi-router-page'
export default [
{
label: 'omi-router',
path: '/omi-router',
tag: 'omi-router-page'
}
]

View File

@ -0,0 +1,14 @@
import '../elements/views/home-page'
import nav1Route from './nav1'
import nav2Route from './nav2'
import errorRoute from './error'
let routeList = [
{
label: 'Home',
path: '/',
tag: 'home-page'
}
]
export default routeList.concat(nav1Route, nav2Route, errorRoute)