2018-08-11 admin


什么是ef.js,(maybe) An elegant HTML template engine & basic framework


GitHub licensenpmBuild statusFOSSA Status

(maybe) An elegant HTML template engine & basic framework

ef.js is a static template framework for browsers, which you can write your UI without concerning about the logic, or writing logic without concerning about the UI.

ef.js also provides a simple template-engine which helps you create component modules with data binding at ease, but you can also use your favourite template-engine if it can be parsed into ef.js’s AST.

Official Website (WIP)


Related projects:

Community projects:


CDNJS | jsDeliver | UNPKG

For dev versions:

CDNJS | jsDeliver | UNPKG


import { create, onNextRender, inform, exec, bundle, setParser, parseEft, t, version } from 'ef.js'
// or you can use import * as ef from 'ef.js'

version // Version string of ef.js

setParser(someparser) // Change the default parser for ef.js so you can use a different type of template
parseEft('Your awesome template') // Get ef.js ast using default parser

const templateString = 'Your awesome template'
const ast = [/* AST which supported by ef */]

const data = {
	$data: {/* Binding data */},
	$methods: {/* Binding methods */}

const template1 = create(template)
const template2 = create(ast)
const template3 = t`Your awesome template`

const component1 = new template1() // Create a component without data
const component2 = new template2(data) // Create a component and then updates it's data

onNextRender(callback) // Cache operations to execute on next render
inform() // Tell ef to cache operations **USE WITH CARE**
exec() // Tell ef to execute all cached operations **USE WITH CARE**
exec(true) // Force execute cached operations **USE WITH CARE**
bundle(callback) // Wrapper for inform() and exec()

component1.$element // The DOM element of component1
component2.$element // The DOM element of component2

component1.$data.something = 'something new' // Update the binding data 'something'
component2.$methods.someMethod = ({e, value, state}) => {
	state.$data.something = 'something new'
	console.log('Event target', e.target)
	console.log('Value passed', value)
} // Update binding method

const logData = val => console.log('Subscribed data updated:', val)
component1.$subscribe('info.data', logData) // Observe a value
component1.$unsubscribe('info.data', logData) // Stop observing a value

component1.$update(data) // Update the whole component state
component2.$parent // Get where the component is mounted

component1.$refs // Get all referenced nodes

component1.mountingPoint = component2 // Mount component2 to 'mountingPoint' on component1
component1.mountingPoint = null // Detach the mounted component

component1.listMP.push(componet2) // Mount component2 to list 'listMP' mounting point on component1

component1.$mount(...) // Mount method called by ef when trying to mount
compinent1.$umount() // Unmount from parent
component1.$destroy() // Destroy the component when not needed for more memory

ef.js template language (EFML) format

EFML is a completely logic-free template language. Just like HTML, there you can do nothing about logic, but EFML provides a easy starting point for data binding and events handling.

Also EFML is the first language that can be parsed into the AST which ef supports.

Note: EFML is very strict to indents. Wrong indents could lead to a parsing error.

Here is an example.

Tree structure
Lines not started with >#%@.+- are considered as comments
The escape character of eft is '&', for prevention of the conflict with js escapes.
Except for the change of the character, all the usage should be the same.
this is a comment
'>' stands for tag name
	'#' stands for attributes
	Mustaches stands for binding data
	content inside mustaches after '=' stands for the default value for this binding
	content without mustaches stands for a static data
	which means that you cannot modify them using ef.js
	#class = {{class = some class name}}
	#style = {{attr.style = background: #ECECEC}}
	#id = testdiv
	#some-attr = some text
	'%' stands for properties
	%title = Welcome, {{name}}
	%anotherProperty = text
	'@' stands for events
	contents after ':' are considered as value passed to the handler
	@click = updateInfo:{{binding.value}} and static value
	modify keys now can be bind easily
	@mousedown.shift.alt.ctrl.meta = select
	bind to keys is also easy
	@keypress.13 = submit
	use '.prevent' to preventDefault, '.stop' to stopPropagation, '.stopImmediate' to stopImmediatePropagation
	@keydown.8.prevent.stop = stopbackspace
	use '.capture' to capture an event
	@submit.capture.stopImmediate = submit
	'.' stands for text nodes
	.Name: {{name}}&nJob: {{job}}
	'-' stands for standard mounting point
	'.' after a tag name stands for class names for this tag
		'#' at the end of a tag name stands for the reference name of the node
		Mustaches after a dot will bind to 'class' automatically
		>span.{{emergency = emergency}}#notice_box
			.Notice: {{notice}}
		.some text
		'+' stands for list mounting point

For standalone eft parser see eft-parser.

Run a test

git clone https://github.com/ClassicOldSong/ef.js.git
cd ef.js
npm install
npm run dev

Then you can test it out in the opening browser window.

Build from source

git clone https://github.com/ClassicOldSong/ef.js.git
cd ef.js
npm install
npm run build && npm run prod

Then you can get the fresh-built ef.min.js in the dist folder.

Note: All debugging messages are disabled in the production version.



FOSSA Status


转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]