JavaScript Micro-Framework สำหรับการสร้างเว็บแอปพลิเคชันหน้าเดียว
ดาวน์โหลด CJS, ESM, UMD หรือติดตั้งผ่าน NPM:
npm install @ryanmorr/avalonAvalon เป็นโซลูชันแบบครบวงจรในการจัดการสถานะการกำหนดเส้นทางและมุมมองสำหรับเว็บแอพ:
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 ดำเนินการ async จัดส่งการกระทำอื่น ๆ กระทำการกลายพันธุ์ ฯลฯ ฟังก์ชั่นการเรียกกลับการกระทำนั้นเป็นวัตถุของข้อมูลที่เกี่ยวข้องและฟังก์ชั่นความสะดวกสบายเป็นพารามิเตอร์แรก:
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
*/
} ) ;เพื่อให้การสนับสนุนการดำเนินการ async ดีขึ้นให้กำหนดพารามิเตอร์ที่สองสำหรับการแก้ไขการโทร (และเลือกพารามิเตอร์ที่สามสำหรับการปฏิเสธการโทร) ซึ่งเป็นส่วนหนึ่งของลายเซ็นฟังก์ชั่นการโทรกลับของแอ็คชั่น การส่งการกระทำแบบ async จะส่งคืนสัญญาโดยอัตโนมัติ นี่คือตัวอย่างของวิธีที่คุณอาจใช้การกระทำแบบ async เพื่อดึงข้อมูลจากเซิร์ฟเวอร์:
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 เส้นทางและเลื่อนไปข้างหน้าและย้อนกลับในสแต็กประวัติเซสชัน เส้นทางจะต้องกำหนดด้วย Slash ไปข้างหน้า:
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 ปัจจุบันถูกใช้โดยค่าเริ่มต้น ส่งคืนค่าการส่งคืนของฟังก์ชั่นการเรียกร้องการกระทำ/เส้นทางหรือสัญญาหากเป็นการกระทำ/เส้นทาง Async
// 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", โหนดคีย์สำหรับรายการที่มีประสิทธิภาพแตกต่างกันและส่วนประกอบการทำงานไร้สัญชาติ:
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 ที่ให้ไว้และส่งเส้นทางการจับคู่แรก ส่งคืนค่าส่งคืนของฟังก์ชั่นการโทรกลับเส้นทางหรือสัญญาหากเป็นเส้นทาง Async:
app . route ( '/foo' , ( ) => 'bar' ) ;
app . path ( ) ; //=> "/"
history . length ; //=> 0
app . navigate ( '/foo' ) ; //=> "bar"
app . path ( ) ; //=> "/foo"
history . length ; //=> 1redirect(path)แทนที่รายการประวัติปัจจุบันด้วยเส้นทาง URL ที่ให้ไว้และจัดส่งเส้นทางการจับคู่แรก ส่งคืนค่าส่งคืนของฟังก์ชั่นการโทรกลับเส้นทางหรือสัญญาหากเป็นเส้นทาง Async:
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' ) ;
} ) ; โครงการนี้ทุ่มเทให้กับโดเมนสาธารณะตามที่อธิบายโดย Unlicense