用於構建單頁網絡應用程序的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' ) ;
} ) ; 該項目專用於公共領域,如不執行的描述。