Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/leekangtaqi/ninjajs
Micro and elegant frontend framework
https://github.com/leekangtaqi/ninjajs
front-end frontend-framework javascript ninja react react-like redux
Last synced: 2 months ago
JSON representation
Micro and elegant frontend framework
- Host: GitHub
- URL: https://github.com/leekangtaqi/ninjajs
- Owner: leekangtaqi
- Created: 2016-11-04T02:07:15.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2019-07-22T06:23:26.000Z (over 5 years ago)
- Last Synced: 2024-11-15T00:43:24.676Z (3 months ago)
- Topics: front-end, frontend-framework, javascript, ninja, react, react-like, redux
- Language: JavaScript
- Homepage:
- Size: 559 KB
- Stars: 13
- Watchers: 6
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Micro and elegant frontend framework
Like a ninja, Ninjajs dexterous and elegant, and its body full of magic weapons that simple but powerful.
Ninjajs will help you to use the simple way to build complex systems.
"Practical but not fancy" is its talisman.## Geting Started
## Install
```shell
$ npm install ninjajs
```## Pay A Glance
```
$ npm run dev
```http://localhost:8080
## Usage
### Startup
main.js
```javascript
import App from 'path to xxx component'let app = Ninja({container: window, reducer, middlewares, state: {}}) // container, reducer, middlewares, initialState
app.set('routes', routes)
app.start(async () => {
// set entry for the application.
app.set('entry', new App(document.getElementById('app')))
})
```### API
**set(key, val)**
*
key
\
*val
\buildin config - key -> value
*env
\ application environment - production, development, test
*mode
\ browser or history
*context
\ application context obj (store, tags, ...others)
*routes
\ expect a plain obj to describe the routes (more in below)
*entry
\ application entry component**registerWidget(options)**
*
options.name
\
*options.methods
\
allow user to control component with method invocation.
eg:
app.registerWidget({
name: 'modal',
methods: ['open']
})**start()**
all ready callback
### Component
#### Define component
```javascript
@Componnet // register this component to hub, in order to use it in html directly.
export default class Todo extends Ninja.Component {get tmpl() {
return require('path to template of component');
}onCreate(opts) {}
}
```#### State Management
redux like:```javascript
@Connect(
state => ({
...states
}),
dispatch => ({
...actions
})
)
export default class Todo extends Ninja.Component {}
```### Router
#### Define routes
```javascript
import TodoList from '...path to component';export default {
component: App,
path: '',
children: [
{
path: '/',
component: TodoList,
defaultRoute: true
}
]
}
```
#### Fields
| field | type | desc |
| ------------- |:-------------:| :-----|
| path | string | Corresponding URI, Relative path |
| component | Object | Component constructors |
| children | Array | sub routes outlets |
| defaultRoute | Boolean | specify that this is a default route |
| components | Object | dynamic route defined, get identifier from query string |
| abstract | Boolean | specify that this is a abstract route, no Corresponding component |
| ...others | Any | will be get from context.req.body |#### Context
1. req \| field | type |
| -------- |:----------- |
| params | Object |
| body | Object |
| query | Object |#### Router outlet in html
```html
greeting!
```#### Component life cycle about router
| evts |
| ------------ |
| enter |
| before-leave |
| leave |
| leaved |eg:
```javascript
@View // this decorator specify that component will be a view, give the component relevant features
export default class Todo extends Ninja.Component {
// ...others
onCreate(opts) {
this.on('enter', ctx => {
// todo
})
this.on('before-leave', ctx => {
// todo
})
this.on('leave', ctx => {
// todo
})
this.on('leaved', ctx => {
// todo
})
}
}
``````javascript
// Advanced Usage
class Foo extends Ninja.Component {
// ...others
// decorator onUse
// @param , when nav to this component, the middlewares (defined in 'opts') will be invoke.
// each middleware method will be injected a callback ( component will be present when the callback invoked ) and a
// router context object.
// eg: const enterFoo = (next, ctx)
@onUse('enterFoo')
onCreate(opts) {}
}
```#### Route hooks
**1. history-pending - callback(from, to, location, context[, next])**
*
from
\ from which Component
*to
\ to which Component
*location
\ uri
*context
\ context object
*req
\ request object
*params
\
*body
\
*query
\
*next
\ execution callback, if exists, the execution won`t be continue until next being executed**2. history-resolve - callback(from, to, context, routes, index[, next])**
*
from
\ from which Component
*to
\ to which Component
*context
\ context object
*req
\ request object
*params
\
*body
\
*query
\
*routes
\ uris
*index
\ current index in uris
*next
\ execution callback, if exists, the execution won`t be continue until next being executedeg:
```
app.hub.subscribe('history-pending', (from, to, location, context, next) => {})app.hub.subscribe('history-resolve', (from, to, context, routes, index) => {})
```### Form
#### Buildin rules
* required
* max
* min
* maxlength
* minlength
* pattern#### API
* registerValidators(name, fn)
* name \
* fn \
Register customer validators#### Detail
* Integrate with Redux
A action will be dispatched when interact with inputs.
You will get corrent value in state and opts.
Attached to opts:
* submit \ submit specific form manually.
* forms \ forms map.* input fields & add class
* field
* $valid
* $invalid
* $dirty
* $pristine
* $error
* $originVal
* $val
* class
* f-valid
* f-invalid
* f-dirty
* f-pristine
* multi form validation supported#### Example
```javascript
@Form({
username: {
required: true,
minlength: 2,
maxlength: 20
},
password: {
required: true,
min: 1,
max: 10
},
address: {
pattern: /.*/
}
})
class Foo extends Ninja.Component {
// ...others
async onSubmit() {
e.preventDefault();
this.opts.submit('FormA') // submit specific form manually
if (this.opts.forms.FormA.$invalid) {
return;
}
}
}
``````html
.f-valid {
border: green
}
.f-invalid {
border: red
}
.f-dirty {
}
.f-pristine {
}
username required!
```
### Usage v2.* (Deprecated)
#### routes.js
```javascript
export default {
component: 'app',
children: [
{
path: '/',
defaultRoute: true,
component: 'count',
},
{
path: '/test',
component: 'test',
children: [
{
path: '/test2',
component: 'test2'
}
]
}
]
}
``````javascript
//main.js
import { router Ninja } from 'ninjajs';let app = new Ninja(container, reducer, middlewares, initialState); // create ninja application
app.set('env', process.env.NODE_ENV === 'production' ? 'production' : 'development');
app.set('mode', 'browser');
app.set('context', { store: app.store, hub: router.hub, tags: {} });
router.hub.routes = routes; // set routes
app.router(router);
app.start(async () => {
//todo
})```
```javascript
//componentrequire('path-to-nest');
Hello World
import { connect } from 'ninjajs';
connect( //redux like
state => ({}),
dispatch => ({})
)(this)
this.mixin('router'); // mixin router, if you wanna use middleware (the $use method)
this.$use(function(next, ctx){
//trigger when nav to this component
})```
## Who's using
## Buy us a coffee
## More
source for more detail## Contact
* WX: leekangtaqi
* QQ: 2811786667