react-view-router@2.x
A Route manager for
react
can write routing configuration like vue-router in react. see: Nested Routes
Unlike 1.x,
react-view-router@2.x
does not depend on the react-router Library
中文说明
Installation
npm install react-view-router --save
# or
yarn add react-view-router
Basic Usage
/// router.js
import ReactViewRouter from 'react-view-router';
const router = new ReactViewRouter({
base: '', // the base URL of the app. For example, if the entire single page application is served under /app/, then base should use the value "/app/"
mode: 'hash', // or browser|memory|hash, default:hash
routes: [] // also can be passed by router.use method
});
export default router;
/// app.js
import React from 'react';
import { RouterView } from 'react-view-router';
import router from './router';
import routes from './routes';
router.use({ routes });
router.beforeEach((to, from, next) => {
if (to) {
console.log(
'%croute changed',
'background-color:#ccc;color:green;font-weight:bold;font-size:14px;',
to.url, to.query, to.meta, to.redirectedFrom
);
return next();
}
});
function App() {
const filter = routes => routes.filter(r => !r.meta.hide);
return (
<div>
<h1>App</h1>
<RouterView
router={router}
filter={filter}
fallback={<div>loading</div>}
/>
</div>
);
}
/// home/index.js
import React from 'react';
import { RouterView } from 'react-view-router';
export default function HomeIndex() {
return (
<div>
<h1>HomeIndex</h1>
<RouterView />
</div>
);
}
/// home/main/index.js
import React from 'react';
import { RouterView } from 'react-view-router';
export default function HomeMainIndex() {
return (
<div>
<h1>HomeMainIndex</h1>
<RouterView />
<RouterView name="footer" />
</div>
);
}
/// home/home/main/some/index.js
import React from 'react';
import { withRouteGuards } from 'react-view-router';
import store from 'store';
class HomeMainSomeIndex extends React.Component {
constructor(props) {
super(props);
this.state = { text: 'text1' };
}
refresh = () => {
this.setState({ text: 'text1 refreshed' })
}
render() {
let { text } = this.state;
return (
<div>
<h1>HomeMainSomeIndex</h1>
{ text }
</div>
);
}
}
export default withRouteGuards(HomeMainSomeIndex, {
beforeRouteEnter(to, from, next) {
if (!store.logined) next('/login');
else next(vm => vm.refresh());
},
beforeRouteLeave(to, from, next) {
// confirm leave prompt
next();
},
beforeRouteUpdate(to, from) {
},
afterRouteLeave(to, from) {
},
});
/// home/main/some/footer.js
import React from 'react';
export default function HomeMainSomeFooter() {
return (
<div>
<h1>HomeMainSomeFooter</h1>
</div>
)
}
/// login/index.js
import React from 'react';
import store from './store';
import router from './router';
export default function LoginIndex() {
const doLogin = () => {
store.logined = true;
router.push({
path: '/home',
query: { aa: 1 }
}, () => {
console.log('router.push is complete!');
}, () => {
console.log('router.push is abort!');
});
};
return (
<div>
<h1>LoginIndex</h1>
<button onClick={doLogin}>Login</button>
</div>
);
}
/// routes.js
import { normalizeRoutes, lazyImport } from 'react-view-router';
import Home from './home';
import Login from './login';
const routes = normalizeRoutes([
{
path: '/home',
component: Home
// children routes
children: [
// path redirect
{ path: '/', redirect: 'main' },
// or path index
// { path: '/', index: 'main' },
{
path: 'main',
// lazy load
component: lazyImport(() => import(/* webpackChunkName: "home" */ './home/main')),
// route meta infos
meta: { needLogin: true },
children: [
{ path: '/', redirect: to => ({ path: 'some', query: { aa: 1, bb: 2 } }) },
{
path: 'some',
components: {
default: lazyImport(() => import(/* webpackChunkName: "home" */ './home/main/some')),
footer: lazyImport(() => import(/* webpackChunkName: "home" */ './home/main/some/footer.js')),
}
// route guards:
beforeEnter(to, from, next) { next(); }
beforeLeave(to, from, next) { next(); }
beforeUpdate(to, from) {}
afterLeave(to, from) {}
}
]
}
]
},
{
path: '/login',
component: Login
}
])
APIs
Route Option
-
path
URL string. -
component
React component. -
components
React components that be used forNamed RouterView
. -
exact
Whether only matches withlocation.pathname
exactly. -
strict
When true, a path that has a trailing slash will only match a location.pathname with a trailing slash. This has no effect when there are additional URL segments in the location.pathname. -
redirect
Navigates to new location, can be string, object or function. -
index
index route name, can be string or function. -
children
Nested child routes. -
meta
some custom route infos, see: Route Meta Fields. -
defaultProps
object{ aa: 1, bb: '2', cc: true }
, give some props into route component. -
props
boolean or object{ aa: Number, bb: String, cc: Boolean }
, Pass url params as a prop into route component. -
paramsProps
boolean or object{ aa: Number, bb: String, cc: Boolean }
, Pass url params as props into route component. -
queryProps
boolean or object{ aa: Number, bb: String, cc: Boolean }
, Pass url query as props into route component. -
guards
the route guards, see:Per-Route Guard
RouterView Props
-
name
Use forNamed Views
, see vue-router instructions -
filter
is a function:function (routes: Array) { return [] }
that use for filter routes -
fallback
can be a functionfunction ({ parentRoute, currentRoute, inited, resolving, depth }) { return <div /> }
, orReact Component Element
like this:<Loading>loading</Loading>
RouterView Instance Methods
-
RouterView.push(routes: Array): Array
add routes to RouterView instance, likeArray.push
; -
RouterView.splice(start[, deleteCount[, item1[, item2[, ...]]]]): Array
delete routes in RouterView instance, likeArray.splice
; -
RouterView.indexOf(route: String|Object): Number
checkroute
is in RouterView, likeArray.indexOf
-
RouterView.remove(route: String|Object): Object
removeroute
from RouterView, returnremoved route
orundefined
ReactViewRouter Props
-
currentRoute
current matched route infos:
{
url: String,
// A string that equals the path of the current route, always resolved as an absolute path
path: String,
// The full resolved URL including query and hash.
fullPath: String,
// true if the path matches the location.pathname exactly.
isExart: Boolean,
// An Array containing route records for all nested path segments of the current route.
matched: [
route1,
// route2:
{
// the path from route config
path: String,
// the subpath from route config
subpath: String,
// the meta from route config
meta: Object,
// the redirect from route config
redirect: String|Object|Function,
// the original route config
config,
// the component instance that matched this route config if found.
componentInstances: {
default: React.Component,
/* others: React.Component */
}
// the RouterView instance that matched this route config if found.
viewInstances: {
default: RouterView
}
}
...,
routeN
],
// An object that contains key/value pairs of dynamic segments and star segments. If there are no params the value will be an empty object.
params: Object,
// An object that contains key/value pairs of the query string. For example, for a path /foo?user=1, we get currentRoute.query.user == 1. If there is no query the value will be an empty object.
query: Object,
// The name of the route being redirected from, if there were one
redirectedFrom: Object,
// The route abort function that passed by `router.push`, `router.replace`, `router.redirect`
onAbort: Function,
// The route complete function that passed by `router.push`, `router.replace`, `router.redirect`
onComplete: Function,
}
ReactViewRouter instance Props
-
RouterLink
aNavLink
component likeroute-link
invue-router
. -
currentRoute
the current route that matched current url. -
initialRoute
the initial route when router be created.
ReactViewRouter instance Methods
-
beforeEach
global before guards -
beforeResolve
global brefore resolve guards -
afterEach
global after guards -
push
、replace
、go
、back
、forward
redirect
history navigation methods -
parseQuery
、stringifyQuery
Provide custom query string parse / stringify functions, can be override bynew ReactViewRouter({ parseQuery: parseQueryMethod, stringifyQuery: stringifyQueryMethod });
-
install
ReactVueLike
plugin install methods. see: ReactVueLike
Export Methods
-
withRouteGuards
route component guards methods:
/**
* route component guards methods
* @param {Object} component - route component
* @param {Object} guards - guards methods
* @param {Class} [componentClass] - the route component class, it will be useful when component is High-order components
* @return {RouteComponentGuards} - the route componet that can be regarded as `React.forwardRef`
**/
function withRouteGuards(component, guards = {}, componentClass?) {}
-
lazyImport
route component lazy load method:
/**
* route component lazy load method
* @param {Function} importMethod - webpack lazy import method, For example: () => import('@/components/some-component')
* @return {RouteLazy} - the result only be used with component or components props in route config
**/
function lazyImport(importMethod) {}
-
normalizeRoutes
normalize route configs:
/**
* normalize route configs
* @param {Array} routes - unnormalized route configs
* @param {Object} [parent] - if provide, routes will be resolved regarded as parert`s children
* @return {Array} - normalized route configs
**/
function normalizeRoutes(routes, parent?) {}
-
normalizeLocation
normalize location string or object:
/**
* normalize location string or object
* @param {Object|string} to - location that need to normalize
* @param {Object} [route] - if provide, location will be resolved with route.parert
* @return {Object} - normalized location object: { path: string, pathname: string, search: string, query: Object, ...custom props }
**/
function normalizeLocation(to, route?) {}
-
isLocation
determine whetherv
is a location object
/**
* determine whether `v` is a location object
* @param {Object} v - the object to be determined
* @return {boolean}
**/
function isLocation(v) {}
-
matchPath
just re-export, see: matchPath
NOTE
- if route component is
Class Component
(notFunction Component
), thenthis
variable inbeforeRouteUpdate
,beforeRouteLeave
,afterRouteLeave
Component Guards will be that component instance;