JavaScript Mikro-Kerangka Mikro untuk Membangun Aplikasi Web Halaman Tunggal
Unduh versi CJS, ESM, UMD atau instal melalui NPM:
npm install @ryanmorr/avalonAvalon adalah solusi all-in-one untuk mengelola keadaan, perutean, dan tampilan untuk aplikasi 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 >
` ) ;Lihat contoh TODOMVC.
avalon(state?) Buat instance aplikasi dengan keadaan awal sebagai objek kunci/nilai biasa. Properti title dicadangkan untuk judul dokumen saat ini, mengubahnya akan secara otomatis memperbarui judul dokumen:
const app = avalon ( {
title : 'Hello World' ,
foo : 1 ,
bar : 2
} ) ;mutation(name, callback)Tentukan mutasi dengan memberikan nama dan fungsi panggilan balik yang secara sinkron mengubah status dengan mengembalikan objek keadaan parsial yang akan digabungkan ke dalam keadaan aplikasi:
app . mutation ( 'foo' , ( state , payload ) => {
return {
foo : payload
} ;
} ) ;commit(name, payload?)Hubungi mutasi untuk memperbarui status aplikasi dengan memberikan namanya dan muatan opsional, mengembalikan keadaan parsial yang dihasilkan dari mutasi:
app . mutation ( 'foo' , ( state , n ) => ( { foo : n + 10 } ) ) ;
app . commit ( 'foo' , 10 ) ; //=> {foo: 20}action(name, callback)Tentukan suatu tindakan dengan memberikan nama dan fungsi panggilan balik yang dapat digunakan untuk menanggapi pendengar acara DOM, melakukan operasi async, mengirimkan tindakan lain, mutasi komit, dll. Fungsi callback tindakan disediakan objek data yang relevan dan fungsi kenyamanan sebagai parameter pertama:
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
*/
} ) ;Untuk mendukung operasi async dengan lebih baik, tentukan parameter kedua untuk menyelesaikan panggilan (dan secara opsional parameter ketiga untuk menolak panggilan) sebagai bagian dari tanda tangan fungsi callback tindakan. Mengirim tindakan async akan secara otomatis mengembalikan janji. Berikut adalah contoh bagaimana Anda dapat menerapkan tindakan async untuk mengambil data dari server:
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) Rute bekerja persis seperti tindakan, kecuali mereka juga menanggapi perubahan dalam jalur URL, seperti acara klik yang dipicu pengguna dan pengiriman formulir, panggilan terprogram ke metode navigate dan redirect , dan bergerak maju dan mundur dalam tumpukan riwayat sesi. Rute harus didefinisikan dengan slash maju terkemuka:
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
*/
} ) ;Parameter Dukungan Rute, Parameter Opsional, dan Wildcards:
// 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?)Kirim tindakan dengan parameter opsional atau rute. Jika tidak ada argumen yang disediakan, jalur URL saat ini digunakan secara default. Mengembalikan nilai pengembalian fungsi callback tindakan/rute atau janji jika itu adalah tindakan/rute 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)Tentukan tampilan yang akan segera diterjemahkan dan diperbarui secara otomatis melalui DOM virtual ketika keadaan berubah. Fungsi Callback View disediakan pembangun DOM virtual melalui templat yang ditandai, keadaan saat ini, dan fungsi pengiriman yang nyaman untuk tindakan pengiriman dan rute sebagai hasil dari pendengar acara DOM dengan parameter opsional sebagai objek kunci/nilai:
app . view ( parentElement , ( html , state , dispatch ) => html `
< div >
< p > Name: ${ state . name } </ p >
< button onclick = ${ dispatch ( 'handleClick' , { foo : 1 , bar : 2 } ) } > Increment </ button >
</ div >
` ) ;Tampilan Atribut/Properti Dukungan, Gaya CSS sebagai string atau objek, pendengar acara yang ditunjukkan oleh awalan "ON", node terkunci untuk daftar yang efisien, dan komponen fungsional tanpa kewarganegaraan:
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)Dorong entri baru ke tumpukan sejarah dengan jalur URL yang disediakan dan mengirimkan rute pencocokan pertama. Mengembalikan nilai pengembalian fungsi callback rute atau janji jika itu adalah rute async:
app . route ( '/foo' , ( ) => 'bar' ) ;
app . path ( ) ; //=> "/"
history . length ; //=> 0
app . navigate ( '/foo' ) ; //=> "bar"
app . path ( ) ; //=> "/foo"
history . length ; //=> 1redirect(path)Mengganti entri riwayat saat ini dengan jalur URL yang disediakan dan mengirimkan rute pencocokan pertama. Mengembalikan nilai pengembalian fungsi callback rute atau janji jika itu adalah rute async:
app . route ( '/foo' , ( ) => 'bar' ) ;
app . path ( ) ; //=> "/"
history . length ; //=> 0
app . redirect ( '/foo' ) ; //=> "bar"
app . path ( ) ; //=> "/foo"
history . length ; //=> 0on(name, callback)Berlangganan acara aplikasi, mengembalikan fungsi untuk menghapus pendengar spesifik itu:
// 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?)Memicu acara khusus dengan argumen opsional:
app . on ( 'foo' , ( a , b , c , d ) => {
// Do something
} ) ;
app . emit ( 'foo' , 1 , 2 , 3 , 4 ) ;state()Dapatkan objek keadaan saat ini:
const app = avalon ( {
title : 'Hello World'
foo : 1 ,
bar : 2
} ) ;
app . state ( ) ; //=> {title: "Hello World", foo: 1, bar: 2}path()Dapatkan jalur URL saat ini:
app . navigate ( '/foo' ) ;
app . path ( ) ; //=> "/foo"use(plugin)Tambahkan plugin dengan menyediakan fungsi panggilan balik yang segera dipanggil dengan instance aplikasi dan status saat ini. Mengembalikan nilai pengembalian fungsi panggilan balik 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' ) ;
} ) ; Proyek ini didedikasikan untuk domain publik seperti yang dijelaskan oleh Unlicense.