使用 Web3 和 Vue.js 來建立你的第一個以太坊 dAPP(二)

發表於2018-05-09

 

歡迎回到這個很牛的教程系列的第2部分,在教程中我們親手構建我們的第一個分散式應用程式。 在第二部分中,我們將介紹VueJS和Vuex的核心概念,並引入web3js以與metamask進行互動。

如果你錯過了第一部分,你可以在下面找到它:

正事: VueJS

VueJS是一個用於構建UI的javascript框架。乍一看,它看起來與經典的moustache模板類似,但在底層為了使Vue變得響應式發生了很多事情。

這將是一個非常基礎的Vue應用程式的結構。資料物件中的訊息屬性將渲染到id為’app’的元素的螢幕區域,當我們更改此訊息時,它將在螢幕上更新並無需重新整理。你可以在這個jsfiddle中檢視它(須開啟自動執行):https://jsfiddle.net/tn1mfxwr/2/ 。

VueJS的另一個重要特性是元件。元件是小規模的、可重用的和自包含的程式碼片斷。本質上,Web應用程式可以抽象為一顆更小的元件樹。當我們開始編寫我們的前端應用程式時,這將會變得更加清晰。649

將網頁抽象成元件的示例。該網頁由三部分組成。其中兩個元件具有子元件。

狀態的聯合:Vuex

我們將使用Vuex來管理我們的應用程式的狀態。與redux類似,Vuex實現了一個倉庫,作為我們app相關資料的“唯一真實資料來源”。Vuex允許我們以可預測的方式操作和提供我們的應用程式所使用的資料。

它的工作方式非常簡單。元件在渲染時是需要資料的,它會派發一個動作(action)來獲取它所需要的資料。獲取資料的API呼叫發生在action的async中。 一旦資料被提取完成,action就會將這些資料提交給mutation。 之後mutation會改變我們倉庫中的狀態。當該元件所使用的資料在倉庫中發生更改時,它將重新渲染。648
Vuex的狀態管理模式

 

在繼續之前…

在第一部分中,我們使用 vue-cli 生成了 Vue 應用程式,同時還安裝了需要的依賴項。 如果你還沒有完成這一部分,請點選的頂部的連結。

如果你正確地完成了一切,目錄結構應該如下所示:647

新生成的 vue 應用

注意: 如果你打算從這裡複製貼上程式碼,新增/src/ 到 .eslintignore 檔案中,避免縮排錯誤。

你可以在終端輸入‘npm start’來啟動這個App。這個App會包含預設的vue應用,因此我們可以將它放出來。
注意:我們正在使用vue Router儘管只有一個route,我們不需要它,但是因為它太簡單了,我認為將它放到教程裡挺好的。
提示:在.vue檔案將你的atom語法(例如 bottom right)新增到HTML。
現在來清理一下這個新專案:

  • 在app.vue中刪除img-tag,同時刪除在style-tags之間的所有東西。
  • 刪除components/HelloWorld.vue,新建兩個檔案分別名為casino-dapp.vue(我們的主模組)和hello-metamask.vue(會包括我們的metamask資料)
  • 在我們的新檔案hello-metamask.vue中貼上以下程式碼,這些程式碼現在只是在一個p-tag中顯示文字‘Hello’。

 

  • 通過引入檔案,我們現在要載入hello-metamask模組到我們的主模組casino-dapp模組中,然後在我們的vue例項中關聯這個模組,因此我們可以將它作為一個tag加到我們的模板中。將下面程式碼貼上到casino-dapp.vue檔案中:
  • 現在如果你開啟了router/index.js,你就會看到我們根目錄下只有一個route,它仍然指向我們已經刪掉的HelloWorld.vue模組。我們需要將它改為指向我們的casino-dapp.vue模組。

關於Vue Router:你可以新增其他的路徑以及繫結模組,當你訪問定義的路徑他們會進行渲染。因為我們App.vue檔案中有route-view tag,正確的模組會被渲染。

  • 在src中建立一個名為util的新資料夾。在這個資料夾中建立另一個資料夾名為constants。建立一個名為network.js的新檔案,然後將下面程式碼貼上進去。當我們程式碼在清理的時候,這會讓我們顯示Ethereum 網路名稱而不是它的id。

646

  • 最後但同樣重要的是(現在其實並不重要),在src中建立一個名為store的新資料夾。在下一章我們再來談論這個。

如果你在終端執行‘npm start’,然後在瀏覽器訪問localhost:8080,你應該就能在螢幕上看到‘Hello’。如果是這樣的,你就可以準備繼續了。

 

設定我們的Vuex store

在這一章我們要設定我們的store。現在開始在我們的全新的store目錄(上一章的最後一部分)建立兩個檔案:index.js和state.js;我們由state.js開始,這個檔案將會作為一個新的我們檢索資料的代表。645

好的,現在我們開始在index.js中配置我們的store。我們要引入vuex庫供vueJS使用。我們還要引入state,然後也加入我們的store中。

最後一步來編輯main.js來包含我們的store:

做得不錯,完成了這麼多的配置,給自己一點表揚。現在我們準備好了開始通過web3 API獲取我們的metamask資料,然後讓他為我們的應用服務。就要實現了!

從 Web3 和 Metamask 開始

就像之前提到的,為了將資料獲取到我們的Vue app,我們需要傳送一個action來做非同步API呼叫。我們使用promises將一些呼叫連線到一起,然後將其抽象成一個檔案。因此在util資料夾中建立一個名為getWeb.js的新檔案。將下面的程式碼貼上到裡面,這些程式碼包含了你要遵循的相當多的註解。我們在程式碼塊下面也會提到。

首先要注意的是我們使用promises來連線回撥,如果你不知道promises,檢視相關連結。下一步我們檢查使用者是否有Metamask(或者 Mist)在執行。Metamase注入他自己的web3的例項,我們因此確認window.web3(被注入的例項)已經定義了。

如果沒有定義的話,我們要使用Metamask建立一個web3例項作為當前provider,因此我們不依賴被注入的例項的版本。我們將我們新建立的例項傳給下一個promises,在這裡我們做幾個API呼叫:

  • web3.version.getNetwork() 會返回我們連線的網路ID。
  • web3.eth.coinbase() 返回我們節點屬於的地址,當使用Metamask的時候這會是我們選擇的賬戶。
  • web3.eth.getBalance(
    ) 返回我們作為引數傳過去的地址的balance。

還記得我們說的在我們的Vuex store中需要在一個action產生非同步API呼叫嗎?我們現在會把它hook出來,之後從我們的元件dispatch出去。在store/index.js中我們會引入我們的getWeb3.js檔案,呼叫它然後將它commit給一個mutation,然後在我們的store中儲存。
在你的引用語句中新增644

然後在action物件(在你的sotre中)中我們會呼叫getWeb3然後commit結果。我們在邏輯中新增了大量的console.logs,因此我們可以看到程式的步驟,這會讓我們對完全的dispatch-action-commit-mutation-statechange流程瞭解的更加透徹。643

現在開始建立我們的mutation,它會在我們的store中將資料儲存到state。通過訪問第二個引數,我們可以在mutation中訪問傳進commit的資料。在mutations物件新增下面的函式。642

不錯!現在還要做的就剩下從我們的元件將action dispatch給實際檢索資料,然後把它渲染到我們的應用。為了dispatch我們的actions,我們要利用Vue的生命週期hooks。

在我們的例子中,我們需要從main casino-dapp元件dispatch 我們的action,在元件被建立之前。因此在components/casino-dapp.vue 的name屬性之後新增下面的函式:641

好了,現在我們要從hello-metamask元件渲染這些資料,我們所有的賬戶資料都會在這個元件中被渲染。為了從我們的store獲取資料,我們需要將一個getter函式傳入computed。然後我們可以在我們的模板中使用curly-braces關聯資料。

不錯,現在都可以工作了。在你的終端使用‘npm start’啟動專案,然後訪問localhost:8080。我們現在應該可以看到我們的metamask資料。當我們開啟控制檯的時候,我們應該看到在state管理模式下控制檯log輸出的資訊,就像是在文章的vuex部分描述的一樣。640

如果你能做到這一點,一切都很好,那麼就認真的做下去。目前這塊是這個系列最難的部分。在下一部分,我們將學習如何輪詢Metamask的更改(如更換賬戶)和將我們在第一部分寫的智慧合約連線到我們的應用。

相關文章