<address id="ttjl9"></address>

      <noframes id="ttjl9"><address id="ttjl9"><nobr id="ttjl9"></nobr></address>
      <form id="ttjl9"></form>
        <em id="ttjl9"><span id="ttjl9"></span></em>
        <address id="ttjl9"></address>

          <noframes id="ttjl9"><form id="ttjl9"></form>

          首頁

          v-for的鍵值key

          前端達人

          我們現在在使用v-for的時候、都必須會加上一個必要的key值,并且很多人會使用index來作為key,其實這樣是不太妥當的一種做法。那么v-for中的鍵值key到底有什么作用呢。請看:

          官方給出的解答

          當 Vue 正在更新使用 v-for 渲染的元素列表時,它默認使用“就地更新”的策略。如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序,而是就地更新每個元素,并且確保它們在每個索引位置正確渲染。這個類似 Vue 1.x 的 track-by="$index"。

          這個默認的模式是高效的,但是只適用于不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出。

          為了給 Vue 一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要為每項提供一個唯一 key attribute:

          
          
          1. <div v-for="item in items" v-bind:key="item.id">
          2. <!-- 內容 -->
          3. </div>

          建議盡可能在使用 v-for 時提供 key attribute,除非遍歷輸出的 DOM 內容非常簡單,或者是刻意依賴默認行為以獲取性能上的提升。

          舉例

          
          
          1. <div v-for="(item,index) in list" :key="index"> {{item.name}}</div>
          2. list: [
          3. {
          4. id: 1,
          5. name: "name1",
          6. },
          7. {
          8. id: 2,
          9. name: "name2",
          10. },
          11. {
          12. id: 3,
          13. name: "name3",
          14. }
          15. ]

          這個場景如何我們不佳key vue 回直接報錯,所以大部分人都會使用index作為key的值

          如果我們在添加一個數據

          
          
          1. list: [
          2. {
          3. id: 1,
          4. name: "name1",
          5. },
          6. {
          7. id: 2,
          8. name: "name2",
          9. },
          10. {
          11. id: 3,
          12. name: "name3",
          13. },
          14. {
          15. id: 4,
          16. name: "last",
          17. },
          18. ]

          此時前面3條數據直接服用之前的,新渲染最后一條數據,此時index作為key沒有任何問題

          如何我們在中間添加一條

          
          
          1. list: [
          2. {
          3. id: 1,
          4. name: "name1",
          5. },
          6. {
          7. id: 2,
          8. name: "name2",
          9. }, {
          10. id: 4,
          11. name: "last",
          12. },
          13. {
          14. id: 3,
          15. name: "name3",
          16. }
          17. ]

          此時我們更新渲染的數據 通過index 定義key 進行數據對比一下

          之前的數據:

          中間插入之后的數據 :

          由此可以發現除了第一條數據可以復用以為其余的3條數據都是需要重新渲染,因為key的值發生了變化。

          這個時候就可以體現出一個效率的問題,只插入一條數據,卻要從新渲染3條數據

          所以我們需要可以想辦法讓數組中不會變化的數據的key值也不變,所以不能通過index來設置key值,應該設置一個唯一的id來標識數據的唯一性;我們修改之后再來對比一下渲染的效率:

          之前的數據:

          <div v-for="(item,index) in list" :key="item.id"> {{item.name}}</div>

          中間插入之后的數據:

           對此對比發現,只有一條數據發生改變,因為其他數據的id 都沒有變、所以對應的key也沒有發生改變。我們只需要渲染這一條新的數據就可以。 所以一般推薦使用id作為key值配合v-for使用

          總結:

          Vue很大的一個特點就是雙向數據綁定,數據一旦改變,那么頁面就渲染新的數據呈現在頁面上。但是對于用v-for渲染的列表數據來說,數據量可能一般很龐大,而且我們經常還要對這個數據進行一些增刪改操作,而key的出現就是盡可能的回避這個問題,提高效率,如果我們給列表增加了一條數據,頁面只渲染了這數據。




          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          JS數組去重的幾種方法

          前端達人

          數組去重

          1 雙層for循環(類似冒泡排序的雙層循環寫法)

          var arr = [2,3,4,2,34,21,1,12,3,4,1] for(var i =0;i<arr.length;i++){ //第一層:每次循環拿到arr中一個元素 for(var j=i+1;j<arr.length;j++){ //第二層:每次拿到的元素再和每次拿到的元素后邊的元素依次進行比對(因為第一個要從第二個開始比,第二個要從第三個比以此類推,所以這里的j應比i大1為j=i+1) if(arr[i] === arr[j]){ //如果相同就刪除后邊的元素 arr.splice(j,1) } } } //arr:[1, 2, 3, 4, 12, 21, 34] 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12

          2 循環和indexof、循環和includes

          創建新數組,循環舊數組,看每次循環的元素是否存在于新數組中沒有就把當前元素添加到新數組中

          //indexof var arr = [2,3,4,2,34,21,1,12,3,4,1] var arr2 = [] arr.forEach((e)=>{ if(arr2.indexOf(e)==-1){ arr2.push(e) } }) console.log(arr2) //arr2:[1, 2, 3, 4, 12, 21, 34] 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          //includes var arr = [2,3,4,2,34,21,1,12,3,4,1] var arr2 = [] arr.forEach((e)=>{ if(!arr2.includes(e)){ arr2.push(e) } }) console.log(arr2) //arr2:[1, 2, 3, 4, 12, 21, 34] 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10

          3 利用對象屬性不能重復去重

          var arr = [2,3,4,2,34,21,1,12,3,4,1] var obj = {}; arr.forEach((e,i)=>{ obj[arr[i]] = "abc"; }); var arr2=Object.keys(obj) console.log(arr2) //arr2:["1", "2", "3", "4", "12", "21", "34"] var arr3 = arr2.map(e => ~~e ) //arr3:[1, 2, 3, 4, 12, 21, 34] //注意這種方法不僅給數組重新排列而且還改變了數組中元素的類型 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11

          ~是js里的按位取反操作符,~~就是執行兩次按位取反,其實就是保持原值,但是注意雖然是原值,但是對布爾型變量執行這個操作,會轉化成相應的數值型變量,也就是 ~~true === 1,~~false === 0。

          4 ES6 Set

          ES6 提供了新的數據結構 Set。它類似于數組,但是成員的值都是唯一的,沒有重復的值。

          var arr = [2,3,4,2,34,21,1,12,3,4,1] var arr1 = [...new Set(arr)] console.log(arr1) //arr1:[1, 2, 3, 4, 12, 21, 34] 
          
          • 1
          • 2
          • 3
          • 4

          5 ES6 Array. prototype.filter()

          注:indexOf在數組中找元素的時候,碰到符合條件的第一個就會把它的下標返回

          var arr = [2,3,4,2,34,21,1,12,3,4,1] var arr2 = arr.filter((e,i)=>{ //看每次循環的元素在數組中出現的第一個下標位置(indexOf返回的位置),和每次循環的元素的下標(filter循環每次的i)是否一致,一致就說明他就是第一個符合條件,不會被過濾掉。 return arr.indexOf(e)==i; }) console.log(arr2) //arr2:[1, 2, 3, 4, 12, 21, 34] 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7

          6 ES6 Array. prototype.reduce()

          var arr = [2,3,4,2,34,21,1,12,3,4,1] var arr2 = arr.reduce((pre,e)=>{ //這里當然也可以用indexOf來判斷是否存在 pre.includes(e)?pre:pre.push(e); return pre },[]) console.log(arr2) //arr2:[1, 2, 3, 4, 12, 21, 34]
          

          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          部署智能合約到conflux公鏈

          前端達人

          一、準備合約

          本節課程教大家如何講智能合約部署到conflux公鏈上,首先大家可以看到下面的這個智能合約是不是很簡單。我們將會以這個合約演示部署到conflux公鏈的過程。

          pragma solidity ^0.5.0;
          
          contract Counter {
              uint public count=0;
              event SelfEvent(address indexed sender, uint current);
          
              constructor() public {
              } function inc(uint num) public returns (uint){ return count += num;
              } function self() public {
                  emit SelfEvent(msg.sender, count);
              }
          } 復制代碼

          二、conflux的sdk安裝

          我們使用js-conflux-sdk作為本教程的web教程,交互首先我們需要進行安裝nodejs作為我們的運行環境。飛機票一張收下吧,我們安裝好nodejs后,就可以來玩我們的sdk了。廢話不多說,直接開始擼。

          我們使用WIN + R鍵打開命令行,然后創建一個文件夾(溫馨提示切換到非系統盤玩切換方式“D:”就切換到D盤了)使用“mkdir my-project && cd my-project” 創建好項目后自動進入文件夾,然后我們運行“npm init” 進行初始化node項目,這一步會讓你確認一些東西,如果你是小白一路回車(Enter鍵)就好。如果你是前端大神,我也沒啥好教的我也不太懂。為了穩定我們使用固定版本號方式安裝依賴,我們運行 “npm install js-conflux-sdk@0.9.2” 命令進行安裝js-conflux-sdk的0.9.2版本依賴(可以使用“npm uninstall package-name” 命令刪除對應依賴)。前置準備到這里基本已經完成。

          三、編寫調用合約js代碼

          下面請看我的目錄結構跟隨我一起來學習,下面的目錄結構請不要直接看到了就創建,因為你不知道都是什么意思,看玩我的解釋在回頭創建。

           

          image

           

          小伙伴應該已經發現了 node_modules、package-lock.json、package.json 這些文件是我們在進行安裝 sdk依賴時自動生成的。其他文件目前都沒有,我們來按順序生成他們。

          先創建sol這個文件夾,然后創建這三個文件。test.sol就是上面我們的合約代碼直接拷入文件中。abi.json和code.json兩個文件是通過這個工具 remix 在線生成的。我來說下生成過程。 首先我們將里面的文件全部刪除,然后點擊這里找到我們的項目目錄下的test.sol 文件

           

           

           

           

          我們應該看到下方我框出來的兩個按鈕了吧,那兩個按鈕就是abi.json和code.json文件的來源。abi.json我們可以直接復制過去,code.json文件我們要改點東西。

          首先我們看到的code文件應該是這樣的

          { "linkReferences": {}, "object": "608060405260...c63430005110032", "opcodes": "PUSH1 0x80 PUSH1 ... 1100 ORIGIN ", "sourceMap": "27:337:0 ... 37;;;;;;" } 復制代碼

          代碼有省略,太長不好看,我們看到object這個key值了吧,我們把它的值考出來然后在頭部加0x 就好了放在code.json文件中。code.js文件中只存放object的內容前面加0x,也就是下面的代碼,其他信息都不要,千萬記住了。這點很重要?。。。?

          "0x608060405260...c63430005110032" 復制代碼

          就是這樣的。然后我們在寫另外兩個call和deploy兩個文件

          先寫deploy文件

           // 私鑰地址
          const PRIVATE_KEY = '0x20f9169d40801955faada641cdb029f8e42c581c0c991a62753c736a0a168e5e';
          // 合約地址
          const CONTRACT = '';
          const { Conflux } = require('js-conflux-sdk');
          
          async function main() {
            const cfx = new Conflux({
              url: 'http://mainnet-jsonrpc.conflux-chain.org:12537',
              defaultGasPrice: 100,
              defaultGas: 1000000,
            });
            const account = cfx.Account(PRIVATE_KEY); // create account instance
            console.log(account.address); 
          
            // create contract instance
            const contract = cfx.Contract({
              abi: require('./sol/RC20.abi.json'),
              bytecode: require('./sol/RC20.code.json'),
            });
          
            const receipt = await contract.constructor()
              .sendTransaction({ from: account })
              .confirmed();
            console.log(receipt.contractCreated); 
          }
          main().catch(e => console.error(e)); 復制代碼

          打開項目cmd窗口在上面的目錄下 運行命令 “node deploy.js”就將合約部署上去了

          receipt.contractCreated 這個會打印出合約地址。






          作者:悠悠_15832013094

          鏈接:https://juejin.im/post/5ef563f75188252e99702335

          來源:掘金

          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          Conflux 開發教程 | 使用 IDE 在 Conflux 開發 DApp 的實戰操作指南

          前端達人

          Conflux DApp 開發教程

          對本教程有任何疑問或建議可以在 GitHub 給我們留言。

          簡介

          Conflux DApp 開發教程將使用 Conflux Studio 在 Oceanus 網絡下開發一個簡單的代幣應用 Coin。
          在這里插入圖片描述

          通過這個開發教程,你將會學習到如何進行 Conflux 智能合約的編寫、調用,配置智能合約的代付以及如何使用 Web 前端項目與智能合約進行交互,從而實現一個包含前端和智能合約的完整的 DApp。

          在閱讀教程中遇到任何問題,歡迎在 Issues 中向我們反饋。

          準備工作

          安裝 IDE

          請在 GitHub 下載頁面下載 Conflux Studio。目前 Conflux Studio 支持 macOS 和 Linux 系統,請根據系統下載對應的版本。

          正確安裝 Conflux Studio 并初次啟動后,Conflux Studio 將顯示歡迎頁面,根據提示完成 Docker, Conflux Node 以及 Conflux Truffle 的下載、安裝及啟動。
          在這里插入圖片描述

          創建錢包

          完成所有的安裝步驟后,首先需要創建鑰匙對來完成后續的合約部署以及調用。

          在 Conflux Studio 的任意界面,點擊應用左下?的鑰匙圖標,打開密鑰管理器。點擊 Create 按鈕打開新鑰匙對彈窗,輸入鑰匙對的名字并點擊 Save 按鈕。完成后將在密鑰管理器中看到剛剛生成的鑰匙對的地址。鑰匙對由私鑰和公鑰組成,公鑰在智能合約中也常被稱作地址。

          導出私鑰可以通過點擊每個地址后面的眼睛按鈕打開查看私鑰彈窗,彈窗顯示地址以及私鑰。后續教程中會需要通過管理器導出私鑰。
          在這里插入圖片描述

          為了順利完成教程,首先需要創建三個鑰匙對:

          • minter_key 用于 Coin 合約部署時的簽名,是這個教程中最常使用的鑰匙對
          • receiver_key 用于 Coin 合約接收轉賬,將在后文中介紹轉賬時用到
          • sponsor_key 用于 Coin 合約代付功能,將在后文中介紹代付功能時用到

          連接 Conflux 網絡

          教程將在 Oceanus 網絡進行合約的部署以及合約的調用。點擊頂部 Network 標簽的倒三角打開下拉菜單,點擊選擇 Oceanus 網絡進行切換。

          切換完成后,可以在主頁面中看到當前網絡為 oceanus。頁面左邊包括了當前網絡的節點 URLChain ID,TPS 信息,頁面右邊包含了當前網絡區塊的信息。
          在這里插入圖片描述

          申請測試 CFX

          點擊頂部 Explorer 標簽打開區塊瀏覽器,并在地址欄粘貼鑰匙對地址,可以在左邊看到當前地址的 CFX 余額信息。
          在這里插入圖片描述

          在區塊鏈的世界中,大家通常將申請測試 Token 的方式稱為 faucet,目前在 Oceanus 網絡下每次 faucet 申請到的 Token 為 100 CFX。

          獲取 CFX 的方式有兩種方式:

          • 輸入地址后點擊地址欄右邊的水龍頭按鈕,Conflux Studio 將為地址自動申請 CFX
          • 你也可以直接在瀏覽器中輸入 https://wallet.confluxscan.io/faucet/dev/ask?address={address} 來申請 CFX
            在這里插入圖片描述

          使用上述方法在 Conflux Studio 中為 minter_key 和 sponsor_key 申請 CFX Token。完成申請后,這兩個賬戶上的余額將會從 0 CFX 更新為 100 CFX。

          目前余額信息為:

          • minter_key 余額 100 CFX
          • receiver_key 余額 0 CFX
          • sponsor_key 余額 100 CFX

          智能合約

          創建項目

          點擊頂部左邊的 Project 標簽切換至項目列表頁面,點擊頁面中的 New 按鈕打開項目創建窗口,輸入項目的名稱并選擇 coin 模版,點擊 Create Project 完成項目的創建。
          在這里插入圖片描述

          合約代碼

          Coin 合約是一個簡單的代幣合約,其中:

          • 通過 mint 方法可以增發代幣數量
          • 通過 send 方法可以將一定數量的代幣轉賬給別的用戶,同時會在事件中記錄下這筆轉賬的信息
          • 通過 balanceOf 方法可以查詢到指定賬戶地址的代幣余額
          • 通過 add_privilege 方法可以為合約添加代付白名單
          • 通過 remove_privilege 方法可以為合約移除代付白名單
            在這里插入圖片描述

          Conflux 智能合約使用 Solidity 語言進行開發,打開目錄下的 contracts/Coin.sol 文件,這個是本項目的核心代碼:

          // 指定了 Solidity 的版本,通過 Pragmas(https://solidity.readthedocs.io/en/latest/layout-of-source-files.html#pragmas) 告訴編譯器本代碼可以兼容的版本為 0.5.0 到 0.7.0
          pragma solidity >=0.5.0 <0.7.0;
          
          // 導入 SponsorWhitelistControl 合約
          import "./SponsorWhitelistControl.sol";
          
          // 定義 Coin 的合約
          contract Coin {
              // 定義了兩個 State Variables(https://solidity.readthedocs.io/en/latest/structure-of-a-contract.html#state-variables)
              address public minter;
              mapping (address => uint) private balances;
          
              // 使用 SponsorWhitelistControl 合約連接系統合約
              SponsorWhitelistControl constant private SPONSOR = SponsorWhitelistControl(address(0x0888000000000000000000000000000000000001));
          
              // 定義了 `Sent` 的事件,定義了 from / to / amount 列
              event Sent(address from, address to, uint amount);
          
              // Coin 合約的 constructor ,在 constructor 中指定了 minter 的地址
              constructor() public {
                  // msg.sender 為部署合約時簽名的賬戶地址,將這個地址賦值給 minter
                  minter = msg.sender;
              }
          
              // 定義 mint 方法,通過此方法來增發代幣
              function mint(address receiver, uint amount) public {
                  require(msg.sender == minter);
                  require(amount < 1e60);
                  balances[receiver] += amount;
              }
          
              // 定義 send 方法,通過此方法可以給別的賬戶轉賬代幣
              function send(address receiver, uint amount) public {
                  require(amount <= balances[msg.sender], "Insufficient balance.");
                  balances[msg.sender] -= amount;
                  balances[receiver] += amount;
                  // 通過 emit 觸發 Sent 事件,記錄這筆轉賬的信息
                  emit Sent(msg.sender, receiver, amount);
              }
          
              // 定義 balanceOf 方法,這是個 view 類型的方法,用于查詢賬戶余額
              function balanceOf(address tokenOwner) public view returns(uint balance){
                return balances[tokenOwner];
              }
          
              // 定義了 add_privilege 方法,調用系統合約 add_privilege 方法添加地址到代付白名單
              function add_privilege(address account) public payable {
                  address[] memory a = new address[](1);
                  a[0] = account;
                  SPONSOR.add_privilege(a);
              }
          
              // 定義了 remove_privilege 方法,調用系統合約 remove_privilege 從合約代付白名單中移除地址
              function remove_privilege(address account) public payable {
                  address[] memory a = new address[](1);
                  a[0] = account;
                  SPONSOR.remove_privilege(a);
              }
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59

          編譯及部署合約

          點擊工具欄的 Build 按鈕進行合約的編譯,編譯的結果將會保存在 build/Coin.json 文件中。
          在這里插入圖片描述
          在部署合約前,首先需要確認在 Explorer 中選擇合約部署所使用的地址,Conflux Studio 會使用這個地址將部署合約這筆交易進行簽名(選擇的方法為在 Explorer 的地址欄中輸入地址)。在合約代碼的 constructor 中,minter 被賦值為 msg.sender,這個 msg.sender 就是 Explorer 所選擇的地址。

          在此我們選擇 minter_key 作為部署合約的簽名者。
          在這里插入圖片描述
          點擊工具欄的部署按鈕進行部署,部署完成后,部署結果會在 deploys 的 JSON 文件中,在這個文件中可以在 contractCreated 中找到當前合約部署的地址,后文中使用 contract_addr 來代表這個合約地址。
          在這里插入圖片描述

          調用合約

          點擊頂部的 Contract 標簽切換至合約頁面,在地址欄輸入 contract_addr 地址并加載合約。
          在這里插入圖片描述

          合約頁面由三個部分組成:

          • 左邊為合約調用區域
          • 中間為合約數據查詢區域
          • 右邊為事件查詢區域

          合約調用及查詢

          增發代幣

          點擊合約調用的下拉菜單中選擇 mint 方法,在下方的參數區域分別填入以下信息:

          • receiver 接收代幣的地址。填入 minter_key 地址
          • amount 發行的代幣總數。填入整數 1000
          • Value 選填項,具體可查看 Value 詳解。填 0 或者不填
          • Signer 這筆交易的簽名地址,如果沒有開通代付功能,交易手續費將在這個賬戶地址中扣除,在合約代碼中通過 msg.sender 獲取到這個地址。填入 minter_key 地址

          填寫完成后點擊執行按鈕,Conflux Studio 將自動構造交易并推送到網絡中。成功執行后可以在下方 Result 中看到這筆成功的交易。
          在這里插入圖片描述

          查詢代幣余額

          點擊查詢區域的下拉菜單并且選擇 balanceOf 方法,這是在代碼中定義的查詢方法。在下方的 tokenOwner 填入 minter_key 地址并點擊執行,就可以在下方的 Result 中看到 minter_key 賬戶的 Coin 代幣的余額信息為 1000。使用同樣方法可以查詢到 receiver_key 賬戶的代幣余額為 0。
          在這里插入圖片描述

          轉賬代幣

          在合約調用區域選擇 send 方法,在 Parameters 中分別填入:

          • receiver 收款人地址。填入 receiver_key 地址
          • amount 轉賬的代幣數量。填入整數 200
          • Signer 這筆交易的簽名地址,代幣轉出的數量將會在這個賬戶中扣除。填入 minter_key 地址,

          點擊執行完成轉賬,再次查詢代幣余額可以看到 minter_key 賬戶只剩下 800 代幣,而 receiver_key 賬戶則從 0 變成了 200 代幣。在這里插入圖片描述

          Value 參數

          Conflux 智能合約的每個調用的方法都可以帶上 Value 參數,這是一個可選的參數。如果帶上了這個值,智能合約出了在執行這個方法的邏輯外,還會額外轉 Value 中指定數量的 CFX token 到 receiver 賬戶,轉賬金額為 Value 中所填的值。有些智能合約的方法需要這個參數才可以完成調用,但是在 Coin 合約不需要這個參數。

          后文中的代付功能將會使用到 Value 參數。

          查詢事件

          在事件區域選擇 Sent 并點擊執行,下方的 Event Logs 可以看到轉賬的記錄。Sent 事件的列都是由代碼中的 Sent 事件的參數來定義的(其中 epoch 為事件發生的時間,這個為系統默認列)。在代碼中定義了 Sent 方法的參數為 from, to 和 amount,分別對應了這筆轉賬的發起者地址,接受者地址以及轉賬的數量。
          在這里插入圖片描述

          代付功能

          Conflux Studio 支持 Conflux 系統合約提供的代付功能

          通過系統合約可以為別的合約設置代付功能,系統合約提供給了四個方法:

          • add_privilege 添加合約代付白名單,在代付白名單中的地址調用該合約的方法時不需要付手續費,費用由代付賬戶支付。其中添加特殊地址 0x0000000000000000000000000000000000000000 代表為所有調用該合約的地址代付費用
          • remove_privilege 移除合約代付白名單
          • set_sponsor_for_collateral 設置合約儲存費 (collateral for storage) 的代付賬戶及代付金額
          • set_sponsor_for_gas 設置合約手續費 (gas fee) 的代付賬戶、代付金額及每筆交易代付金額上限

          啟用一個合約的代付需要設置代付的賬戶、代付金額的及代付白名單。教程將會使用 Conflux Studio 通過系統合約設置代付賬戶及代付金額,通過 Coin 合約添加代付白名單。設置完成后,minter_key 賬戶調用 Coin 合約的方法時將不會被扣除手續費,手續費由 sponsor_key 賬戶代付。

          設置代付賬戶及代付金額

          在 Conflux Studio 中訪問系統合約地址 0x0888000000000000000000000000000000000001,在合約調用區域能看到前文中提及的四個設置代付的方法。
          在這里插入圖片描述

          選擇 set_sponsor_for_collateral 方法,該方法有三個參數:

          • contract_addr 設置代付的合約地址。填入 contract_addr
          • Value 設置代付金額。填入整數 40
          • Signer 代付賬戶地址。填入 sponsor_key 地址
            在這里插入圖片描述
            填好以上參數并執行運行,系統合約將為 Coin 合約設置好儲存費代付賬戶,此時 sponsor_key 賬戶將會被扣除 40 CFX。

          選擇 set_sponsor_for_gas 方法,該方法有四個參數:

          • contract_addr 設置代付的合約地址。填入 contract_addr
          • upper_bound 設置每筆交易代付的上限。填入 1000000000000
          • Value 設置代付金額。填入整數 40
          • Signer 代付賬戶地址。填入 sponsor_key 地址
            在這里插入圖片描述
            填好以上參數并再次執行運行,系統合約將為 Coin 合約設置好手續費代付賬戶,此時 sponsor_key 賬戶將會再次被扣除 40 CFX。

          完成這兩個方法的調用后 Coin 合約代付賬戶便設置好了,sponsor_key 賬戶將為 Coin 合約的手續費和儲存費各提供為 40 CFX Token 的代付服務。由于目前代付白名單中并沒有賬戶地址,因此還需要添加白名單地址才能完成代付設置。

          添加代付白名單

          在 Coin 合約中集成了設置代付白名單的方法,通過調用此方法可以添加或刪除代付白名單。

          在 Conflux Studio 中訪問 contract_addr 合約,選擇 add_privilege 方法:

          • account 添加白名單的地址。填入 minter_key 地址
          • Value 不填
          • Signer 這筆交易的簽名地址。填入 minter_key 地址

          運行后就成功設置了代付白名單了,至此 Coin 合約的代付功能設置好了。

          代付測試

          在進行代付測試前,先查詢并記錄下 minter_key 賬戶的 CFX 余額。例如本教程中,minter_key 的初始余額為 97.6210937497093952 CFX。

          回到 Coin 合約調用頁面,再次調用 mint 方法并使用 minter_key 地址增發代幣 1000,完成代幣增發后再次查詢 minter_key 的余額,仍然為 97.6210937497093952 CFX。

          可以看到增發代幣的這筆交易,原本應該由 minter_key 賬戶支付的手續費,變成了由 sponsor_key 賬戶支付。

          前端項目

          前端項目源碼可以前往 Conflux 前端。

          預備

          下載項目并安裝依賴

          • 下載前端項目:git clone https://github.com/ObsidianLabs/conflux-frontend-react
          • 使用 npm install 或者 yarn 進行項目依賴安裝

          Conflux Portal 的安裝及配置

          Conflux Portal 是由 Conflux 提供的瀏覽器插件,目前提供了 Chrome 及 Firefox 的支持,用戶可以使用 Conflux Portal 進行私鑰的管理以及交易簽名。

          前往 Conflux Portal GitHub 下載安裝。項目的源代碼在 GitHub 中可以找到。

          在這里需要將 Conflux Studio 中生成的地址導入到 Conflux Portal 中。完成插件安裝后,在 Conflux Portal 的頁面中選擇 Import,將 Conflux Studio 中的 minter_key 的私鑰(在創建錢包章節中介紹了如何將私鑰導出)粘貼到輸入框中,點擊 Import 按鈕完成私鑰導入。
          在這里插入圖片描述

          運行前端項目

          在運行項目之前,需要修改一些默認的環境變量。

          前面的教程中部署合約后會生成一個 contractCreated,這個值便是部署在網絡中智能合約的地址。打開項目根目錄并找到 .env 文件,這個文件提供了項目的環境變量,將 REACT_APP_CONFLUX_COIN_ADDRESS 的值修改為 contract_addr。

          使用 yarn start 啟動前端項目,開發服務器運行起來后會在瀏覽器中打開前端頁面(如果沒有打開,請在瀏覽器中訪問 http://localhost:3000)。

          項目運行起來后,頁面將顯示四個卡片信息,分別為

          • 左上角 Conflux 網絡信息模塊
          • 右上角 Conflux Portal 模塊
          • 左下角 Coin 合約模塊
          • 右下角 SponsorWhitelistControl 合約模塊
            在這里插入圖片描述

          連接 Conflux Portal

          點擊右上角組件中的 Connect to Conflux Portal 按鈕,Conflux Portal 頁面將被打開,輸入密碼和選擇賬戶后完成連接。連接成功后,將會在按鈕下看到當前連接的賬戶地址以及賬戶中的 CFX 余額。
          在這里插入圖片描述

          運行 Coin 合約代幣增發和代幣轉賬操作

          左下角的組件為 Coin 合約組件,可以通過這個組件調用代幣增發和代幣轉賬功能。

          • 代幣增發:選擇 mint 方法并在 receiver 中填入增發地址 minter_key 地址和在 amount 中填入增發代幣的數量 100,點擊 Push Transaction,在彈出的 ConfluxPortal Notification 窗口中點擊 Confirm 按鈕來確認交易。

          • 代幣轉賬:選擇 send 方法并在 receiver 中填入收款人地址 receiver_key 地址和在 amount 中轉賬代幣的數量 20,點擊 Push Transaction,在彈出的 ConfluxPortal Notification 窗口中點擊 Confirm 按鈕來確認交易。
            在這里插入圖片描述

          查看 Coin 合約中的余額

          選擇 balanceOf 方法并在 tokenOwner 輸入框中填入查詢的地址,點擊 Query Data 按鈕可以查詢到賬戶的余額。
          在這里插入圖片描述

          查看 Sent 事件

          選擇 Sent 事件并點擊 Query Data 可以查詢到轉賬操作所觸發的轉賬事件的記錄。
          在這里插入圖片描述

          前端項目解析

          項目使用 React 進行開發。主要由三大部分組成:視圖組件、js-conflux-sdk 以及 Conflux Portal。

          項目根目錄下的 .env 環境變量,在這里定義了兩個環境變量,分別為

          • REACT_APP_CONFLUX_NODE_RPC:Conflux 的網絡節點地址,目前默認為 Oceanus 網絡的地址
          • REACT_APP_CONFLUX_COIN_ADDRESS:已部署的 Coin 智能合約地址

          視圖組件

          視圖組件在項目的 src/components 中,其中 App.js 為頁面的主入口,負責頁面的排列及合約信息的讀取。
          在這里插入圖片描述

          ConfluxNetwork.js

          負責渲染 Conflux 網絡信息,Node URL 的值為 .env 環境變量文件下的 REACT_APP_CONFLUX_NODE_RPC 設置的值(默認為 Oceanus 網絡)。

          ConfluxPortal.js

          負責渲染 Conflux Portal 的連接信息,并提供了連接 Conflux Portal 的交互按鈕。

          • connectConfluxPortal 調用 Conflux Portal 的 enable 方法啟用 conflux (conflux portal 實例由瀏覽器插件注入到 windows.portal 中),完成 enable 后調用 getAccount 方法獲取到 Portal 中的賬戶。
          • refreshBalance 調用 Conflux SDK 的 getBalance 方法來更新賬戶余額信息
          • renderPortalButton 根據當前不同的狀態,渲染連接 Portal 的按鈕
          ConfluxContract.js

          負責渲染 Conflux 合約信息,本項目中提供了 Coin 和 SponsorWhitelistControl 兩個合約。

          ConfluxContract.js 由三個組件組成,分別為:

          • ConfluxContract 負責根據傳入的合約 abi 來渲染合約的信息,包括合約地址、合約方法和事件,合約提交的交互邏輯及顯示執行后的結果
          • ContractMethods 負責渲染合約 abi 中的方法和事件的表單及相對應的按鈕
          • ConfluxForm 負責根據方法或事件的 abi 來渲染輸入表單

          lib

          lib 在項目的 src/lib 中,這里的文件主要是為視圖提供包括連接網絡、構造交易、獲取賬戶、讀取合約等服務。
          在這里插入圖片描述

          conflux.js

          conflux.js 是 js-conflux-sdk 的封裝。js-conflux-sdk 是由 Conflux 提供的 JavaScript SDK,本前端項目使用 SDK 來連接 Conflux 網絡,和合約進行交互以及構造合約中的實例。

          conflux-portal.js

          conflux-portal.js 是 Conflux Portal 的封裝,本前端項目通過調用瀏覽器插件來完成交易的簽名。調用 Conflux Portal 提供的 enable 方法可以啟動項目和 Conflux Portal 的連接(需要提前檢查瀏覽器是否正確安裝插件,在 constructor 中通過檢查 window.conflux 是否為空來判斷)。conflux-portal.js 提供了獲取賬戶 getAccount 和發送交易 sendTransaction 兩個主要的方法。

          abi

          lib/abi 文件夾下提供了兩個 json 文件,分別為 Coin.json 和 SponsorWhitelistControl.json,這兩個文件是構造合約所需要使用的 abi 文件。

          總結

          在本開發教程中,我們學習了如何使用 Conflux Studio 來完成一個完整的 Coin DApp 開發,其中包括了:

          • 使用鑰匙對管理器創建賬戶及導出賬戶私鑰
          • 切換 Oceanus 網絡,查看網絡信息
          • 賬戶申請 CFX Token
          • 創建、編譯并部署項目
          • 解析 Coin 合約代碼,學習如何編寫合約的讀寫方法及事件
          • 使用合約瀏覽器調用 Coin 合約的代幣增發、轉賬、查詢余額及查詢事件
          • 設置并使用智能合約的代付功能
          • 將私鑰導入 Conflux Portal 并連接前端項目
          • 在前端項目中調用 Coin 合約的代幣增發、轉賬、查詢余額及查詢事件
          • 解析前端項目代碼,學習如何通過 Conflux Portal 和 Conflux JavaScript SDK 連接網絡并實現交易

          關于 Conflux Bounty

          Conflux 基金會為了鼓勵用戶參與生態建設,提供了 Conflux Bounty 賞金平臺。通過完成 Bounty 賞金平臺發布的各項任務,參與者可以獲得 FC (Fans Token) 作為獎勵。

          FC 的價值

          FC,全稱 Fans Coin,是由 Conflux 基金會與社區成員共同研發的生態代幣,用于記錄和感謝對 Conflux 生態建設做出貢獻的社區成員。FC 目前在 Oceanus 上運行,Conflux 基金會承諾,在主網上線后,鎖定和未鎖定的 FC 都可以與主網 CFX 進行 1:1 承兌,以此保障所有社區成員的勞動成果都可以獲得獎勵。
          在這里插入圖片描述

          FC 賞金分配方案會展示在賞金任務詳情頁中,包括最高獎金數量、獎金分配人數、獎金數量分布、排行名次確定方式等信息。賬號余額中的賞金獎勵可以隨時申請提現至 Conflux 錢包。Conflux 團隊會對所有的提現申請進行審核。

          對于已經通過的提現申請,Conflux 團隊會在每周二中午 12 點(如遇節假日,往后順延至下一個工作日)進行提幣操作。完成提幣操作后,您的 Conflux 錢包將會收到您提現的賞金獎勵。

          Bounty 的價值

          Conflux Bounty (https://bounty.conflux-chain.org) 的宗旨是為每一個通證找到價值。Bounty 分為幾個板塊:技術、品牌、社群、資源、其他等。

          • 技術板塊:分為產品、SDK、教程、開發、測試等;主要是獎勵社區的一些技術資源貢獻者。
          • 品牌板塊:分為文案、設計、視頻、媒體、推廣等;主要是獎勵在各大網絡平臺分享 Conflux 的各種最新動態,擴大 Conflux 的生態影響力的活躍貢獻者;
          • 社群板塊:分為活動、推廣等;主要是獎勵舉辦各種 Conflux 相關線上線下活動,幫助解答社群問題,活躍日常氣氛等。
          • 資源板塊:分為政務、商務、人力等;主要是獎勵為生態中引進企業資源,擴建Conflux 生態等。
          • 其他板塊:分為周邊、采購等;主要是獎勵一些其他的零散任務。

          關于 Obsidian Labs

          黑曜石實驗室(Obsidian Labs) 是全球最大的區塊鏈開發工具(IDE)提供商,也是 Conflux Studio 的開發團隊,致力于為區塊鏈開發者提供必備的工具及服務,幫助鏈上應用生態快速發展。目前,除了 Conflux Studio 外,Obsidian Labs 還為 EOS、Nervos、Substrate、Alogorand 等明星項目提供了專屬的 IDE 和框架工具。






          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          原文鏈接:https://blog.csdn.net/weixin_45029854/article/details/107638406
          作者:Sam @黑曜石實驗室
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          智能合約 web3.js ABI Address三者的關系

          前端達人

          web3.js是以太坊提供的一個Javascript庫,它封裝了以太坊的JSON RPC API,提供了一系列與區塊鏈交互的Javascript對象和函數,包括查看網絡狀態,查看本地賬戶、查看交易和區塊、發送交易、編譯/部署智能合約、調用智能合約等,其中最重要的就是與智能合約交互的API。

          下面就介紹如何使用web3.js提供的接口調用智能合約。

          系統和軟件

          
          
          1. Ubuntu 16.04 64
          2. nodejs 6.10.0
          3. npm 3.10.10

          示例合約

          本文以下面的MetaCoin合約為例,說明在應用中使用web3.js操作智能合約的方法。

          
          
          1. // 本文中用到的MetaCoin合約
          2. pragma solidity ^0.4.2;
          3. contract MetaCoin {
          4. mapping (address => uint) balances;
          5. event Transfer(address indexed _from, address indexed _to, uint256 _value);
          6. function MetaCoin() {
          7. balances[tx.origin] = 10000;
          8. }
          9. function sendCoin(address receiver, uint amount) returns(bool sufficient) {
          10. if (balances[msg.sender] < amount) return false;
          11. balances[msg.sender] -= amount;
          12. balances[receiver] += amount;
          13. Transfer(msg.sender, receiver, amount);
          14. return true;
          15. }
          16. function getBalance(address addr) returns(uint) {
          17. return balances[addr];
          18. }
          19. }

          這個合約有三個函數:

          MetaCoin:構造函數,在合約被部署到區塊鏈時執行 
          getBalance:返回某賬戶的余額,它只讀數據,不會修改數據 
          sendCoin:向另一個賬戶發送指定數量的MetaCoin,它會改變狀態變量balances 
          啟動一個以太坊節點,將上面的合約部署到區塊鏈中,并記錄下合約的地址,可以通過truffle部署,具體參考這篇文章。 接下來就可以按照下面的步驟在項目中通過web3.js來使用這個合約。

          添加web3到項目中

          首先新建一個Nodejs項目并初始化:

          
          
          1. $ mkdir web3test && cd web3test
          2. $ npm init

          會提示輸入項目信息,全部默認即可。 
          接下來下載web3.js到項目中:

          $ npm install web3 --save 
          • 1
          • 2

          以上命令會將web3.js下載到web3test/node_modules目錄下,其中–save參數會web3.js添加到package.json配置文件中。

          創建web3對象

          要使用web3.js與區塊鏈交互,需要先創建web3對象,然后連接到以太坊節點。 在web3test目錄下新建index.js文件,在其中輸入以下代碼:

          
          
          1. var Web3 = require("web3");
          2. // 創建web3對象
          3. var web3 = new Web3();
          4. // 連接到以太坊節點
          5. web3.setProvider(new Web3.providers.HttpProvider("http://localhost:8545"));

          獲取已部署的合約實例

          要使用智能合約,必須先從區塊鏈中獲取到合約實例,獲取合約實例需要合約的ABI和合約的地址:

          
          
          1. // 合約ABI
          2. var abi = [{"constant":false,"inputs":[{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"name":"sendCoin","outputs":[{"name":"sufficient","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}];
          3. // 合約地址
          4. var address = "0xb2cdd356e58280906ce53e1665697b50f88aac56";
          5. // 通過ABI和地址獲取已部署的合約對象
          6. var metacoin = web3.eth.contract(abi).at(address);

          metacoin就是獲取到的合約對象實例,此時metacoin對象中就包含了與合約函數同名的Javascript函數,之后就可以通過metacoin對象來調用合約中的函數了。

          調用合約函數

          MetaCoin合約中有兩個函數:getBalance和sendCoin,可以通過metacoin對象直接調用這兩個函數。

          首先來看getBalance,由于getBalance函數只是從區塊鏈中讀數據,而不修改數據,因此我們通過在getBalance后面加上.call()的方式調用:

          
          
          1. var account_one = web3.eth.accounts[0];
          2. var account_one_balance = metacoin.getBalance.call(account_one);
          3. console.log("account one balance: ", account_one_balance.toNumber());

          這里:

          在getBalance后加上.call()來顯式指明用call的方式調用 
          通過call的方式調用可以得到getBalance函數的返回值 
          通過call的方式調用的函數只在節點本地虛擬機中執行,不會產生交易,不會花費費用,不會修改數據 
          下面來看sendCoin函數,由于sendCoin要修改合約內部的數據,所以要使sendCoin生效,必須要向區塊鏈發送交易,可以在sendCoin后面加上.sendTransaction()來指明這是一筆交易:

          
          
          1. var account_one = web3.eth.accounts[0];
          2. var account_two = web3.eth.accounts[1];
          3. // 提交交易到區塊鏈,會立即返回交易hash,但是交易要等到被礦工收錄到區塊中后才生效
          4. var txhash = metacoin.sendCoin.sendTransaction(account_two, 100, {from:account_one});
          5. console.log(txhash);

          這里:

          在sendCoin函數后加上.sendTransaction()指明要向區塊鏈發送交易 
          合約代碼中sendCoin函數只有兩個參數,而在web3中通過.sendTransaction()調用合約函數的時候需要增加最后一個參數,它是一個javascript對象,里面可以指定from/value/gas等屬性,上面的例子用from來指定交易的發送者 
          上面的調用語句執行后,會向區塊鏈提交一筆交易,這筆交易的發送者是account_one,接收者是metacoin的地址,交易的作用是以account_two和100作為參數執行合約的sendCoin函數 
          函數會立即返回交易的hash,表明交易已經提交到區塊鏈,但是并不知道交易何時處理完成,交易要等到被曠工收錄到區塊中后才會生效 
          監聽合約事件

          當通過.sendTransaction()調用合約的時候,交易會被提交到區塊鏈進行處理,這個處理需要一定的時間,如果需要等交易完成之后再執行其他操作,就必須要知道交易何時完成,那么如何知道交易何時完成呢?可以通過監聽合約事件來實現。

          在合約中可以定義事件,事件可以帶有參數,在合約函數內部完成某些操作時,可以觸發事件,向外界傳達一些信息。例如,在MetaCoin合約中定義了一個事件叫做Transfer,表示一個轉賬的事件,它帶有三個參數:交易的發送者、接受者、轉賬數量。在sendCoin函數中,轉賬成功后就會觸發Transfer事件,將對應的參數傳給該事件,這樣外部監聽到事件后,可以取出事件的參數來獲得交易發送者、接收者、數量。同時事件中還帶有其他信息,比如交易hash等。

          在web3中使用事件,要首先獲取事件對象,然后監聽事件,如果事件發生,就會在回調函數中獲取到事件信息:

          
          
          1. // 獲取事件對象
          2. var myEvent = metacoin.Transfer();
          3. // 監聽事件,監聽到事件后會執行回調函數
          4. myEvent.watch(function(err, result) {
          5. if (!err) {
          6. console.log(result);
          7. } else {
          8. console.log(err);
          9. }
          10. myEvent.stopWatching();
          11. });
          12. // 輸出:
          13. { address: '0xb2cdd356e58280906ce53e1665697b50f88aac56',
          14. blockNumber: 651,
          15. transactionIndex: 0,
          16. transactionHash: '0xcc71bc2824cc84d1ee831c46189e3a80cf0af05697ba0370693aa97390c8067b',
          17. blockHash: '0x1d53f04206f3926d0f311b1230a9dd0b0c5aadac35b169a6a609e384ab130c6f',
          18. logIndex: 0,
          19. removed: false,
          20. event: 'Transfer',
          21. args:
          22. { _from: '0x68b73956d704007514e9257813bdc58cdf3c969a',
          23. _to: '0x9c3c1a2f5ef913fac44f0348a78f68d835f3f26e',
          24. _value: { [String: '100'] s: 1, e: 2, c: [Object] } } }


          從輸出可以看出,獲取到的事件信息包括事件的參數、事件名、區塊號、交易hash等。

          通過檢測事件中的transactionHash與調用合約函數返回的交易hash是否一致,可以判定某一筆交易是否已完成:

          
          
          1. var account_one = web3.eth.accounts[0];
          2. var account_two = web3.eth.accounts[1];
          3. var account_one_balance = metacoin.getBalance.call(account_one);
          4. console.log("account one balance:", account_one_balance.toNumber());
          5. var txhash = metacoin.sendCoin.sendTransaction(account_two, 100, { from: account_one });
          6. var myEvent = metacoin.Transfer();
          7. myEvent.watch(function (err, result) {
          8. if (!err) {
          9. if (result.transactionHash == txhash) {
          10. var account_one_balance = metacoin.getBalance.call(account_one);
          11. console.log("account one balance after sendCoin:", account_one_balance.toNumber());
          12. }
          13. } else {
          14. console.log(err);
          15. }
          16. myEvent.stopWatching();
          17. });
          18. // 輸出:
          19. account one balance: 7000
          20. account one balance after sendCoin: 6900


          watch中的回調函數如果被執行,說明事件已被觸發,也就是說某筆交易已經處理完,檢查交易hash是否一致,可以判定產生這個事件的交易是否是自己發送的交易,如果是,就可以進行其他操作,比如查詢最新的余額


          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          async function

          前端達人

          這篇文章多看幾遍加深理解

          async function 聲明定義了一個異步函數,它返回一個AsyncFunction對象。異步函數 是指通過 事件循環(event loop) 異步執行的函數,通過返回一個隱式的 Promise 作為其結果。使用異步函數的代碼的語法和結構更像使用標準同步功能。(The async function declaration defines an asynchronous function, which returns an AsyncFunction object. An asynchronous function is a function which operates asynchronously via the event loop, using an implicit Promise to return its result. But the syntax and structure of your code using async functions is much more like using standard synchronous functions.

          語法

          async function name([param[, param[, ... param]]]) { statements } 
          
          • 1

          參數

          • name:函數名稱
          • param:要傳遞給函數的參數。
          • statements:函數體語句。

          返回值:返回一個promise對象,將返回異步函數返回的值(如果異步函數是resolved則返回resolved的值;如果拋出異常,則rejected從異步函數中拋出的異常)。(A Promise which will be resolved with the value returned by the async function, or rejected with an uncaught exception thrown from within the async function.)

          異步函數可以包含await表達式,該表達式暫停異步函數的執行 并等待 Promise的執行結果返回,結果返回后就恢復異步函數的執行。

          await 關鍵字只在異步函數(async functions)內有效。如果在異步函數外使用它,會拋出語法錯誤。
          當異步函數暫停時,它調用的函數仍會繼續執行。

          舉例一:

          function resolveAfter5Seconds() { return new Promise(resolve => { setTimeout(() => { resolve('resolved'); }, 5000); }); } async function asyncCall() { console.log('calling'); let result = await resolveAfter5Seconds(); console.log(result); // 5s之后輸出結果 } asyncCall(); //返回的是一個promise對象 // console.log(asyncCall()); // Promise { <pending> } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16

          運行效果:
          在這里插入圖片描述
          舉例二:

          let resolveAfter6Second = function () { console.log('start slow promise'); return new Promise(resolve => { setTimeout(() => { resolve('slow'); console.log('slow promise is done'); }, 6000); }) } let resolveAfter4Second = function () { console.log('start fast promise'); return new Promise(resolve => { setTimeout(() => { resolve('fast'); console.log('fast promise is done'); }, 4000); }) } let sequentialStart = async function () { console.log('sequential start'); const slow = await resolveAfter6Second(); console.log(slow); const fast = await resolveAfter4Second(); console.log(fast); } sequentialStart() //立即輸出 // sequential start // start slow promise //再過6秒后輸出 // slow promise is done // slow // start fast promise //再過4秒后輸出 // fast promise is done // fast 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41

          運行效果:
          在這里插入圖片描述
          換一種await的寫法,結果完全不同:兩個計時器被同時創建

          let resolveAfter6Seconds = function () { console.log('start slow promise'); return new Promise(resolve => { setTimeout(() => { resolve('slow'); console.log('slow promise is done'); }, 6000); }) } let resolveAfter4Seconds = function () { console.log('start fast promise'); return new Promise(resolve => { setTimeout(() => { resolve('fast'); console.log('fast promise is done'); }, 4000); }) } let concurrentStart = async function () { console.log('concurrent start'); let slow = resolveAfter6Seconds(); let fast = resolveAfter4Seconds(); console.log(await slow); console.log(await fast); } setTimeout(() => { concurrentStart(); }, 2000); //2秒后執行 // concurrent start // start slow promise // start fast promise //再過4秒后執行 // fast promise is done //再過2秒后執行 // slow promise is done // slow // fast 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42

          運行效果:
          在這里插入圖片描述
          在 concurrentStart 中,兩個計時器被同時創建,接著執行await。等待的是 promise的resolve回調,resolve后面的代碼( console.log(‘fast promise is done’);)會繼續執行。
          這兩個計時器同時運行。但是 await 仍舊是順序執行的,第二個 await 還是得等待第一個執行完。在這個例子中,這使得先運行結束的輸出出現在最慢的輸出之后。
          也可以把 concurrentStart 改寫成如下,運行效果一樣:

          let resolveAfter6Seconds = function () { console.log('start slow promise'); return new Promise(resolve => { setTimeout(() => { resolve('slow'); console.log('slow promise is done'); }, 6000); }) } let resolveAfter4Seconds = function () { console.log('start fast promise'); return new Promise(resolve => { setTimeout(() => { resolve('fast'); console.log('fast promise is done'); }, 4000); }) } let concurrentPromise = async function () { console.log('concurrent start'); return Promise.all([resolveAfter6Seconds(), resolveAfter4Seconds()]).then((messages) => { console.log(messages[0]); // slow console.log(messages[1]); // fast }); } setTimeout(() => { concurrentPromise(); }, 2000); //2秒后輸出 // concurrent start // start slow promise // start fast promise //再過6秒后輸出 // fast promise is done //再過2秒后輸出 // slow promise is done // slow // fast 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41

          并行執行兩個或更多的任務,如下例所示:

          let resolveAfter6Seconds = function () { console.log('start slow promise'); return new Promise(resolve => { setTimeout(() => { resolve('slow'); console.log('slow promise is done'); }, 6000); }) } let resolveAfter4Seconds = function () { console.log('start fast promise'); return new Promise(resolve => { setTimeout(() => { resolve('fast'); console.log('fast promise is done'); }, 4000); }) } let parallel = async function () { console.log('start paralel'); await Promise.all([ (async () => console.log(await resolveAfter6Seconds()))(), (async () => console.log(await resolveAfter4Seconds()))() ]); } setTimeout(parallel, 2000); //2秒后輸出 // start paralel // start slow promise // start fast promise //再過4秒后輸出 // fast promise is done // fast //再過2秒后輸出 // slow promise is done // slow 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41

          運行效果:
          在這里插入圖片描述
          如果希望并行執行兩個或更多的任務,你必須像在parallel中一樣使用await Promise.all([job1(), job2()])

          也可以把parallel改寫成如下,運行效果一樣:

          let resolveAfter6Seconds = function(){ console.log('start slow promise'); return new Promise(resolve => { setTimeout(() => { resolve('slow'); console.log('slow promise is done'); }, 6000); }); } let resolveAfter4Seconds = function(){ console.log('start fast promise'); return new Promise(resolve =>{ setTimeout(() => { resolve('fast'); console.log('fast promise is done'); }, 4000); }) } let parallelPromise = function(){ console.log('parallelPromise start'); resolveAfter6Seconds().then(msg => console.log(msg)); resolveAfter4Seconds().then(msg => console.log(msg)); } setTimeout(() => { parallelPromise(); }, 2000); //2秒后輸出 // parallelPromise start // start slow promise // start fast promise //再過4秒后輸出 // fast promise is done // fast //再過2秒后輸出 // slow promise is done // slow 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39

          async/await和Promise#then對比以及錯誤處理:
          大多數異步函數(async functions )也可以使用 Promises函數 編寫。然而,當涉及到錯誤處理時,異步函數不太容易出錯。
          上面例子中的concurrentStart函數和concurrentPromise函數在功能上都是等效的。在concurrentStart函數中,如果任一awaited調用失敗,它將自動捕獲異常,異步函數執行中斷,并通過隱式返回Promise將錯誤傳遞給調用者。
          在Promise例子中這種情況同樣會發生,函數必須負責返回一個捕獲函數完成的Promise。在concurrentPromise函數中,這意味著它從Promise.all([]).then()中返回一個Promise。事實上,在此示例的先前版本忘記了這樣做!
          但是,async函數仍有可能然可能錯誤地忽略錯誤。
          以parallel異步函數為例。 如果它沒有等待await(或 return)Promise.all([])調用的結果,則不會傳播任何錯誤。
          雖然parallelPromise函數示例看起來很簡單,但它根本不會處理錯誤! 這樣做需要一個類似于return Promise.all([])處理方式。(詳見

          使用async函數重寫 promise 鏈

          返回 Promise的 API 將會產生一個 promise 鏈,它將函數分解成許多部分。例如下面的代碼:

          function getProcessedData(url) { return downloadData(url)// returns a promise .catch(e => { return downloadFallbackData(url);// returns a promise }) .then(v => { return processDataInWorker(v);// returns a promise }) } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10

          可以重寫為單個async函數:

          async function getProcessedData(url) { let v; try { v = await downloadData(url); } catch (e) { v = await downloadFallbackData(); } return processDataInWorker(v); } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9

          在上述示例中,return 語句中沒有 await 操作符,因為 async function 的返回值將被隱式地傳遞給 Promise.resolve。

          return await promiseValue; 與 return promiseValue;的比較

          返回值隱式的傳遞給Promise.resolve,并不意味著return await promiseValue;,只是在功能上等同于返回return promiseValue;。
          重寫的上面代碼,在processDataInWorker拋出異常時返回null:

          async function getProcessedData(url) { let v; try { v = await downloadData(url); } catch(e) { v = await downloadFallbackData(url); } try { return await processDataInWorker(v); // 注意 `return await` 和單獨 `return` 的比較 } catch (e) { return null; } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13

          簡單地寫上return processDataInworker(v);將導致在processDataInWorker(v)出錯時function返回值為Promise而不是返回null。

          return foo;return await foo;有一些細微的差異:
          return foo;不管foo是promise還是rejects都將會直接返回foo。相反地,如果foo是一個Promise,return await foo;將等待foo執行(resolve)或拒絕(reject),如果是拒絕,將會在返回前拋出異常。


















          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          JavaScript 中 this 關鍵字

          前端達人

          this是什么 

          一般情況下,this 指向調用他們的那個對象 ,也就是說誰調用就指向誰。

          在全局作用域下 this指向誰 window

          console.log(this);

          普通函數里面 this 指向 window

          
          
          1. function fn() {
          2. console.log(this);
          3. };
          4. fn();

          定時器里面的 this 指向 window

          
          
          1. window.setTimeout(function() {
          2. console.log(this);
          3. }, 3000);

          對象的方法里面的this指向這個對象

          
          
          1. var idol = {
          2. myname: '某某某',
          3. age: '18歲',
          4. sex: '女',
          5. skill: function() {
          6. console.log(this);
          7. }
          8. };
          9. idol.skill()

          給指定元素綁定事件,this指向事件綁定者 btn

          
          
          1. var btn = document.querySelector('button');
          2. // btn.addEventListener('click', function() {
          3. // console.log(this);
          4. // });
          5. btn.onclick = function() {
          6. console.log(this);
          7. };

          構造函數里面的this指向對象的實例化 構造函數在調用的時候 使用new

          
          
          1. function Fun() {
          2. console.log(this);
          3. }
          4. var fun = new Fun();
          5. fun.uname = 'Jack';
          6. fun.age = '18歲';
          7. fun.sex = '男';
          8. console.log(fun)








          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

          VSCode通過LocalHost打開html文件

          前端達人



          在這里插入圖片描述

          首先安裝上圖的插件,接著如下圖右鍵HTML文件選擇Open with Live Server即可

          在這里插入圖片描述

          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          Echarts圖表根據瀏覽器窗口縮放進行動態縮放,多個echarts同時縮放

          前端達人


          更改之前的效果圖:

          在這里插入圖片描述
          更改之前瀏覽器窗口放大縮小圖表都不會進行動態的縮放,
          更改之后的效果圖:

          在這里插入圖片描述
          更改之后圖表就會根據瀏覽器窗口大小實時監聽進行縮放
          代碼:

           topChart.setOption({ series: [ {name: '最大值',type: 'line',stack: '最大值',data: dataMax}, {name: '最小值',type: 'line',stack: '最小值',data: dataMin}, {name: '平均值',type: 'line',stack: '平均值',data: dataAvg}, ] }); window.addEventListener("resize",()=> {//監聽瀏覽器窗口大小 topChart.resize(); }); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10

          如果有多個圖表同時渲染,給個定時器就可以了,ss[0],ss[1],ss[2],ss[3]分別表示四個圖表的class

          var resizeTimer = null; window.addEventListener("resize", () => { if (resizeTimer) { clearTimeout(resizeTimer) } resizeTimer = setTimeout(function(){ ss[0].resize(); ss[1].resize(); ss[2].resize(); ss[3].resize(); }, 10); }); 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12

          沒了,結束了,是不是很簡單吶,如有問題,歡迎留言。


























          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務


          [Vue項目實戰]登錄功能實現

          前端達人

          寫在前面

          vue文件最后要空一行,不然會報錯,真的奇葩…

          登錄概述

          登錄業務流程

          • 1.在登錄頁面輸入用戶名和密碼
          • 2.調用后臺接口進行驗證
          • 3.通過驗證之后,根據后臺得響應狀態跳轉到項目主頁

          登錄業務的相關技術點

          • http是無狀態的
          • 通過cookie在客戶端記錄狀態
          • 通過session在服務器端記錄狀態
          • 通過token方式維持狀態

          這里要清楚哦!

          登錄—token原理分析

          • 1.登錄頁面輸入用戶名和密碼進行登錄
          • 2.服務器驗證通過之后生成該用戶的token并返回
          • 3.客戶端存儲該token
          • 4.后續所有的請求都攜帶該token發送請求
          • 5.服務器端驗證token是否通過

          登錄功能實現

          登錄頁面的布局

          通過Element-UI組件實現布局

          • el-form
          • el-form-item
          • el-input
          • el-button
          • 字體圖標

          在vscode打開終端ctrl+~

          git status 查看當前git狀態
          git checkout -b login 創建一個新的分支叫login
          git branch 切換分支
          在這里插入圖片描述


          在vue ui中啟動!
          在這里插入圖片描述


          終端指令npm run serve也可以運行!

          在components文件下創建一個vue文件

          import Vue from 'vue' import VueRouter from 'vue-router' import login from './components/login.vue' Vue.use(VueRouter) const routes = [ {path:'/login',component:login} ] const router = new VueRouter({ routes }) export default router 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15

          配置路由(并添加路由重定向)

          const router = new VueRouter({ routes: [ { path: '/', redirect: '/login' }, { path: '/login', component: login } ] }) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12

          一定要注意空格,不然會報錯,可惡啊!

          頁面編寫

          先給一個全局樣式表

          /* 全局樣式表 */ html, body, #app{ height: 100%; margin: 0; padding: 0; } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8

          并在main.js中導入

          import './assets/css/global.css' 
          
          • 1

          完成登錄框居中

          注意:translate 進行移動,完成真正的居中

          .login_box{ width: 450px; height: 300px; background-color: #fff; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9

          在這里插入圖片描述

          添加一個登錄圖標
           .avatar_box{ height: 130px; width: 130px; border: 1px solid #eee; border-radius: 50%; padding: 10px; box-shadow: 0px 0px 10px #ddd; position: absolute; left: 50%; transform: translate(-50%,-50%); background-color: #fff;
                  img{ width: 100%; height: 100%; border-radius: 50%; background-color: #eee; } } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18

          在這里插入圖片描述

          登錄表單的布局

          通過Element-UI組件實現布局

          • el-form
          • el-form-item
          • el-input
          • el-button
          • 字體圖標

          elements組件庫網頁
          在網站里面可以找到一些可以使用的基礎模板代碼

          導入組件

          import Vue from 'vue'
          import { Button, Form, FormItem, Input } from 'element-ui'//分開import會報錯
          
          Vue.use(Button) Vue.use(Form) Vue.use(FormItem) Vue.use(Input) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7

          中間form和button都是直接到上面的組件庫里面去找的

          中間一些代碼不貼了,比較枯燥呀

          特別地,我們的小圖標是從阿里的icon庫里面下載的

          具體用法見以前寫得一篇博客
          阿里巴巴icon圖標盡在掌握(前端如何引入icon庫,美麗圖標隨你處置T.T)
          在這里插入圖片描述

          登錄表單的數據綁定
          • 1.:model=“loginForm” 綁定一個表單
          • 2.在form-item中用v-model雙向綁定數據對象
          • 3.在export default中data() return表單數據
          登錄表單的驗證規則
          • 1.:rules="ruleForm"綁定一個規則
          • 2.在form-item中用prop屬性設置為需要校驗的字段名
           // 這是表單的驗證規則對象 loginFormRules: { // 驗證用戶名是否合法 username: [ { required: true, message: '請輸入登錄名稱', trigger: 'blur' }, { min: 3, max: 10, message: '長度在 3 到 10 個字符', trigger: 'blur' } ], // 驗證密碼是否合法 password: [ { required: true, message: '請輸入登錄密碼', trigger: 'blur' }, { min: 6, max: 15, message: '長度在 6 到 15 個字符', trigger: 'blur' } ] } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14

          在這里插入圖片描述

          登錄表單的重置
          • 1.在el-form中添加ref引用名稱,以便獲取表單
          • 2.在方法中添加方法,用this.$refs.loginFormRef.resetFields()來重置表單,注意表單的值會變為data里面設置的初值
          登錄預驗證
          • 1.同樣的this.$refs.loginFormRef.validate()
          • 2.配置axios
          import axios from 'axios' // 配置請求的根路徑 axios.defaults.baseURL = 'https://127.0.0.1:8888/api/private/v1/' Vue.prototype.$http = axios 
          
          • 1
          • 2
          • 3
          • 4
          • 3.如下獲取查詢的結果
            使用async 和await要獲取返回結果
           this.$refs.loginFormRef.validate(async valid => { if (!valid) return const { data: res } = await this.$http.post('login', this.loginForm) console.log(res) if (res.meta.status !== 200) return console.log('登錄失敗') console.log('登錄成功') }) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          登錄組件配置彈窗提示
          • 1.在element.js中引入message并掛載到vue上
          Vue.prototype.$message = Message // 掛載到了Vue上 
          
          • 1
          • 2.直接調用this.$message.error(‘登錄失敗!’)
            在這里插入圖片描述
          登錄成功后的行為
          1.將登錄之后的token,保存到客戶端的sessionStorage中
          • 1.項目中除了登錄之外的其他API接口,必須在登錄之后才能訪問
          • 2.token只應在當前網站打開期間生效,所以將token保存在sessionStorage中
            將這個token存儲到了會話存儲
            在這里插入圖片描述

          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼藍小助,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務



          日歷

          鏈接

          個人資料

          藍藍設計的小編 http://www.syprn.cn

          存檔

          亚洲va欧美va天堂v国产综合