15 分鐘帶你入門 Fuse
Fuse 這個技術令人興奮,不僅可以用來做交互原型,還可以導出成 iOS 和 Android 的原生 App 供生產使用,重點的重點在于輸出的成品品質不錯,所以私以為值得學習一下 (官方也表示以后會支持導出 Mac,Linux,Windows App)。
我們來通過一張圖了解一下 Fuse 做了什么。
所以 Fuse 是一種和 Qt 類似的技術,通過一個中間層封裝系統的 API 來實現 “一次編寫,到處調試” 的偉大理想。
但是沒有了 Qt 的歷史包袱 Fuse 要顯得更加輕量(就像 Photoshop 之于 Sketch )并且使用 JavaScript 這種 “人人都會” 的語言,從而極大的降低了學習成本,而且 Fuse 在 UI 層是實實在在用的系統級的,不像 Qt 是模擬的 UI,所以最終的成品效果都要好不少。
但是此類技術不敢用于復雜的 App,考慮再三之后,突然想起我之前給Producter 設計過一個 UI,不如就從此處開始,于是花了 2.5 天的時間完成了這個 App,下面是最重的成品截圖,過一段時間再整理完善后會開源出來。
創建 App
從 Fuse 下載安裝后,非常簡單就可以創建你的第一個 App —— 點擊 New!
如果你的編輯器是 Atom 的話,請務必安裝官方的插件。
創建之后目錄極為簡單,只有兩個文件
MainView.ux 就是 App 界面開始的地方。你可以通過在編輯器里右鍵點擊 Preview Local 來運行 App 更酷的是,Fuse 支持實時修改,所以你不需要反復的編輯,編譯你的 App。
編譯完成后你就得到了你第一個 Fuse App! 當當當~
構建界面
Fuse 的界面和 Qt 的 QML 很類似,每一個元素都實際對應一個 Uno 類,所以你可以隨時查閱 Fuse Class Reference 來看看元素都有哪些屬性。
通過下面這段代碼,就可以給界面添加一段文字
<App Theme="Basic"> <Text Value="Hi"/> </App>
Fuse 有個很高端的界面布局系統,你可以通過 Layout 章節進行深入了解,我就不再贅述,先跳過具體的細節。
綁定數據
我們現在給 Fuse 增加一個 JavaScript 控制腳本,首先在項目根目錄創建一個 js 文件,就叫做 main.js 吧,然后給 MainView.ux 增加一段標記。
<App Theme="Basic"> <JavaScript File="main.js" /> <Text Value="Hi"/> </App>
假設我們希望綁定 Text 的 Value 到一個變量 name,先修改 Text 的標記
<App Theme="Basic"> <JavaScript File="main.js" /> <Text Value="{name}"/> </App>
接著在 main.js 里編寫如下內容
var Observable = require('FuseJS/Observable'); var name = Observable("Kevin"); module.exports = { name: name };
保存之后你就會看到界面上的文字變成了 Kevin,那么綁定如何體現呢? 我們來加一段 Timeout
var Observable = require('FuseJS/Observable'); var name = Observable("Kevin"); setTimeout(function(){ name.value = "Fuse"; },1000); module.exports = { name: name };
這時候你保存下,就會看到 1 秒過后文字變成了 Fuse!
列表
根據數據生成力量內容在 Fuse 更是深得這幾年前端的精髓,你只需要把數據綁定好并寫好模版就可以了。
例如我生成十個單身的男子
var people = Observable(); for (var i = 0; i < 10; i++) { people.add({name:"Man" + i, age: (2*i)+1}) }
那么要顯示這個列表,我們就需要這樣來修改 MainView.ux
<App Theme="Basic"> <JavaScript File="main.js" /> <ScrollView> <StackPanel> <Each Items="{people}"> <Text Value="{name}"/> <Text Value="{age}"/> </Each> </StackPanel> </ScrollView> </App>
ScrollView 提供滾動支持,StackPanel 可以按行排列內容。
于是,我們的效果就實現了!
定義界面 UI
不過這樣太難看了點,我們可以美化一下
<App Theme="Basic"> <JavaScript File="main.js" /> <ScrollView Padding="30"> <StackPanel ItemSpacing="20"> <Each Items="{people}"> <Rectangle> <Stroke Width="2" Brush="#000" /> <StackPanel ItemSpacing="5" Margin="10"> <Text Value="{name}" FontSize="20" TextColor="#000" Margin="0"/> <Text Value="{age}" TextColor="#aaa"/> </StackPanel> </Rectangle> </Each> </StackPanel> </ScrollView> </App>
這是我近期很喜歡的設計風格 :)
加入動畫
我希望在按住某個 Cell 的時候可以縮放一下
可以加入 WhilePressed 代碼,將其嵌套到你希望觸發的控件標簽里面即可。
<App Theme="Basic"> <JavaScript File="main.js" /> <ScrollView Padding="30"> <StackPanel ItemSpacing="20"> <Each Items="{people}"> <Rectangle> <Stroke Width="2" Brush="#000" /> <StackPanel ItemSpacing="5" Margin="10"> <Text Value="{name}" FontSize="20" TextColor="#000" Margin="0"/> <Text Value="{age}" TextColor="#aaa"/> </StackPanel> <WhilePressed> <Scale Factor="0.98" Duration="0.1"/> </WhilePressed> </Rectangle> </Each> </StackPanel> </ScrollView> </App>
從網絡獲取數據
利用 fetch 方法我們可以直接獲取網絡數據
fetch("https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://www.digg.com/rss/index.xml") .then(function(response) { status = response.status; //Network status return response.json(); }) .then(function(responseObject) { //JSON }).catch(function(err) { // An error occured parsing Json console.log("Fetch Error" + err); });
頁面導航
如果你寫過 iOS 或者其他 App,那么可能對這個需求會很 “旺盛”,在 Fuse 中通過 HierarchicalNavigation 可以定義簡單的導航,下面是一個簡單的導航結構。
<App Theme="Basic"> <Panel> <HierarchicalNavigation ux:Name="nav" ReuseExistingNode="false" Active="mainPage" /> <Style> <Page> <EnteringAnimation> <Move X="1" RelativeTo="ParentSize" /> </EnteringAnimation> <ExitingAnimation> <Move X="-1" RelativeTo="ParentSize" /> </ExitingAnimation> </Page> </Style> <Page ux:Name="mainPage"> <StackPanel> <Button Text="Page 1"> <Clicked> <NavigateTo Target="subPage1" /> </Clicked> </Button> <Button Text="Page 2"> <Clicked> <NavigateTo Target="subPage2" /> </Clicked> </Button> <WhileCanGoForward> <Button Text="Go Forward"> <Clicked> <GoForward /> </Clicked> </Button> </WhileCanGoForward> </StackPanel> </Page> <Page ux:Name="subPage1"> <StackPanel> <Text>Welcome to page 1!</Text> <Button Text="Go Back"> <Clicked> <GoBack /> </Clicked> </Button> </StackPanel> </Page> <Page ux:Name="subPage2"> <StackPanel> <Text>Welcome to page 2!</Text> <Button Text="Go Back"> <Clicked> <GoBack /> </Clicked> </Button> </StackPanel> </Page> </Panel> </App>
順便你也可以發現如何使用事件,例如 Clicked 事件直接加到希望監聽的控件下面即可
<Clicked> <NavigateTo Target="subPage2" /> </Clicked>
NavigateTo 需要配合 HierarchicalNavigation 一起用,ux:Name 可以給某個控件命名,有了名字就可以互相 “提及” 了。
真機運行
在根目錄執行 target 也可以換成 Android
uno build --target=iOS --run
15 分鐘完畢,感謝觀看,如果你希望深入了解 Fuse,那么就可以通過學習資源的兩個鏈接來搞定!更多問題,則可以去社區提問或者加入他們的官方 Slack 群。
也歡迎通過各種方式與我交流!