學不動系列:新前端框架 Nautil,哇~

基於 react 的除了 Next.js 其餘的所謂框架我都只想說,雞你太美!React 實在太香了,可是實戰開發起來卻又不怎麼好弄。讓咱們來看最新的 roadmap:javascript


來自:react-developer-roadmap前端

我就想寫個網頁,何須這麼殘忍?面對這個畫面,我都有貼大哥表情包的衝動。可是我忍住,畢竟我仍是想寫代碼來豐富個人人生的。java

在 react 的生態中,咱們不難發現很是優秀的項目。例如,跨組件的通訊怎麼辦?來 redux 吧!redux 組織好複雜?上 redux-saga 吧!異步咋解決呢?來 redux-thunk 真香!使用特定 state 也挺麻煩?搞 reselect 如何!哎呀呀,仍是來 rematch 或來套國產的 dva 也行……react


沒忍住……jquery

你讓我寫個應用,我除了要花精力去解決打包編譯工具的問題以外,還要來糾結到底要用哪一個方案。真的很煩唉!其實,就像當年用 jquery 用爽了,扛起 backbone 或更狠上 angular 就開幹。我寫了這麼多年 react,想要的是一套框架,拿過來就開擼的那種。git


從 roadmap 中,咱們看這個區域,也就是 react 生態的狀態管理和表單數據管理這個部分。是否是複雜!很複雜!那是由於 MobX 尚未擴展開來聊。害得我又想貼表包……github

咱們能不能簡化 react 應用中的狀態管理?能不能把數據請求這塊處理的更加優雅?能不能提供更靠譜的 form 模型?有的。ajax

Nautil 框架來了!!!

一款基於 react 的 js 前端框架。在我看來,一個前端框架須要具有應用開發中必不可少的部件。並且要好用,方便開發者理解和寫代碼。Nautil 一次性提供體驗超爽,並且還有趣的:redux

  • UI 渲染
  • 路由
  • 狀態管理
  • 數據倉庫
  • 數據類型檢查
  • 跨端開發解決方案
  • 多語言國際化

讓咱們來舉個例子,就拿複雜的 state 管理來開刀吧。想一想你在以往經驗裏面使用 redux 是怎麼用的,有沒有在準備方案階段就很糾結和心累?若是你用 Nautil,不須要糾結,由於你沒得選,只有一種全局的狀態管理方案。api

import { Component, Store, ObservableProvider } from 'nautil'
import { Section, Text } from 'nautil/components'

// create a store
const store = new Store({
   name: 'tomy',
   age: 10,
})

class App extends Component {
  render() {
    return (
      <ObservableProvider
        name="$store" value={store}
        subscribe={dispatch => store.watch('*', dispatch)} dispatch={this.update}
      >
        <Page1></Page1>
      </ObservableProvider>
    )
  }
}

class Page1 extends Component {
  static injectProviders = {
    $store: true,
  }
  render() {
    const { state } = this.$store
    return <Section>
      <Text>Hi, I am {state.name}, and I am {state.age} years old.</Text>
    </Section>
  }
}複製代碼

啥?你沒看到怎麼管理狀態的?不怪你,由於它實在實在是太方便了,由於在 Nautil 裏面,你能夠沒有全局的狀態管理,可是你必定會有某個數據是全局的(準確的說是跨組件),你只須要用 ObservableProvider 這個組件去提供就能夠了。而後在很深的組件裏面去使用 injectProviders 來注入這個被提供的數據。恰巧的是,Nautil 提供的 Store 是一個可被觀察的數據容器,使用 store.watch 來監聽它的數據的變化,並在變化的時候觸發更新操做。

還沒明白?


這裏的 store 就是你的狀態管理器了啊!!!store 裏面存着整個應用被共享的 state,你能夠在任何地方去,任何地方改,任何地方刪,都會經過 store.watch 的部分觸發應用更新。也許你沒聽明白個人意思。個人意思是,你甚至能夠在 react 應用以外去修改數據都是能夠的,只要你在任何地方執行一下:

store.state.age ++複製代碼

你的界面就會發生變化。是的,即便把你的 nautil 應用和 angular 應用混在一塊兒,共享一個 store,也是能夠的。同時,你還能夠經過 watch 來收集每一次數據的變化,在必要時,把收集起來的數據經過 store.update 來複原數據。

它是否是徹底超出了你對 react 狀態管理的理解?不要緊,還有一個東西會超出你的理解,那就是從後臺 api 拉取數據。

你有沒有想過,爲何那麼優秀的 redux 會變得那麼臃腫?由於數據是前端應用的命啊,一個不須要從後臺 api 取數據的前端應用,除非是工具或遊戲,不然就是沒有靈魂的應用啊!因此,redux 出來以後,包括 react 自己,都必須面臨異步數據請求的問題。以 react 自己而言,它一開始徹底沒有機制去處理,一個數據必然存在兩種狀態:數據尚未從後臺拉回來的狀態,已經拉回來的狀態。在數據沒有拉回來的時候,把界面顯示出來,等數據回來了,再閃一下,哦豁,用戶均可以化身產品經理給開發提 bug 了。

Nautil 怎麼解決?

import { Component, ObservableProvider, Depository, Prepare } from 'nautil'
import { Text } from 'nautil/components'

// set data sources information
const datasources = [
  {
    id: 'articles',
    url: '/api/articles',
  },
  {
    id: 'tag',
    url: '/api/tags/{tag}',
  },
]

// create a data depository
const depo = new Depository({
   expire: 10000,
})

// register data sources into depository
depo.register(datasources)

class App extends Component {
  render() {
    return (
      <ObservableProvider
        name="$depo" value={depo}
        subscribe={dispatch => depo.subscribe('articles', dispatch).subscribe('tag', dispatch)}
        dispatch={this.update}
      >
        <Page1></Page1>
      </ObservableProvider>
    )
  }
}

class Page1 extends Component {
  static injectProviders = {
    $depo: true,
  }

  render() {
    const depo = this.$depo
    const some = depo.get('tag', { tag: 'some name' })

    return (
      <Prepare isReady={some} loadingComponent={<Text>loading...</Text>}>
        <Text>{some.name}</Text>
      </Prepare>
    )
  }
}複製代碼

建立一個數據倉庫來管理從後臺 api 接口拉取的數據。在業務代碼和後臺 api 之間,不要直接打交道,而是經過數據倉庫整合。業務代碼,只須要從倉庫中 get 數據便可,這個 get 是同步操做,不須要等待。同時,倉庫是可觀察的,經過一個 subscribe 方法對倉庫進行觀察,若是發現對應的數據發生變化,那麼當即更新界面。對於倉庫中尚未對應的數據時,使用 Prepare 組件來提供一個 loading 效果。

聽上去好像還挺順的對不對?可是,等等!!!我何時發 ajax 去請求數據?


你真的不須要關心 ajax 的問題,真的!你只要 get, get, get~ 我能理解你理解不了,只是如今。只要你用用,什麼 thunk, saga, action, dispatch 通通一邊去耍吧。不須要異步的好嗎。

話說回來,即便有異步操做,咱們還有 store,隨時隨地,時時刻刻,想改就改,毫無限制。

若是你再去了解一下 Nautil 的路由,你會發現一個規律:

Nautil 就是 react,nautil 不僅是 react。

說的這麼玄乎,意思是,它徹底兼容 react 應用。好比你在其餘地方寫了一些純 UI 的 react 組件,不要緊,拿過來直接用。或者你想在其餘的 react 應用中使用 nautil 編寫的組件,不要緊,直接拿去用。

你會發現,nautil 中強調「可觀察的」這樣一個概念。簡單說就是有一個辦法知道發生了變化。nautil 內置的 Observer 組件用於監聽這些變化,而且在變化發生時執行傳入的邏輯(通常是更新界面)。因此,在 nautil 中,數據、狀態、路由都是「可觀察的」對象,被注入到應用中。但本質上,它們是徹底獨立的,意思是,你能夠在 react 應用以外的任何場景使用這些「可觀察的」對象,也能夠將整個體系以外的「可觀察的」對象拿到 nautil 中直接使用。這也能夠說是「漸進式」,可用可不用,固然,做爲框架,你必須這樣用才符合我寫 nautil 的初衷。

不開源的都是耍流氓。

很遺憾,Nautil 到如今尚未發佈。但你能夠經過 github 關注或貢獻代碼。你也能夠從 github 克隆下來跑跑看,也許會喜歡上呢~

+--------------------------+

|                github                    |

+--------------------------+

最後補充一句。Nautil 還提供了內置的 Model,擁有結構化、數據校驗、格式化、類型檢查、可觀察等特性,在表單開發時多是你正在尋找的最好的解決方案,之一。

相關文章
相關標籤/搜索