用于构建单页网络应用程序的JavaScript微型框架
下载CJS,ESM,UMD版本或通过NPM安装:
npm install @ryanmorr/avalonAvalon是管理Web应用程序的状态,路由和视图的多合一解决方案:
import avalon from '@ryanmorr/avalon' ;
const app = avalon ( {
count : 0
} ) ;
app . mutation ( 'increment' , ( { count } ) => {
return {
count : count + 1
} ;
} ) ;
app . action ( 'handleClick' , ( { commit } ) => {
commit ( 'increment' ) ;
} ) ;
app . view ( parent , ( html , { count } , dispatch ) => html `
< div >
< p > Count: ${ count } </ p >
< button onclick = ${ dispatch ( 'handleClick' ) } > Increment </ button >
</ div >
` ) ;查看todomvc示例。
avalon(state?)创建一个具有初始状态的应用程序实例作为普通键/值对象。 title属性是为当前文档标题保留的,将其更改将自动更新文档标题:
const app = avalon ( {
title : 'Hello World' ,
foo : 1 ,
bar : 2
} ) ;mutation(name, callback)通过提供名称和回调函数来定义突变,该名称和回调函数通过返回将合并到应用程序状态的部分状态对象同步更改状态:
app . mutation ( 'foo' , ( state , payload ) => {
return {
foo : payload
} ;
} ) ;commit(name, payload?)通过提供其名称和可选有效载荷来调用突变以更新应用程序状态,从而返回由突变产生的部分状态:
app . mutation ( 'foo' , ( state , n ) => ( { foo : n + 10 } ) ) ;
app . commit ( 'foo' , 10 ) ; //=> {foo: 20}action(name, callback)通过提供可用于响应DOM事件侦听器,执行异步操作,调度其他操作,提交突变等的名称和回调函数来定义操作。为第一个参数提供了操作回调函数的对象:
app . action ( 'foo' , ( { state , params , event , dispatch , commit , navigate , redirect , emit } ) => {
/**
* state - the current state of the app
* params - key/value object provided to the dispatcher or null if not provided
* event - the event object of user triggered DOM events or null if not applicable
* commit - function for calling mutations
* dispatch - function for dispatching actions or routes
* navigate - function for navigating to a URL path and dispatching a route
* redirect - function for redirecting to a URL path and dispatching a route
* emit - function for emitting a custom event
*/
} ) ;为了更好地支持异步操作,请定义用于解决呼叫的第二个参数(并且是拒绝呼叫的第三个参数),作为操作回调函数签名的一部分。派遣异步动作将自动返回承诺。这是您如何实施异步操作以从服务器获取数据的示例:
app . action ( 'load' , ( { params , commit } , resolve , reject ) => {
commit ( 'isLoading' , true ) ;
request ( '/get' , params ) . then ( ( data ) => {
commit ( 'isLoading' , false ) ;
commit ( 'setData' , data ) ;
resolve ( data ) ;
} ) . catch ( ( error ) => {
commit ( 'isLoading' , false ) ;
commit ( 'setError' , error ) ;
reject ( error ) ;
} ) ;
} ) ;
app . dispatch ( 'load' , { id : 'foo' } ) . then ( ( data ) => {
// Handle data
} ) . catch ( ( error ) => {
// Handle error
} ) ;route(path, callback)路由完全像操作一样工作,除了它们还响应了URL路径的变化,例如用户触发的点击事件和表单提交,对navigate和redirect方法的程序化调用,以及在会话历史记录堆栈中向前和向后移动和向后移动。必须用前锋斜线定义路线:
app . route ( '/' , ( { state , path , params , event , dispatch , commit , navigate , redirect , emit } ) => {
/**
* state - the current state of the app
* path - the URL path that matched the route
* params - key/value object extracted from a route's parameters or null if static path
* event - the event object of user triggered DOM events or null if not applicable
* commit - function for calling mutations
* dispatch - function for dispatching actions or routes
* navigate - function for navigating to a URL path and dispatching a route
* redirect - function for redirecting to a URL path and dispatching a route
* emit - function for emitting a custom event
*/
} ) ;路线支持参数,可选参数和通配符:
// Matches routes like "/a/b/c" and "/x/y/z"
app . route ( '/:foo/:bar/:baz' , ( { params : { foo , bar , baz } } ) => {
// Do something
} ) ;
// Matches routes like "/a/b" and "/a"
app . route ( '/:foo/:bar?' , ( { params : { foo , bar } } ) => {
// Do something
} ) ;
// Matches routes like "/", "/a", and "/a/b/c"
app . route ( '/*' , ( { params : { wildcard } } ) => {
// Do something
} ) ;dispatch(name?, params?)派遣具有可选参数或路线的操作。如果没有提供参数,则默认情况下使用当前的URL路径。返回操作/路由回调函数的返回值,或者如果是异步操作/路由,则返回承诺。
// Dispatch an action with parameters
app . dispatch ( 'foo' , { foo : 1 , bar : 2 } ) ;
// Dispatch the first matching route (parameters are extracted from the URL path)
app . dispatch ( '/foo/bar/baz' ) ;
// Dispatching an async action/route returns a promise
app . dispatch ( 'load' ) . then ( ( data ) => {
// Do something
} )view(element, callback)定义一个视图将在状态更改时立即通过虚拟DOM渲染并自动更新。通过标记模板,当前状态和方便的调度函数,提供了一个虚拟DOM构建器,以派遣操作和路由的方便调度函数,这是DOM事件侦听器,其可选参数作为键/值对象:
app . view ( parentElement , ( html , state , dispatch ) => html `
< div >
< p > Name: ${ state . name } </ p >
< button onclick = ${ dispatch ( 'handleClick' , { foo : 1 , bar : 2 } ) } > Increment </ button >
</ div >
` ) ;视图支持属性/属性,CSS样式作为字符串或对象,事件侦听器,由“ ON”前缀,有效列表diff的键节点和无状态功能组件表示:
const Item = ( html , props , dispatch ) => html `
< li key = ${ props . id } onclick = ${ dispatch ( 'handleClick' , { id : props . id } ) } >
${ props . children }
</ li >
` ;
app . view ( parentElement , ( html , state ) => html `
< ul class =" list " >
${ state . items . map ( ( item ) => html `
< ${ Item } id = ${ item . id } > ${ item . name } </ />
` ) }
</ ul >
` ) ;navigate(path)使用提供的URL路径将新的条目推入历史记录堆栈,并派遣第一个匹配路线。返回路由回调函数的返回值或如果是异步路由的承诺:
app . route ( '/foo' , ( ) => 'bar' ) ;
app . path ( ) ; //=> "/"
history . length ; //=> 0
app . navigate ( '/foo' ) ; //=> "bar"
app . path ( ) ; //=> "/foo"
history . length ; //=> 1redirect(path)用提供的URL路径代替当前历史记录条目,并派遣第一个匹配路线。返回路由回调函数的返回值或如果是异步路由的承诺:
app . route ( '/foo' , ( ) => 'bar' ) ;
app . path ( ) ; //=> "/"
history . length ; //=> 0
app . redirect ( '/foo' ) ; //=> "bar"
app . path ( ) ; //=> "/foo"
history . length ; //=> 0on(name, callback)订阅应用程序事件,返回一个函数以删除该特定的侦听器:
// Listen for state changes
app . on ( 'mutation' , ( name , nextState , prevState , partialState ) => {
// Do something
} ) ;
// Listen for when an action/route is dispatched
app . on ( 'dispatch' , ( type , state , name , params , event , returnValue ) => {
// Do something
} ) ;
// Listen for when the URL path changes
app . on ( 'pathchange' , ( path ) => {
// Do something
} ) ;
// Listen for when a view has been rendered
app . on ( 'render' , ( parentElement ) => {
// Do something
} ) ;
// Define your own custom event with parameters
const stop = app . on ( 'foo' , ( a , b , c , d ) => {
// Do something
} ) ;
// Stop listening for custom event
stop ( ) ;emit(name, ...args?)触发具有可选参数的自定义事件:
app . on ( 'foo' , ( a , b , c , d ) => {
// Do something
} ) ;
app . emit ( 'foo' , 1 , 2 , 3 , 4 ) ;state()获取当前状态对象:
const app = avalon ( {
title : 'Hello World'
foo : 1 ,
bar : 2
} ) ;
app . state ( ) ; //=> {title: "Hello World", foo: 1, bar: 2}path()获取当前的URL路径:
app . navigate ( '/foo' ) ;
app . path ( ) ; //=> "/foo"use(plugin)通过提供立即使用应用程序实例和当前状态调用的回调函数来添加插件。返回插件回调函数的返回值:
// A simple logging plugin
const log = app . use ( ( app , state ) => {
const events = [
'mutation' ,
'dispatch' ,
'pathchange' ,
'render'
] ;
events . forEach ( ( name ) => app . on ( name , console . log . bind ( console , name ) ) ) ;
return console . log . bind ( console , 'avalon' ) ;
} ) ; 该项目专用于公共领域,如不执行的描述。