沐鳴登錄測速_socket.io的接入使用

WebSocket 簡介

傳統的客戶端和服務器通信協議是HTTP:客戶端發起請求,服務端進行響應,服務端從不主動勾搭客戶端。

這種模式有個明顯軟肋,就是同步狀態。而實際應用中有大量需要客戶端和服務器實時同步狀態的場景,比如聊天室、股票行情、在線共享文檔等都需要客戶端實時拿到服務器的最新狀態。

針對這種實時同步的需求,一種簡單的方式是輪詢,比如每隔5s發一次http請求去拿服務器最新的狀態數據。但這種方式會存在數據延遲,浪費帶寬等副作用。

更完美的方式是使用WebSocket,瀏覽器原生支持,W3C標準協議,客戶端和服務器建立持久性連接可以互發消息。

socket.io 簡介

socket.io 是一個類庫,內部封裝了WebSocket,可以在瀏覽器與服務器之間建立實時通信。

如果某些舊版本的瀏覽器不支持WebSocket,socket.io會使用輪詢代替。另外它還具有可發送二進制消息、多路復用、創建房間等特性,因此相比直接使用原生WebSocket,socket.io是更好的選擇。

開發一個實時應用主要分兩部分:服務端和客戶端,socket.io分別提供了相應的npm包供我們方便地調用。

接下來就通過一個生動形象且有趣的栗子分別介紹這兩大塊。

現在假設李白,瑤,呂布,后羿,貂蟬5個人加入了一個叫 KPL 的房間,在文章結束時我們將擁有一個麻雀雖小五臟俱全的峽谷英雄在線聊天室

服務端api

首先安裝socket.io提供的服務端npm包:

npm i socket.io

可以與 Express 框架配合使用:

const http = require('http')
const app = require('express')()
const server = http.createServer(app)
const io = require('socket.io')(server)
server.listen(3000)

也可以與 Koa 框架配合使用

const http = require('http')
const Koa = require('koa')
const app = new Koa()
const server = http.createServer(app.callback())
const io = require('socket.io')(server)
server.listen(3000)

使用起來就是這麼簡單。接下來就可以寫業務邏輯啦

io.on('connect', client => { // client 即是連接上來的一個客戶端
  console.log(client.id) // id 是區分客戶端的唯一標識

  client.on('disconnect', () => {}) // 客戶端斷開連接時調用(可能是關掉頁面,網絡不通了等)
})

connect 和 disconnect 是 socket.io 內置的事件類型,用於在客戶端連接和斷開的時候做一些事情。

在客戶端建立連接時需要把他們加入到一個房間里去,類似創建了一個聊天室

  console.log(client.id)
+ client.join('KPL') // 將客戶端加入到 KPL 房間內
  client.on('disconnect', () => {})

緊接着瑤進來秒發了首條消息:我打野,不給就送

服務器在收到這條振奮人心的消息后需要立即同步給其他四位隊友

  client.join('KPL')
+ client.on('talk', message => {
+   client.to('KPL').emit('talk', message) // 發送給房間里的每個人,除了發送者
+ })
  client.on('disconnect', () => {})

服務端的功能到這基本上就開發完了。創建了一個房間,並在收到成員消息時立即同步給房間里的其他成員

客戶端api

socket.io 為客戶端提供了另一個npm包,直接安裝

npm i socket.io-client

接下來就可以在頁面上建立到服務器的連接啦

import io from 'socket.io-client'

const socket = io() // 建立連接

向服務器發送消息

  const socket = io()
+ socket.emit('talk', '我打野,不給就送')

接收服務器發來的消息

  const socket = io()
+ socket.on('talk', message => {
+ })

李白看到了瑤的消息,強忍住問候對方家人的衝動,像哄那啥似地說道:

  socket.on('talk', message => {
+   socket.emit('talk', '你買個石頭騎在我頭上他不香么')
  })

客戶端的功能到這基本上也開發完了。核心api就是on和emit用於收發消息,既簡單又優雅。

最後

至此一個可以實時發送接收消息的聊天室就完成了,雖然簡陋,但核心功能完備。

瑤最終倔強地打了野,李白選擇了上路,3分鐘被對面捶到高地,后羿在家裡等鳥,呂布和貂蟬躲在藍buff旁邊的草叢里聊天,就這樣在李白和瑤互相拉票舉報對方的全局消息中遊戲結束

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7409

沐鳴首頁_碼農如何通過編程賺更多的錢

有很多機會可以將收入擴展到日常工作之外

成為程序員是一件很棒的事。 不僅大多數時候工作都很有趣,而且周圍有很多工作機會,而且大多數人的薪水都很高。

但是有時候,多花一些錢是值得讚賞的。 是因為您仍在上大學,還是想開始為自己而不是別人工作,您有一個孩子並想花更多的時間陪伴他們,您仍然需要賺錢或在做開發,就是圖個好玩兒。

這是一件好事:作為程序員,您擁有增加現金流量所需的一切。 您的大腦,您的筆記本電腦-這才是您真正需要的。 有興趣嗎?查看以下策略,並確定最適合您的策略。

開始自由職業

自由職業可能是一件好事。 沒有(真正的)老闆,可供選擇的項目很多,專家的日租金高,您想要的假期多……列表還在繼續。

但是,找到客戶和項目需要大量的紀律和精力。 對我來說,比較大的好處是您可以在晚上或周末在您的永久性工作旁邊開始自由職業。

像Upwork或Fiverr這樣的平台似乎提供了很多機會,尤其是在場邊做事,但要意識到那裡的競爭。

此外,費率非常低,因此,如果您只是想第一次將腳趾伸入水中,或者僅對少量額外收入感到滿意,我將不建議您這樣做。

更好的策略是使用您的LinkedIn個人資料,聯繫招聘人員和網絡中的過往客戶,參加會議和聚會,並尋找與遠程工作人員與公司相匹配的平台。

參加編程比賽

是的,這是真實的東西。 有專門的平台可以組織編程競賽,以獲得真正的獎金。

比較大的公司之一是擁有超過一百萬會員和眾多比賽的Topcoder。 它們具有三個主要重點領域:設計,數據科學和開發。

您將從事由2000多家公司發起的實際項目或與對手的一場比賽。 保證樂趣,快速學習也是如此。

如果您喜歡挑戰,這可能適合您。 但是,存在競爭,因此您不能指望穩定的收入流,因此請優先考慮這一點。

開始寫作

我認為,寫作仍然是吸引廣泛受眾的優秀方法之一。 您有很多機會開始寫作並從中賺錢:

  • 您可以創建自己的博客並通過廣告收入獲利。
  • 您可以編寫書籍或电子書,然後在線銷售。
  • 您可以在頭條等平台上撰寫文章,並參与其合作夥伴計劃。
  • 您可以為已建立的網站(如css-Tricks)撰寫來客帖子,如果您的文章被接受,則將向您支付固定金額。

嘗試並觀察人們對您所寫內容的反應並沒有錯。

但是,您應該考慮的事情是選擇對自己有特殊興趣的利基市場(保持积極性),保持一致的寫作(需要時間來獲得認可),並不斷提高寫作技巧以實現更高質量的文章(人們會感謝您,那裡有足夠多的低質量文章……)。

錄製和出售在線課程

在我看來,能夠在網上教人是過去十年來比較好的事情之一,而且至少可以持續十年。

對學生和老師的好處都是巨大的。 學生可以從多種產品中進行選擇,並按自己的時間表學習。 教師的內容可以觸及1000或100,000的人。

如果您具有編程經驗,最好是具有JavaScript或Python(或任何其他流行語言或框架)之類的語言的專業知識,甚至是利基滲透測試,並且您能夠並且樂於教別人,那麼創建在線課程可能就是您的事 。

有許多平台可用於發布您的課程。 例如,Udemy每月大約有7500萬遊客,任何人都可以加入。

Udemy traffic overview

其他平台(例如Frontend Masters或Pluralsight)僅應邀參加,但如果您有聲譽或良好的網絡,為什麼呢?

但是,錄製課程時需要注意以下幾點:

  • 購買優質裝備:必備麥克風和網絡攝像頭!
  • 高質量的內容為王。 競爭在穩步增長,因此您需要說服人們您可以教給他們有價值的東西。
  • 練習大聲而清晰地講話。
  • 務必重做您的錄音。
  • 創建其他材料,例如GitHub項目,演示文稿,編碼示例…

即使一門課程被記錄下來並且人們開始購買它似乎很吸引人,它也會為您創造被動收入,但這在一定程度上是正確的。 比較好的老師會不斷更新他們的課程,因為技術一直在變化!

開始成為技術主播

許多人不喜歡它在鏡頭前,但仍然是該領域的專家,並希望與他人分享他們的知識。

播客無疑是一個很好的媒介。 儘管他們已經存在了一段時間,但在過去的四到五年中,它們已經大受歡迎,吸引了成千上萬的人每天上下班或上床睡覺。

現在,大多數播客都可以自由收聽,因此金錢更多是一種副作用。 許多播客的節目贊助商都是用服務或金錢付費的。 許多播客都在Patreon上,該平台上的人們可以按月向他們付款以支持他們的工作並解鎖專有內容。

但是,為了成功播客,您應該能夠很好地表達自己的觀點,購買一些好的設備(麥克風),最重要的是,要有耐心不斷錄製情節。

人們必須先製作一兩年的每周情節,然後才能真正看到聽眾的進步,這種情況並不少見。

因此,如果您在執行此操作之前真的對此充滿熱情,那就太好了。

結論

我要告訴您的最後一件事與上述每個選項有關:

一致性為王。

無論您從什麼開始,都必須堅持下去。 大多數事情不會在一夜之間發揮作用。 這是艱苦的工作,您必須花費時間和精力。 99%的人放棄得太早。 躋身成功的1%之列!

原文 http://news.51cto.com/art/202002/609781.htm

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7406

沐鳴總代理_使用scss開發小程序(各種小程序平台通用)

微信小程序的wxss、阿里旗下淘寶、支付寶小程序的acss等等語法很類似原生css,但是在web開發里用慣了動態css語言,再寫回原生css很不習慣,尤其是父子樣式的嵌套寫法非常繁瑣。

因此,我希望能有一個自動化構建方案,能夠簡單地將scss轉換成小程序的樣式語言。

方案1

以前寫微信小程序的依賴庫時用過,使用gulp編譯,將源碼和編譯后的代碼分別放到src和dist兩個目錄。gulp會處理src下面的所有文件,將其中的scss轉換成css,並將其他所有文件原封不動挪到dist下相應位置。

這裏就不詳細說了,代碼參考Wux。

方案2

非常簡單直接,使用Webstorm/IDEA的File Watchers功能實時轉換。

安裝Ruby和sass

確保命令行輸入sass -v能出現版本號,安裝過程略。

安裝File Watchers

到插件市場上搜索並安裝(已安裝則跳過)

添加scss的轉換腳本

現在安裝完插件打開項目會自動彈出scss轉css的嚮導,方便了很多。但還需要做一些修改,配置如下:

首先要將生成文件的後綴名改掉,比如這裏我的淘寶小程序就得是acss。

其次,將Arguments改為:

$FileName$:$FileNameWithoutExtension$.acss --no-cache --sourcemap=none --default-encoding utf-8 --style expanded

如果不加–no-cache,scss文件同目錄下會出現一個.sass-cache目錄。

如果不加–sourcemap=none, scss文件同目錄下會出現一個.map文件。

如果不加–default-encoding utf-8, scss文件如果有中文註釋轉換就會報錯。

style可不加,這裏用的是無縮進和壓縮的風格,反正小程序打包發布時還會壓,這裏保持可讀性。

現在這個scss轉換是單獨作用於項目的,如果新建一個小程序項目,就需要重新添加(不建議設置成global,容易誤傷)。

注意到File Watchers列表的右側操作欄下方有導入導出按鈕,可以將現在配好的設置導出保存,將來新建項目時只要導入一下就行了。

之後還有一個問題,如果我手動將編譯后的css(即wxss或者acss,下略)文件刪除,scss文件不改動的話,就不會重新編譯出css文件。
或者萬一監聽失效或者不夠及時,css還有可能是舊的。
所以還需要一個命令,用來將整個目錄下的scss文件統一轉換,確保沒有遺漏和保持代碼最新。

不過我看了半天sass和sass-convert的文檔,沒有找到一個可用的寫法,能讓命令行遍歷指定目錄下的所有scss文件,將其轉換成css放到源文件所在目錄,並且將後綴名改為wxss或者acss。

所以遍歷這個行為只能交給nodejs來實現,代碼如下:

創建編譯腳本build/scss-convert.js:

var path = require("path")
var fs = require("fs")
const { exec } = require('child_process')

const basePath = path.resolve(__dirname, '../')

function mapDir(dir, callback, finish) {
  fs.readdir(dir, function(err, files) {
    if (err) {
      console.error(err)
      return
    }
    files.forEach((filename, index) => {
      let pathname = path.join(dir, filename)
      fs.stat(pathname, (err, stats) => { // 讀取文件信息
        if (err) {
          console.log('獲取文件stats失敗')
          return
        }
        if (stats.isDirectory()) {
          mapDir(pathname, callback, finish)
        } else if (stats.isFile()) {
          if (!['.scss'].includes(path.extname(pathname))) {
            return
          }
          callback(pathname)
        }
      })
      if (index === files.length - 1) {
        finish && finish()
      }
    })
  })
}

mapDir(
  basePath,
  function (file) {
    const newFileWithoutExt = path.basename(file, '.scss')
    if (newFileWithoutExt.startsWith('_')) {
      return  // 按照scss規則,下劃線開頭的文件不會生成css
    }
    // exec可以讓nodejs執行外部命令
    exec(`sass --no-cache --sourcemap=none --default-encoding utf-8 --style expanded ${file}:${newFileWithoutExt}.acss`, {
      cwd: path.dirname(file) // 不寫這個會導致生成的文件出現在根目錄
    }, (err, stdout, stderr) => {
      if (err) {
        console.log(err)
        return
      }
      console.log(`stdout: ${stdout}`)
    })
  },
  function() {
    // console.log('xxx文件目錄遍歷完了')
  }
)

在package.json里添加一條script:

  "scripts": {
    "scss": "node build/scss-convert",
  },

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/8856

沐鳴娛樂_如何利用 策略模式 優化表單驗證

背景

在做移動端項目開發的時候,經常會遇到各種表單驗證,有時候不同的頁面,驗證規則是一樣的 ,如圖

之前項目里的驗證代碼寫的很凌亂,最近剛好遇到這個模塊的功能需要重構,於是對代碼做了大量的優化,記錄一下如何利用策略模式優化表單驗證的

優化前

之前我們的驗證代碼是這樣寫的,把驗證func寫到一個公共模塊裏面,然後每個方法返回一個包含是否通過和message字段的對象

//common.js
export default {
  validateName: function (data, message = '', flag = false) {
    if (!/xxx/.test(data)) {
      message = '驗證不通過提示語'
    } else {
      flag = true
    }
    return {
      message,
      flag
    }
  },
  validatePhone: function (data, message = '') {},
  validateAddress: function (data, message = '') {}
}

然後在業務代碼裏面引用,這種不僅代碼量比較大,而且這種基礎驗證模塊和業務模塊耦合嚴重,我們應該盡量做到將不同模塊和功能代碼分離,提高代碼的可擴展性

優化后

如果驗證不通過,在基礎驗證代碼里立即彈出msg,業務代碼只需要判斷返回的是true或者false就行了

//common.js
export default {
  validateName: function (data, msg = '') {
    if (!/xxx/.test(data)) {
      msg = '驗證不通過提示語'
    }
    msg && alert(msg)
    return !!msg
  },
  validatePhone: function (data, msg = '') {},
  validateAddress: function (data, msg = '') {}
}

這樣業務代碼看上去很簡潔

//index.js
import validate from './common.js'
const keys = Object.keys(validate)
//通過some方法,有1個驗證不通過,就跳出驗證,然後主業務代碼里通過判斷validateResult的值,驗證是否完全通過。
//還有dataKey需要和validateKey有一定的映射規則
const validateResult = keys.some(key => {
  return !validate[key](this.data[dataKey])
})

如果你的驗證方法包含了很多本頁面用不到的其他驗證規則,你只需在業務代碼添加一個白名單字段

const whiteList = ['validatePhone','validateName','validateAddress']

如果你的驗證有先後順序,添加一個優先級字段

const whiteList = [{
    name:'validatePhone',
    level:1,
},{
    name:'validateName',
    level:2,
}]

以上就是我對錶單驗證規則的優化心得,有哪裡需要改進的希望大家可以指點出來,相互交流

原文:https://segmentfault.com/a/1190000021855553

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7951

沐鳴:_如何閱讀別人的代碼?

挺多人問過我“如何閱讀已有代碼”這個問題,希望我能有一個好的方法。有些人希望通過閱讀“優質項目”(比如 Linux 內核)得到啟發,改進自己的代碼質量。對於這個問題,我一般都不好回答,因為我很少從閱讀別人的代碼得到提升。每一次閱讀別人的代碼,對我來說都是一種折磨,而且每一次都不是別人的代碼提升了我,而是我提升了別人的代碼。

比起閱讀代碼,我更喜歡看別人的文章或者書。我喜歡他們跟我面對面的交流,用簡單的自然語言或者畫圖解釋他們的思想。有了思想,我自然知道如何把它變成代碼,而且是優雅的代碼。每一次參加學術會議,我都發現自己幾乎無法理解會議上的 talk 或者 paper。我會在 talk 結束之後的喝茶時間走到演講者面前,對他說:“你的 talk 很有意思,你能在三句話之內總結一下你說了什麼嗎?” 這樣交流之後,我忽然就懂了。

如果有同事請我幫他改進代碼,我不會拿起代碼埋頭看,因為我知道看代碼往往是沒用的。我會讓他們先在白板上給我解釋那些代碼是什麼意思。我的同事們都發現,把我講明白是很困難的。因為我的要求非常高,只要有一點不明白,我就會讓他們重新講。還得畫圖,我會讓他們反覆改進畫出來的圖,直到我能一眼看明白為止。如果圖形是 3D 的,我會讓他們給我壓縮成 2D 的,理解了之後再“推廣”到 3D。我無法理解複雜的,高維度的概念,他們必須把它給我變得很簡單。

所以跟我講代碼總是需要費很多時間,但這是值得的,因為我明白了之後,往往能挖出其他人都難以看清楚的要點。給我講解事情,也能提升他們自己的思維和語言能力,幫助他們簡化思想,甚至在忽然間發現改進他們自己代碼的方法。很多時候我根本沒看代碼,通過給我講解,後來他們自己就把代碼給簡化了。節省了我的腦力和視力,他們也得到了提高。

我最近一次看別人的代碼是在 Intel,我們改了 PyTorch 的代碼。那不是一次愉悅的經歷,因為雖然很多人覺得 PyTorch “好用”,它內部的代碼卻是非常晦澀,難以理解的。PyTorch 不是 Intel 自己的東西,所以沒有人可以給我講。修改 PyTorch 代碼,增加新功能的時候,我發現很難從代碼本身看明白應該改哪裡。後來我發現,原因在於 PyTorch 的編譯構架里自動生成了很多代碼,導致你無法理解那些代碼是怎麼來的。

比如他們有好幾個自己設計的文件格式,裏面有一些特殊的文本,決定了如何在編譯時生成代碼。你得理解這些文件裏面的內容在說什麼,而那不是任何已知的語言。這些文本文件被一些 Python 腳本讀進去,吐出來一些奇怪的 C++,CUDA,或者 Python 代碼。這其實是一種 DSL。我已經在之前的文章中解釋過 DSL 帶來的問題。所以要往 PyTorch 裏面加功能,你就得理解這些腳本是如何處理這些文本文件,生成代碼。而這些腳本寫得也比較混亂和草率,所以就是頭痛 2 ,頭痛的平方。

最後我發現,根本沒有辦法完全依靠這些代碼本身來理解它。那麼怎麼解決這個問題呢?幸好,網絡上有 PyTorch 的內部工程師寫了篇 blog ,解釋 PyTorch 如何組織代碼。Blog 的作者 E. Z. Yang 我見過一面,是在一次 PL 學術會議上。他當時在 MIT 讀書,貌似一個挺聰明的小伙子。不過看了這 blog 也只能初步知道它做了什麼,應該碰大概哪些文件,而這些每天都可能變化。

這篇 blog 還提到,某幾個目錄裏面是歷史遺留代碼,如果你不知道那是什麼,那麼請不要碰!看看那幾個目錄,裏面都是一些利用 C 語言的宏處理生成代碼的模板,而它使用 C 語言宏的方式還跟普通的用法不一樣。在我看來,所謂“宏”(macro)和 metaprogramming 本身就是一個巨大的誤區,而 PyTorch 對宏的用法還如此奇怪,自作聰明。

你以為看了這篇 blog 就能理解 PyTorch 代碼了嗎?不,仍然是每天各種碰壁。大量的經驗都來自折騰,碰壁,在黑暗中摸索。多個人同時在進行這些事情,然後分享自己的經驗。討論會內容經常是:“我發現要做這個,得在這個文件里加這個,然後在那個文件里加那個…… 然後好像就行了。” 下次開會又有人說:“我發現不是像你說的那樣,還得改這裏和這裏,而那裡不是關鍵……” 許多的知其然不知其所以然,盲人摸象,因為“所以然”已經被 PyTorch 原來的作者們掩蓋在一堆堆混亂的 DSL 下面了。

所以我從 PyTorch 的代碼裏面學到了什麼呢?什麼都沒有。我只看到各種軟件開發的誤區在反覆上演。如果他們在早期得到我的建議,根本不可能把代碼組織成這種樣子,不可能有這麼多的宏處理,代碼生成,DSL。PyTorch 之類的深度學習框架,本質上是某種簡單編程語言的解釋器,只不過這些語言寫出來的函數可以求導而已。而寫解釋器是我最在行的事情。

那麼我是怎麼成為現在這個樣子的呢?肯定有某種方法,對吧。我的方法很簡單,寫最短最精巧的代碼,從最薄最精悍的書或者課程裏面學,從真正的大師那裡學,而不是大型開源項目。

造就我今天的編程能力和洞察力的,不是幾百萬行的大型項目,而是小到幾行,幾十行之短的練習。不要小看了這些短小的代碼,它們就是編程最精髓的東西。反反覆復琢磨這些短小的代碼,不斷改進和提煉裏面的結構,磨礪自己的思維。逐漸的,你的認識水平就超越了所有這些幾百萬行,讓人頭痛的項目。

很多人都不知道,有一天我用不到一百行 Scheme 代碼就寫出了一個“深度學習框架”,它其實是一個小的編程語言。雖然沒有性能可言,沒有任何 GPU 加速,功能也不完善,但它抓住了 PyTorch 等大型框架的本質——用這個語言寫出來的函數能自動求導。這種洞察力才是最關鍵的東西,只要抓住了關鍵,細節都可以在需要的時候琢磨出來。幾十行代碼反覆琢磨,往往能幫助你看透上百萬行的項目里隱藏的秘密。

所以我如何閱讀別人的代碼呢?Don’t。除非我真的要使用那個項目的代碼,我才會去折騰它。

原文 http://www.yinwang.org/blog-cn/2020/02/05/how-to-read-code

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7434

沐鳴測速登錄地址_在線工具 – 程序員實用工具集

fly63實用工具箱是一款專為程序員、站長、運營等用戶打造的在線工具集,歡迎有需要的朋友使用和分享。記得ctrl+D收藏哦!

常用工具

1.js加密混淆、壓縮格式化工具

提供對js的排版(格式化),混淆,壓縮,加密等功能,加密方式包括:obfuscator不可逆加密、eval加密、aaencode加密、jjencode加密等

點擊進入

2.站長轉換工具

常用站長工具內容包括:Unicode編碼、UTF-8編碼、URL編碼/解碼、Unix時間戳、html編碼/解碼等

點擊進入

3.ICO圖標生成

可以將jpg、jpeg、gif、png等圖像轉換成ico圖像,方便網站使用,並提供ico圖標下載 

點擊進入

4.短鏈生成/還原工具

免費生成git.io、suo.im的短鏈。並支持短鏈還原

點擊進入

5.圖片格式轉換工具

工具支持轉換為webp、jpeg、png等格式的相互轉換

點擊進入

6.HTTP接口測試工具

模擬客戶端發送http請求,支持跨域,提供在線HTTP請求模擬器,支持請求類型有POST、GET、DELETE、PUT、PATCH請求,提供帶cookie和header的請求,返回header響應頭/請求頭等信息 

點擊進入 

在線轉換

圖片在線轉換Base64數據 圖片格式webp/png/jpeg轉換工具 Sass/Less/Stylus在線轉換工具 RGB/RGBA/HEX/HSL/HSV顏色在線轉換工具 免費快速將視頻轉換成Gif Html/MarkDown在線互轉工具 JSON/YAML在線轉換 PDF文件轉換圖片工具 下載鏈接轉換 SVG轉PNG工具 度量衡單位在線換算工具 Htaccess在線轉換nginx 進制轉換工具 人民幣大寫轉換工具 中文/Unicode在線轉換 在線中文漢字轉換拼音工具 簡體/繁體字轉換

加密解密

在線加密解密【Base64、AES、DES】 Js加密混淆/壓縮工具 DES在線加密解密 md5在線加密工具 隨機密碼生成工具

站長工具

免費在線智能AI文章偽原創工具 圖片主色調在線獲取工具 Markdown在線編輯器 佔位圖在線生成 站長常用轉換工具 圖片在線壓縮工具 Markdown微信公眾號排版編輯器 域名/IP地址查詢 自適應網頁多端預覽工具 meta標籤在線生成工具 圖片在線生成ICO圖標 电子郵箱網址大全 免費短鏈接生成工具

代碼開發

代碼在線編輯器IDE 在線js代碼生成工具 HTTP在線模擬測試工具 Diff在線文本比較工具 html轉js在線工具 uuid在線生成器 curl命令轉代碼 Javascript或HTML在線美化,格式化 正則表達式調試工具 HTML/CSS/Javascript在線代碼運行工具 原生json格式及高亮

css樣式

CSS三角形生成器 CSS3在線樣式生成器 CSS3 Flexbox 在線演示 CSS代碼美化工具 網頁顏色在線取色器 HTML5 標籤含義之元素周期表 Animate.css動畫演示 CSS按鈕生成器

二維碼相關

微信小程序二維碼生成工具 二維碼在線生成器 二維碼在線解碼工具

文檔手冊

ECMAScript 6 入門 npm 中文文檔 Node.js中文文檔 中文技術文檔的寫作規範 css在線參考手冊,並包含CSS2及CSS3大部分內容 Jquery在線參考手冊 JavaScript在線參考手冊 React.js 中文參考文檔

其他

毒雞湯語錄【娛樂】 經典語句大全【娛樂】 公曆農曆轉換查詢工具 手機號碼歸屬地查詢 在線生成流程圖、時序圖工具 在線文本去重複工具 文本替換工具 ASCII碼對照表 高端網站、小程序開發【推廣】 網址導航,上網從這裏開始 高端、高顏值視頻社交【推廣】 在線排版工具 科學計算器 房貸計算器
站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/9769

沐鳴主管:_Vuex映射

vuex 是一把雙刃劍。如果使用得當,使用 vue 可以使你的工作更加輕鬆。如果不小心,它也會使你的代碼混亂不堪。

使用 Vuex 之前,你應該先了解四個主要概念:state、getter、mutation 和 action。一個簡單的 Vuex 狀態在 store 中的這些概念中操作數據。 Vuex 中的映射提供了一種從中檢索數據的好方法。

在文中,我將演示如何映射 Vuex 存儲中的數據。如果你熟悉 Vuex 基礎,那麼這些內容將會幫你編寫更簡潔、更便於維護的代碼。

本文假設你了解 Vue.js 和 Vuex 的基礎知識。

Vuex 中的映射是什麼?

Vuex 中的映射使你可以將 state 中的任何一種屬性(state、getter、mutation 和 action)綁定到組件中的計算屬性,並直接使用 state 中的數據。

下面是一個簡單的 Vuex store 例子,其中測試數據位於 state 中。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    data: "test data"
  }
})

如果要從 state 中訪問 data 的值,則可以在 Vue.js 組件中執行以下操作。

computed: {
        getData(){
          return this.$store.state.data
        }
    }

上面的代碼可以工作,但是隨着 state 數據量的開始增長,很快就會變得很難看。

例如:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    user: {
        id:1,
        age:23,
        role:user
        data:{
          name:"user name",
          address:"user address"
        }
    },
    services: {},
    medical_requests: {},
    appointments: {},
    }
  }
})

要從處於 state 中的用戶對象獲取用戶名:

computed: {
        getUserName(){
          return this.$store.state.user.data.name
        }
    }

這樣可以完成工作,但是還有更好的方法。

映射 state

要將 state 映射到 Vue.js 組件中的計算屬性,可以運行以下命令。

import { mapGetters } from 'vuex';

export default{
    computed: {
        ...mapState([
            'user',
        ])
    }
}

現在你可以訪問組件中的整個用戶對象。

你還可以做更多的事,例如把對象從 state 添加到 mapState 方法。

import { mapGetters } from 'vuex';

export default{
    computed: {
        ...mapState([
            'user',
            'services'
        ])
    }
}

如你所見,這要乾淨得多。可以通過以下方式輕鬆訪問用戶名:

{{user.data.name}}

services 對象和映射的許多其他的值也是如此。

你注意到我們是如何將數組傳遞給 mapState() 的嗎?如果需要為值指定其他名稱,則可以傳入一個對象。

import { mapGetters } from 'vuex';

export default{
    computed: {
        ...mapState({
            userDetails:'user',
            userServices:'services'
        })
    }
}

現在可以通過簡單地調用 userDetails 來引用 user。

何時映射整個 state

根據經驗,僅當 state 中有大量數據,並且組件中全部需要它們時,才應該映射。

在上面的例子中,如果我們只需要一個值(例如 username),則映射整個用戶對象就沒有多大意義。

在映射時,整個對象將會全部加載到內存中。實際上我們並不想繼續把不需要的數據加載到內存中,因為這將是多餘的,並且從長遠來看會影響性能。

映射 getter

映射 getter 的語法與 mapState 函數相似。

import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters([
      'firstCount',
      'anotherGetter',
    ])
  }
}

與映射 state 類似,如果你打算使用其他名稱,則可以把對象傳遞給 mapGetters 函數。

import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters([
      first:'firstCount',
      another:'anotherGetter',
    ])
  }
}

映射 mutation

映射 Mutation 時,可以在用以下語法來提交 Mutation。

this.$store.commit('mutationName`)

例如:

import { mapMutations } from 'vuex'

export default {
  methods: {
    ...mapMutations([
      'search', // 映射 `this.increment()` 到 `this.$store.commit('search')`

      // `mapMutations` 也支持 payloads:
      'searchBy' // 映射 `this.incrementBy(amount)` 到 `this.$store.commit('searchBy', amount)`
    ]),
    ...mapMutations({
      find: 'search' // 映射 `this.add()` 到 `this.$store.commit('search')`
    })
  }
}

映射 action

映射 action 與映射 mutation 非常相似,因為它也可以在方法中完成。使用映射器會把 this.$store.dispatch(‘actionName’) 綁定到映射器數組中的名稱或對象的鍵。

import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 映射 `this.increment()` 到 `this.$store.dispatch('increment')`

      // `mapActions` 也支持 payloads:
      'incrementBy' // 映射 `this.incrementBy(amount)` 到 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 映射 `this.add()` 到 `this.$store.dispatch('increment')`
    })
  }
}

總結

看到這裏,你應該能夠學到:

  • 對 Vuex 中的映射是如何工作的以及為什麼要使用它有了深刻的了解
  • 能夠映射 Vuex store 中的所有組件(state、 getter、 mutation、action)
  • 知道什麼時候應該映射 store

原文:https://blog.logrocket.com/a-complete-guide-to-mapping-in-vuex/

    站長推薦

    1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

    2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

    鏈接: http://www.fly63.com/article/detial/9675

    沐鳴總代平台_CSS 高級布局技巧

    隨着 IE8 逐漸退出舞台,很多高級的 css 特性都已被瀏覽器原生支持,再不學下就要過時了。

    用 :empty 區分空元素

    兼容性:不支持 IE8

    假如我們有以上列表:

    <div class="item">a</div>
    <div class="item">b</div>
    <div class="item"></div>

    我們希望可以對空元素和非空元素區別處理,那麼有兩種方案。

    用 :empty 選擇空元素:

    .item:empty {
      display: none;
    }

    或者用 :not(:empty) 選擇非空元素:

    .item:not(:empty) {
      border: 1px solid #ccc;
      /* ... */
    }

    用 :*-Of-Type 選擇元素

    兼容性:不支持 IE8

    舉例說明。

    給第一個 p 段落加粗:

    p:first-of-type {
      font-weight: bold;
    }

    給最後一個 img 加邊框:

    img:last-of-type {
      border: 10px solid #ccc;
    }

    給無相連的 blockquote 加樣式:

    blockquote:only-of-type {
      border-left: 5px solid #ccc;
      padding-left: 2em;
    }

    讓奇數列的 p 段落先死紅色:

    p:nth-of-type(even) {
      color: red;
    }

    此外,:nth-of-type 還可以有其他類型的參數:

    /* 偶數個 */
    :nth-of-type(even)
    
    /* only 第三個 */
    :nth-of-type(3)
    
    /* 每第三個 */
    :nth-of-type(3n)
    
    /* 每第四加三個,即 3, 7, 11, ... */
    :nth-of-type(4n+3)

    用 calc 做流式布局

    兼容性:不支持 IE8

    左中右的流式布局:

    nav {
      position: fixed;
      left: 0;
      top: 0;
      width: 5rem;
      height: 100%;
    }
    
    aside {
      position: fixed;
      right: 0;
      top: 0;
      width: 20rem;
      height: 100%;
    }
    
    main {
      margin-left: 5rem;
      width: calc(100% - 25rem);
    }

    用 vw 和 vh 做全屏滾動效果

    兼容性:不支持 IE8

    vw 和 vh 是相對於 viewport 而言的,所以不會隨內容和布局的變化而變。

    section {
      width: 100vw;
      height: 100vh;
    
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
    
      background-size: cover;
      background-repeat: no-repeat;
      background-attachment: fixed;
    }
    
    section:nth-of-type(1) {
      background-image: url('https://unsplash.it/1024/683?image=1068');
    }
    section:nth-of-type(2) {
      background-image: url('https://unsplash.it/1024/683?image=1073');
    }
    section:nth-of-type(3) {
      background-image: url('https://unsplash.it/1024/683?image=1047');
    }
    section:nth-of-type(4) {
      background-image: url('https://unsplash.it/1024/683?image=1032');
    }
    
    body {
      margin: 0;
    }
    p {
      color: #fff;
      font-size: 100px;
      font-family: monospace;
    }

    用 unset 做 css Reset

    兼容性:不支持 IE

    body {
      color: red;
    }
    button {
      color: white;
      border: 1px solid #ccc;
    }
    
    /* 取消 section 中 button 的 color 設置 */
    section button {
      color: unset;
    }

    用 column 做響應式的列布局

    兼容性:不支持 IE9

    nav {
      column-count: 4;
      column-width: 150px;
      column-gap: 3rem;
      column-rule: 1px dashed #ccc;
      column-fill: auto;
    }
    
    h2 {
      column-span: all;
    }

    (完)

    站長推薦

    1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

    2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

    鏈接: http://www.fly63.com/article/detial/8898

    沐鳴平台首頁_匿名函數沒有自己的this

    匿名函數沒有自己的this,因此,在構造對象中調用全局函數時,可以省去保存臨時this,再將其傳入全局函數這一步: 

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>匿名函數的this</title>
    </head>
    <body>
    <script>
    const Tom = {
    name:'Tom',
    age:null,
    setAge: function () {
    let _this = this; // 將Tom保存在_this變量里
    setTimeout(function(){
    // 因為是在全局函數里,所以這裏的this是window
    console.log(this); // 輸出:window {parent: Window, opener: null, top: Window, length: 0, frames: Window, …}
    // 這裏的_this才是Tom,所以用_this才能調用Tom的age屬性
    _this.age = 15;
    console.log(_this) // 輸出: {name: "Tom", age: 15, setAge: ƒ}
    }, 1000);
    }
    };

    Tom.setAge();
    setTimeout(() => {
    console.log(Tom.age);
    }, 3000);

    const Rose = {
    name: 'Rose',
    age: null,
    setAge: function () {
    setTimeout(() => { // 匿名函數沒有this,因此匿名函數中的this是他所在函數的上一層,setTimeout()的上層是Rose
    // 因此這裏的this是Rose,可以調用Rose
    this.age = 16;
    console.log(this); // 輸出:{name: "Rose", age: 16, setAge: ƒ}
    }, 1000);
    }
    };

    Rose.setAge();
    setTimeout(() => {
    console.log(Rose.age);
    }, 3000);
    </script>
    </body>
    </html>

     

    站長推薦

    1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

    2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

    鏈接: http://www.fly63.com/article/detial/8885

    沐鳴下載_ES6中的解構賦值

    前言

    從前我們對變量賦值時,都是通過賦值運算符,右邊賦值給左邊這樣操作的。

    let a = 1;
    let b = 2;
    let c = 3;
    
    let obj = {};
    obj.name = 'mm';
    obj.age = 18;
    

    現在我們通過模式匹配的方式來賦值。
    左邊是解構目標,右邊是解構源。
    左右結構要保持一致。

    一、數組解構賦值:基本方式

    1.1 一一對應

    數組的解構是有順序的,是一一對應的。(等號右邊直接寫數組的變量名也可以。)

    let [a,b,c] = [1,2,3];
    console.log(a,b,c);
    
    let arr = [4,5,6];
    let [x,y,z] = arr;
    

    1.2 可嵌套

    只要右邊的模式和左邊相同,那麼左邊對應的變量就會被賦予對應的值。

    let [a,[b,[c,d]],e] = [1,[2,[3,4]],5];
    console.log(a,b,c,d,e);

    1.3 不完全解構

    如果右邊沒有給值,就當做undefined處理。

    let [a,b,c] = [1,2]; // let [a,b,c] = [1,2,undefined];

    1.4 可忽略

    let [a, , b] = [1,2,3];
    

    二、數組解構賦值:剩餘運算符

    2.1 定義

    語法:…變量名

    作用:可以將右邊數組中剩餘的值解構到左邊,而且是以
    數組的形式保存。

    let [a, ...b] = [1,2,3,4,5,6];
    console.log('a為:', a);
    console.log('b為:', b);

    2.2 注意

    剩餘運算符只能放在最後一個參數的位置上,否則報錯。

    let [...b, a] = [1,2,3];
    console.log(b);
    

    三、數組解構賦值:默認值

    3.1 規則

    指定默認值,默認值產生的條件是:右邊數組中對應的數據(====)嚴格等於undefined。

    例如下面,y=10就表示,y的默認值為10。

    let [x,y=10] = [1]; // let [x,y=10] = [1, undefined];
    console.log(x,y);

    3.2 特殊情況

    let [a=10, b=a] = []; // a=10,b=10
    let [a=10, b=a] = [1]; // a=1, b=1
    let [a=10, b=a] = [1,2]; // a=1, b=2
    let [a=b, b=20] = []; // 報錯(在用b之前還沒初始化值)
    

    分析:
    第一行:a和b匹配到undefined,所以採用默認值,a是10,b的值是a,也就是10;
    第二行:a匹配到1,b匹配到undefined,所以b的值就是a,也就是1;
    第三行:a和b均匹配到數值,因此a為1,b為2;(這裏b不會是默認給到a的值,因為它自己有匹配的值)
    第四行:a=b,但是b還沒有初始化,因此報錯。

    四、對象解構賦值:基本方式

    4.1 映射對應

    只有左邊對象的變量名和右邊對象的屬性名相同時,才會取到值。(等號右邊寫對象的變量名也可以。)

    let {a, b} = {a:'foo', b:'bar'}; // a='foo' b='bar'
    
    let obj = {
        name: 'mm',
        age: 18
    }
    let {name, age} = obj; // name='mm' age=18
    
    let {say} = {jump:'jump', sing:'sing'}; // say='undefined' (找不到對應的屬性名,那就給undefined)
    

    4.2 可嵌套

    let obj = {p: ['hello', {y: 'world'}] };
    let {p: [x, { y }] } = obj; // x='hello' y='world'
    

    左邊:p是一種模式匹配,真正解構的是後面的數組中的x和對象中的y。
    因此按照數組解構’hello’賦值給x,按照對象解構’world’賦值給y。
    那麼要想獲取對象中p的屬性值呢,直接寫p就行。

    let {p} = obj; // p=['hello', {y: 'world'}]
    

    4.3 不完全解構

    let {a,b,c} = {a:1,b:2}; // a=1 b=2 c=undefined
    

    4.4 可忽略

    let obj = {p: ['hello', {y: 'world'}] };
    let {p: [x, {  }] } = obj; // x='hello'
    

    五、對象解構賦值:剩餘運算符

    剩下的屬性以對象的形式保留。

    let {a, b, ...res} = {a:1, b:2, c:3, d:4, e:5}; // a=1 b=2 res={c:3, d:4, e:5}
    

    六、對象解構賦值:默認值

    指定默認值,默認值產生的條件是:對象屬性名(====)嚴格等於undefined。

    let {a,b=10,c} = {a:1}; // a=1 b=10 c=undefined
    let {x=3} = {x:undefined}; // x=3
    let {y=4} = {y:null}; // y=null
    

    七、對象解構賦值:易錯點

    對象的解構賦值的內部機制,是先找到同名屬性,然後再賦給對應的變量。真正被賦值的是後者,而不是前者。

    例如,等號左邊foo對應右邊的同名屬性是foo,它的值是’foo’,這個值最後賦值給foo對應的變量f而非foo。
    簡而言之,這個f和b相當於是一個別名

    let {foo:f, bar:b} = {foo:'foo', bar:'bar'}; // f='foo' b='bar'
    

    八、解構賦值的應用

    8.1 交換變量

    let x=1, y=2;
    [x, y] = [y, x];
    console.log(x,y); // 2 1
    

    8.2 接收返回值

    function foo() {
          return [1,2,3];
    }
    let [a,b,c] = foo();
    console.log(a,b,c); // 1 2 3
    
    function bar() {
          return {
                b1: 'bar1',
                b2: 'bar2'
          }
    }
    let {b1, b2} = bar();
    console.log(b1, b2); // 'bar1' 'bar2'
    

    8.3 獲取jsON數據

    var json = {
          name: 'mm',
          age: 18
    }
    let {name, age, say='暫無數據'} = json;
    console.log(name, age); // 'mm' 18 '暫無數據'
    

    8.4 獲取模塊數據

    導出模塊時用export,導入模塊時用import。

    模塊導出:(文件名為:module.js)

    let [a,b,c] = [1,'second',true];
    export {
        a,b,c
    }
    

    模塊導入:

    import {a,b,c} from './module.js';
    console.log(a,b,c); // 1,'second',true
    

    總結

    1. 等號左右結構和形式要對應;
    2. 數組解構賦值時,左邊變量的順序和右邊變量值的順序是一一對應的;對象結構賦值時,左右兩側的順序不重要,只要找到就行;
    3. 如果左邊沒有匹配到右邊的值,那麼當做undefined處理,把undefined賦值給左邊;
    4. 剩餘運算符要放在參數末尾的位置上,如果是數組,那麼會以數組的形式賦值給左邊的變量,如果是對象,則以對象形式賦值。
    5. 默認值生效的前提是,右邊對應數組位置或者對象屬性名的數據嚴格等於undefined。(===)
    6. 用途:ajax後台大量的json數據傳遞到瀏覽器客戶端,用解構賦值可以方便地獲取數據。
    7. 用途:功能模塊導入。

    站長推薦

    1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

    2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

    鏈接: http://www.fly63.com/article/detial/8890