1.1.1 • Published 9 months ago

raab-js v1.1.1

Weekly downloads
-
License
MIT
Repository
-
Last release
9 months ago

Raab-js

简单的前端响应式框架实现(我更愿意称之为伪响应式,因为操作响应数据需要使用特定暴露出的api进行,而不是传统意义上直接操作数据,不过这样做的好处是可以更加精准且减少了代理数据的额外开销)

另外RaabJS内置了路由管理,可以方便的开发单页面应用

安装

npm install raab-js

快速实践

// main.ts
import { App, creatApp, RouteNextFunctionType, RouteType } from 'raab-js'
import MainPage from './mainPage'

class app extends App {
  handleRoute(): RouteType[] {
    return [
      { path: '/', page: new MainPage },
    ]
  }
  RouteMiddle(to: string, from: string, next: RouteNextFunctionType): void {
    next()
  }
}

creatApp(app)

// mainPage.ts
import { BasePage, c, cVal } from 'raab-js'

class MainPage extends BasePage {
  context = rVal<string>('Hello, World!')
  setup() {
    return (
      c('h1', {$text: this.context.bindPath(), style: 'color: red;'})
    )
  }
  enter() {
    return true
  }
  leave() {
    return true
  }
}

export default MainPage

文档

在RaabJS里,所有html元素需要被封装成组件和页面,页面可以包含许多组件,且每一个页面需要有一个路由与其对应。

响应式

RaabJS响应式支持单一数据与数组数据,且数组数据依赖于单一数据

  • rVal() 单一数据

    rVal函数,需要传入相应数据,并支持泛型,与vue的ref相似的是,rVal读取与赋值时需要访问.value属性,另外rVal绑定元素需要调用bindPath方法,如:

    const text = rVal<boolean>(true)
    // 读取
    text.value
    // 赋值
    text.value = false
    // 绑定元素
    c('div', {$text: text.bindPath()})
  • rList() 数组数据

    rList函数,需要传入相应数组,支持泛型,且数组中的响应数据需要包裹rVal函数,另外绑定元素时需要调用bindPath方法并传入数据路径,如:

    const list = rList([
        {text1: rVal('这是第一个数据')},
        {text2: rVal('这是第二个数据')},
        {text3: rVal('这是第三个数据')},
    ])
    
    // 对应 这是第一个数据
    c('div', {$text: list.bindPath('0/text1')})
    // 对应 这是第二个数据
    c('div', {$text: list.bindPath('1/text2')})
    // 对应 这是第三个数据
    c('div', {$text: list.bindPath('2/text3')}		
    • rList具体操作数组方法如下:

      • forEach(fn: rListForEachFunctionType<T>): void

        循环数组

      • append(list: T[]): void

        追加数组,且需要注意的是必须传入数组而不是单一数据

      • insert(index: number, val: T): void

        插入数组,index指定下标,val数据

      • delete(index: number): void

        删除数据,index指定下标

      • setVal(path: string, val: T): void

        设置数据,path为数据路径,val数据

      • getVal(path: string): any

        获取指定路径数据

模板

用于构建html元素,RaabJS中为c,cFor方法,其中c方法接收三个参数为元素名称,元素属性,以及子元素,如:

c('div', {}, [
    c('h1', {$text: 'test'}),
])

其中带$的参数为特殊属性,在函数执行时会进行特殊处理,一般用作事件绑定

  • $text:元素文本
  • $click:绑定点击事件

.........

cFor方法用于循环创建多个元素,其接收两个参数为响应式数组(类型为rListObject,且需要响应的数据必须包裹rVal方法),回调函数,函数会传入index为数组下标已方便绑定数据,如:

const list = rList([
    {c: rVal('123')},
    {c: rVal('456')},
    {c: rVal('789')},
    {c: rVal('012')},
])

c('div', {}, cFor(list, index => {
    return (
        c('div', {}, [
            c('div', {$text: list.bindPath(`${index}/c`)}),
            c('button', {$text: 'delete', $click: (e, i)=>list.delete(i)})
        ])
    )
}))

需要注意的是,回调函数的结果需要进行返回,另外在cFor内部绑定事件函数会被传入两个参数反别是Event与index,其中index为绑定的对应数组下标...

Init

首先,启动一个Raab app需要创建类并继承App基类,实现handleRoute方法与RouteMiddle方法,其中handleRoute需要返回RouteType[]类型结构,具体信息如下

type RouteType = {
    path: string	// 路由路径(支持动态路由,需要在路由参数名前加:,如:id,匹配到后会在页面的enter方法传入相关数据)
    page: BasePage	// 页面类实例
    children?: RouteType[]	// 子路由信息
}

RouteMiddle路由中间件控制路由转跳,传入三个参数to路由去向,from路由来自,next中间方法,next方法必须放置在函数内,否则无法执行路由转跳,且next支持重定向,需要传入指定路由如:

next('/test')

另外关于子路由显示的问题,需要在父路由页面引入Route类并新建实例充当容器以此来展示子路由,如:

import { BasePage, c, Route, router } from 'raab-js'

// router为路由方法,其中changeRoute改变路由不添加history历史,toRoute为前往目标路由并添加历史

class MainPage extends BasePage {
  setup() {
    return (
      c('div', {}, [
        c('div', {style: 'border: red solid 1px'}, [
          // 展示子路由信息
          new Route,
        ]),
        c('button', {$text: 'AAA', $click: ()=>router.changeRoute('/aaa')}),
        c('button', {$text: 'BBB', $click: ()=>router.changeRoute('/bbb')}),
      ])
    )
  }
  enter() {
    return true
  }
  leave() {
    return true
  }
}

export default MainPage

页面

书写页面需要创建类并继承BasePage基类,并实现setup(),enter(),leave()方法,其中setup返回html模板,需要使用c或cFor方法,enter与leave为页面钩子函数,是抽象方法所有必须实现,一般enter会传入页面进入后的相关参数,且需要返回布尔类型或者字符串,true为允许进入或离开此页面,反之亦然,也可以进行重定向如:

enter(p: any) {
    return '/test'
}

组件

书写组件需要创建类并继承BaseComponent基类,并实现setup(),Created(),Destroy()方法,其中Created(),Destroy()为组件生命周期钩子函数,Created为组件被挂载到页面后,Destroy为组件将卸载时(由于目前元素被创建在页面后只实现了隐藏显示并不会真正卸载出dom树,所有Destroy方法暂时无效)

import { BaseComponent, c } from 'raab-js'

class Com extends BaseComponent {
  setup() {
    return (
      c('h1', {$text: 'Hello, Rab!!!', style: 'color: red;'})
    )
  }
  constructor() {
    super()
  }
  Created() {
    
  }
  Destroy() {
    
  }
}

export default Com
1.1.1

9 months ago

1.1.0

10 months ago

1.0.0

10 months ago