Simple
v0.0.2-9-alpha
Published
A very Simple front-end ibrary
Downloads
20
Readme
Simple
Under Development. Fast Release Cycle on NPM. API might change
created by Yiyi Wang (shd101wyy)
Introduction
Simple is a very Simple front-end library without any extra dependencies.
It is extremely small and blazingly fast (maybe).
The idea of this library is from React and Atom Editor space-pen
let Demo = Simple.Component(function(message) {
return this.div(message)
})
Simple.render(Demo('Hello World'), document.getElementById('app'))
Component
View contains many Components
How Simple View Layer Works
Core of Simple mainly consists of 3 parts:
Component <= SimpleDOM <= SimpleElement
- SimpleElement
Low level abstraction for fast DOM manipulation.
You can regard SimpleElement as a kind of Virtual DOM, which helps improve DOM rendering speed. - SimpleDOM
Many native DOM element such asdiv, button, p
SimpleElement are already wrapped by SimpleDOM for you.
It offers many basic prototype functions such asgetDefaultProps
, etc. - Component
Inherited from SimpleDOM, Component is user-defined and highly flexible.
Component Lifecycle
init()
Invoked only once before the element is rendered. You should put all your initialization here.mount()
Invoked only once immediately after the element is rendered.update()
Invoked every time whenstate
orprops
is updated orforceUpdate
is called.
Invoked immediately after the element is done with updating rendering.
This is not called for the initial render.unmount()
Invoked immediately right before a component is unmounted from the DOM.
Use wrapped native DOM elements
<div> Hello World </div>
<div class="my-div"> This is my div </div>
<div style="background-color: #454545">
<h1 style="font-size: 48px;"> This is a Heading </h1>
<p> Very Cool </p>
</div>
Using Simple, we can rewrite that as
this.div('Hello World')
this.div({class: 'my-div'}, 'This is my div')
this.div({style: 'background-color: #454545'},
this.h1({style: {fontSize: '48px'}}, 'This is a Heading') // you can also define style as Object
this.p('Very Cool'))
Basically, it is in the format of
this.tagName([attributes], [...children]) // attributes, children can be omitted
Create your own Component
let MyComponent = Simple.Component({
render: function() { // render function has to be defined.
return this.div({class: 'my-component'}, 'Hello World')
}
})
Simple.render(MyComponent(), document.body)
Create Stateless Component
let Greetings = Simple.Component(function(name) {
return this.div(`Hello ${name}!`)
})
Simple.render(Greetings('Sexy Aaron'), document.body)
Bind Event for Component
Simple supports all native browser events such as click
, input
, and so on
The example below shows how to bind click
event to our button
, so that each time we click the button, the p
will update its content
let EventComponent = Simple.Component({
init: function() {
this.state = {count: 1}
},
render: function() {
return this.div(
this.p(this.state.count + ' seconds 🐸'),
this.button({'click': this.onClick.bind(this)}, '+1s'))
},
onClick: function() {
let count = this.state.count
this.setState({'count': count+1}) // setState function will render the element again
}
})
Embed Component inside another Component
We can use our defined Component inside another Component
For example:
let TodoItem = Simple.Component(function(todo) {
return this.div({style: {width: '400px', height: '16px', marginBottom: '6px'}},
todo)
})
let TodoList = Simple.Component({
getDefaultProps: function() {
return {title: 'No title defined',
data: ['Too young too simple', 'Sometimes native']}
},
render: function() {
return this.div({class: 'todo-list'},
this.h2(this.props.title),
this.props.data.map(todo => TodoItem( todo )))
}
})
let todoList = TodoList({title: 'My TODO List. (I don\'t like the default one)'})
Simple.render(todoList, document.getElementById('app'))
The rendered result is like below
Emitter
Emitter is the Simple library event layer.
Each emitter object should contain a state that is used to store your application data.
How to use Emitter
let emitter = Simple.createEmitter({count: 1}) // define a emitter with initial state
emitter.on('add', function(num) {
let count = this.state.count // get count that is stored in state
this.state.count += num // update count
})
emitter.emit('add', 2) // emit 'add' event with data '2'
emitter.emit('add', 3) // ...
emitter.state // => {count: 6}
Combine Component with Emitter
For the most of time, it is not recommended that a Component has state.
Instead, we use a Emitter to store the state and control the Component.
TODO Example using Component and Emitter
let emitter = Simple.createEmitter(function() {
this.state = {
todos: ['TODO Item 1', 'TODO Item 2'] // initial state
}
})
emitter.on('delete-todo', function(offset, component) {
let todos = this.state.todos
todos.splice(offset, 1)
component.setProps({todos})
})
emitter.on('add-todo', function(todo, component) {
let todos = this.state.todos
todos.push(todo)
component.setProps({todos})
})
let TodoItem = Simple.Component({
render: function() {
return this.div({style: 'clear: both; padding: 12px;', key: this.props.key},
this.p({style: 'float: left; margin: 0 24px 0 0; margin-right: 24px;' }, this.props.text),
this.button({click: this.deleteTodoItem.bind(this)}, 'x'))
},
deleteTodoItem: function() {
this.props.remove(this.props.key)
},
unmount: function() {
console.log('unmount component: ', this.props)
}
})
let Todo = Simple.Component({
emitter: emitter,
getDefaultProps: function() {
return {todos: this.emitter.state.todos}
},
render: function() {
return this.div({class: 'todo'},
this.h2({class: 'todo-title'}, this.props.title),
this.div({class: 'add-item-container'},
this.input({placeholder: 'add new item here', ref: 'inputBox'}),
this.button({click: this.clickAddItem.bind(this)}, 'Add Item')),
this.props.todos.map((d, i) => TodoItem({text: d, 'key': i, remove: this.removeItem.bind(this) })))
},
clickAddItem: function() {
this.emit('add-todo', this.refs.inputBox.value)
},
removeItem: function(offset) {
this.emit('delete-todo', offset)
}
})
let todo = Todo({title: 'This is TODO'})
Simple.render(todo, document.getElementById('app'))
emitter.emit('add-todo', 'This is new TODO item', todo) // emitter.emit([name], [data], [component])
// or
todo.emit('add-todo', 'This is another ner TODO item')
With Component and Emitter, we can build well-structured web applications ;)
How to use this library
I haven't published this library on npmjs
yet since this library is still under development.
The only way to use this library right now is to download it and include the Simple.js
file in html
file.
<head>
<script src="blablabla/Simple.js"> </script>
</head>
Thanks
MIT License
仅以此库祭奠我逝去的青春 eru pusai kongguruu