亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Vuex + Firebase 構(gòu)建 Notes App

Invoker / 1841人閱讀

摘要:前幾天翻譯了基于這篇博客的文章用構(gòu)建一個(gè)筆記應(yīng)用。概述如果熟悉的使用,可以放心地跳過(guò)這一段。存的數(shù)據(jù)都是對(duì)象。修改的邏輯簡(jiǎn)單來(lái)說(shuō)就是在思路上要完成從數(shù)組到對(duì)象的轉(zhuǎn)換。把以上各條添加到里面。

前幾天翻譯了基于這篇博客的文章:用 Vuex 構(gòu)建一個(gè)筆記應(yīng)用。在此基礎(chǔ)上我對(duì)它做了一些更新:

把數(shù)據(jù)同步到 Firebase 上,不會(huì)每次關(guān)掉瀏覽器就丟失數(shù)據(jù)。

加了筆記檢索功能

為保證代碼整潔,加上了 eslint

你可以從 Github Repo 下載源碼,和 Firebase 的同步效果看下面這個(gè) gif:

一、把數(shù)據(jù)同步到 Firebase

可能你也知道 Vue.js 和 Firebase 合作搞出了一個(gè) Vuefire, 但是在這里并不能用它,因?yàn)橛?Vuex 管理數(shù)據(jù)的結(jié)果就是組件內(nèi)部只承擔(dān)基本的View層的職責(zé),而數(shù)據(jù)基本上都在 store 里面。所以我們只能把數(shù)據(jù)的存取放在 store 里面。

1.1 Firebase 概述

如果熟悉 Firebase 的使用,可以放心地跳過(guò)這一段。

如果你還沒(méi)有 Firebase 的賬號(hào),可以去注冊(cè)一個(gè),注冊(cè)號(hào)之后會(huì)自動(dòng)生成一個(gè)"MY FIRST APP",這個(gè)初始應(yīng)用給的地址就是用來(lái)存數(shù)據(jù)的地方。

Firebase 存的數(shù)據(jù)都是 JSON 對(duì)象。我們向 JSON 樹里面加數(shù)據(jù)的時(shí)候,這條數(shù)據(jù)就變成了 JSON 樹里的一個(gè)鍵。比方說(shuō),在/user/mchen下面加上widgets屬性之后,數(shù)據(jù)就變成了這個(gè)樣子:

{
  "users": {
    "mchen": {
      "friends": { "brinchen": true },
      "name": "Mary Chen",
      "widgets": { "one": true, "three": true }
    },
    "brinchen": { ... },
    "hmadi": { ... }
  }
}
創(chuàng)建數(shù)據(jù)引用

要讀寫數(shù)據(jù)庫(kù)里的數(shù)據(jù),首先要?jiǎng)?chuàng)建一個(gè)指向數(shù)據(jù)的引用,每個(gè)引用對(duì)應(yīng)一條 URL。要獲取其子元素,可以用child API, 也可以直接把子路徑加到 URL 上:

// referene 
new Firebase(https://docs-examples.firebaseio.com/web/data)

// 子路徑加到 URL 上
new Firebase("https://docs-examples.firebaseio.com/web/data/users/mchen/name")

// child API
rootRef.child("users/mchen/name")
Firebase 數(shù)據(jù)庫(kù)中的數(shù)組

Firebase 數(shù)據(jù)庫(kù)不能原生支持?jǐn)?shù)組。如果你存了一個(gè)數(shù)組,實(shí)際上是把它存儲(chǔ)為一個(gè)用數(shù)組作為鍵的對(duì)象:

// we send this
["hello", "world"]
// firebase database store this
{0: "hello", 1: "world"}
存儲(chǔ)數(shù)據(jù)
set()

set() 方法把新數(shù)據(jù)放到指定的引用的路徑下,代替那個(gè)路徑下原有的數(shù)據(jù)。它可以接收各種數(shù)據(jù)類型,如果參數(shù)是 null 的話就意味著刪掉這個(gè)路徑下的數(shù)據(jù)。

舉個(gè)例子:

// 新建一個(gè)博客的引用
var ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog")

var usersRef = ref.child("users")

usersRef.set({
  alanisawesome: {
  date_of_birth: "June 23, 1912",
  full_name: "Alan Turing"
  },
  gracehop: {
    date_of_birth: "December 9, 1906",
    full_name: "Grace Hopper"
  }
})

當(dāng)然,也可以直接在子路徑下存儲(chǔ)數(shù)據(jù):

usersRef.child("alanisawesome").set({
  date_of_birth: "June 23, 1912",
  full_name: "Alan Turing"
})

usersRef.child("gracehop").set({
  date_of_birth: "December 9, 1906",
  full_name: "Grace Hopper"
})

不同之處在于,由于分成了兩次操作,這種方式會(huì)觸發(fā)兩個(gè)事件。另外,如果usersRef下本來(lái)有數(shù)據(jù)的話,那么第一種方式就會(huì)覆蓋掉之前的數(shù)據(jù)。

update()

上面的set()對(duì)數(shù)據(jù)具有"破壞性",如果我們并不想改動(dòng)原來(lái)的數(shù)據(jù)的話,可能update()是更合適的選擇:

var hopperRef = userRef.child("gracehop")
hopperRef.update({
  "nickname": "Amazing Grace"
})

這段代碼會(huì)在 Grace 的資料下面加上 nickname 這一項(xiàng),如果我們用的是set()的話,那么full_namedate_of_birth就會(huì)被刪掉。

另外,我們還可以在多個(gè)路徑下同時(shí)做 update 操作:

usersRef.update({
  "alanisawesome/nickname": "Alan The Machine",
  "gracehop/nickname": "Amazing Grace"
})
push()

前面已經(jīng)提到了,由于數(shù)組索引不具有獨(dú)特性,F(xiàn)irebase 不提供對(duì)數(shù)組的支持,我們因此不得不轉(zhuǎn)而用對(duì)象來(lái)處理。

在 Firebase 里面,push方法會(huì)為每一個(gè)子元素根據(jù)時(shí)間戳生成一個(gè)唯一的 ID,這樣就能保證每個(gè)子元素的獨(dú)特性:

var postsRef = ref.child("posts")

// push 進(jìn)去的這個(gè)元素有了自己的路徑
var newPostRef = postsRef.push()

// 獲取 ID
var uniqueID = newPostRef.key()

// 為這個(gè)元素賦值
newPostRef.set({
  author: "gracehop",
  title: "Announcing COBOL, a New Programming language"
})

// 也可以把這兩個(gè)動(dòng)作合并
postsRef.push().set({
  author: "alanisawesome",
  title: "The Turing Machine"
})

最后生成的數(shù)據(jù)就是這樣的:

{
  "posts": {
    "-JRHTHaIs-jNPLXOQivY": {
      "author": "gracehop",
      "title": "Announcing COBOL, a New Programming Language"
    },
    "-JRHTHaKuITFIhnj02kE": {
      "author": "alanisawesome",
      "title": "The Turing Machine"
    }
  }
}

這篇博客聊到了這個(gè) ID 是怎么回事以及怎么生成的。

獲取數(shù)據(jù)

獲取 Firebase 數(shù)據(jù)庫(kù)里的數(shù)據(jù)是通過(guò)對(duì)數(shù)據(jù)引用添加一個(gè)異步的監(jiān)聽器來(lái)完成的。在數(shù)據(jù)初始化和每次數(shù)據(jù)變化的時(shí)候監(jiān)聽器就會(huì)觸發(fā)。value事件用來(lái)讀取在此時(shí)數(shù)據(jù)庫(kù)內(nèi)容的快照,在初始時(shí)觸發(fā)一次,然后每次變化的時(shí)候也會(huì)觸發(fā):

// Get a database reference to our posts
var ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts")

// Attach an asynchronous callback to read the data at our posts reference
ref.on("value", function(snapshot) {
  console.log(snapshot.val());
}, function (errorObject) {
  console.log("The read failed: " + errorObject.code);
});

簡(jiǎn)單起見(jiàn),我們只用了 value 事件,其他的事件就不介紹了。

1.2 Firebase 的數(shù)據(jù)處理方式對(duì)代碼的影響

開始寫代碼之前,我想搞清楚兩個(gè)問(wèn)題:

Firebase 是怎么管理數(shù)據(jù)的,它對(duì)組件的 View 有什么影響

用戶交互過(guò)程中是怎么和 Firebase 同步數(shù)據(jù)的

先看第一個(gè)問(wèn)題,這是我在 Firebase 上保存的 JSON 數(shù)據(jù):

{
  "notes" : {
    "-KGXQN4JVdopZO9SWDBw" : {
      "favorite" : true,
      "text" : "change"
    },
    "-KGXQN6oWiXcBe0a54cT" : {
      "favorite" : false,
      "text" : "a"
    },
    "-KGZgZBoJJQ-hl1i78aa" : {
      "favorite" : true,
      "text" : "little"
    },
    "-KGZhcfS2RD4W1eKuhAY" : {
      "favorite" : true,
      "text" : "bit"
    }
  }
}

這個(gè)亂碼一樣的東西是 Firebase 為了保證數(shù)據(jù)的獨(dú)特性而加上的。我們發(fā)現(xiàn)一個(gè)問(wèn)題,在此之前 notes 實(shí)際上是一個(gè)包含對(duì)象的數(shù)組:

[
  {
    favorite: true,
    text: "change"
  },
  {
    favorite: false,
    text: "a"
  },
    {
    favorite: true,
    text: "little"
  },
    {
    favorite: true,
    text: "bit"
  },
]

顯然,對(duì)數(shù)據(jù)的處理方式的變化使得渲染 notes 列表的組件,也就是 NotesList.vue 需要大幅修改。修改的邏輯簡(jiǎn)單來(lái)說(shuō)就是在思路上要完成從數(shù)組到對(duì)象的轉(zhuǎn)換。

舉個(gè)例子,之前 filteredNotes 是這么寫的:

filteredNotes () {
  if (this.show === "all"){
    return this.notes
  } else if (this.show === "favorites") {
    return this.notes.filter(note => note.favorite)
  }
}

現(xiàn)在的問(wèn)題就是,notes 不再是一個(gè)數(shù)組,而是一個(gè)對(duì)象,而對(duì)象是沒(méi)有 filter 方法的:

filteredNotes () {
  var favoriteNotes = {}
  if (this.show === "all") {
    return this.notes
  } else if (this.show === "favorites") {
    for (var note in this.notes) {
      if (this.notes[note]["favorite"]) {
        favoriteNotes[note] = this.notes[note]
      }
    }
    return favoriteNotes
  }
}

另外由于每個(gè)對(duì)象都對(duì)應(yīng)一個(gè)自己的 ID,所以我也在 state 里面加了一個(gè)activeKey用來(lái)表示當(dāng)前筆記的 ID,實(shí)際上現(xiàn)在我們?cè)?b>TOGGLE_FAVORITE,SET_ACTIVE這些方法里面都需要對(duì)相應(yīng)的activeKey賦值。

再看第二個(gè)問(wèn)題,要怎么和 Firebase 交互:

// store.js
let notesRef = new Firebase("https://crackling-inferno-296.firebaseio.com/notes")

const state = {
  notes: {},
  activeNote: {},
  activeKey: ""
}

// 初始化數(shù)據(jù),并且此后數(shù)據(jù)的變化都會(huì)反映到 View
notesRef.on("value", snapshot => {
  state.notes = snapshot.val()
})

// 每一個(gè)操作都需要同步到 Firebase
const mutations = {

  ADD_NOTE (state) {
    const newNote = {
      text: "New note",
      favorite: false
    }
    var addRef = notesRef.push()
    state.activeKey = addRef.key()
    addRef.set(newNote)
    state.activeNote = newNote
  },
  
  EDIT_NOTE (state, text) {
    notesRef.child(state.activeKey).update({
      "text": text
    })
  },

  DELETE_NOTE (state) {
    notesRef.child(state.activeKey).set(null)
  },

  TOGGLE_FAVORITE (state) {
    state.activeNote.favorite = !state.activeNote.favorite
    notesRef.child(state.activeKey).update({
      "favorite": state.activeNote.favorite
    })
  },

  SET_ACTIVE_NOTE (state, key, note) {
    state.activeNote = note
    state.activeKey = key
  }
}
二、筆記檢索功能

效果圖:

這個(gè)功能比較常見(jiàn),思路就是列表渲染 + 過(guò)濾器:

// NoteList.vue


// NoteList.vue

filters: {
  byTitle (notesToFilter, filterValue) {
    var filteredNotes = {}
    for (let note in notesToFilter) {
      if (notesToFilter[note]["text"].indexOf(filterValue) > -1) {
        filteredNotes[note] = notesToFilter[note]
      }
    }
    return filteredNotes
  }
}
三、在項(xiàng)目中用 eslint

如果你是個(gè) Vue 重度用戶,你應(yīng)該已經(jīng)用上 eslint-standard 了吧。

"eslint": "^2.0.0",
"eslint-config-standard": "^5.1.0",
"eslint-friendly-formatter": "^1.2.2",
"eslint-loader": "^1.3.0",
"eslint-plugin-html": "^1.3.0",
"eslint-plugin-promise": "^1.0.8",
"eslint-plugin-standard": "^1.3.2"

把以上各條添加到 devDependencies 里面。如果用了 vue-cli 的話, 那就不需要手動(dòng)配置 eslint 了。

// webpack.config.js
module: {
  preLoaders: [
    {
      test: /.vue$/,
      loader: "eslint"
    },
    {
      test: /.js$/,
      loader: "eslint"
    }
  ],
  loaders: [ ... ],
  eslint: {
    formatter: require("eslint-friendly-formatter")
  }
}

如果需要自定義規(guī)則的話,就在根目錄下新建.eslintrc,這是我的配置:

module.exports = {
  root: true,
  // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
  extends: "standard",
  // required to lint *.vue files
  plugins: [
    "html"
  ],
  // add your custom rules here
  "rules": {
    // allow paren-less arrow functions
    "arrow-parens": 0,
    "no-undef": 0,
    "one-var": 0,
    // allow debugger during development
    "no-debugger": process.env.NODE_ENV === "production" ? 2 : 0
  }
}
四、結(jié)語(yǔ)

講得比較粗糙,具體可以拿源碼跑一下。如果有什么問(wèn)題,歡迎評(píng)論。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/79360.html

相關(guān)文章

  • 學(xué)習(xí)實(shí)踐 - 收藏集 - 掘金

    摘要:官網(wǎng)地址聊天機(jī)器人插件開發(fā)實(shí)例教程一創(chuàng)建插件在系統(tǒng)技巧使你的更加專業(yè)前端掘金一個(gè)幫你提升技巧的收藏集。我會(huì)簡(jiǎn)單基于的簡(jiǎn)潔視頻播放器組件前端掘金使用和實(shí)現(xiàn)購(gòu)物車場(chǎng)景前端掘金本文是上篇文章的序章,一直想有機(jī)會(huì)再次實(shí)踐下。 2道面試題:輸入U(xiǎn)RL按回車&HTTP2 - 掘金通過(guò)幾輪面試,我發(fā)現(xiàn)真正那種問(wèn)答的技術(shù)面,寫一堆項(xiàng)目真不如去刷技術(shù)文章作用大,因此刷了一段時(shí)間的博客和掘金,整理下曾經(jīng)被...

    mikyou 評(píng)論0 收藏0
  • 使用 Vuex + Vue.js 構(gòu)建單頁(yè)應(yīng)用

    摘要:鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇下的使用方法,傳送門使用構(gòu)建單頁(yè)應(yīng)用新篇華麗的分割線原文地址前言在最近學(xué)習(xí)的時(shí)候,看到國(guó)外一篇講述了如何使用和來(lái)構(gòu)建一個(gè)簡(jiǎn)單筆記的單頁(yè)應(yīng)用的文章。 鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇 vue2.0 下的 vuex 使用方法,傳送門:使用 Vuex + Vue.js 構(gòu)建單頁(yè)應(yīng)用【新篇】 ---------...

    tomorrowwu 評(píng)論0 收藏0
  • 使用 Vuex + Vue.js 構(gòu)建單頁(yè)應(yīng)用

    摘要:鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇下的使用方法,傳送門使用構(gòu)建單頁(yè)應(yīng)用新篇華麗的分割線原文地址前言在最近學(xué)習(xí)的時(shí)候,看到國(guó)外一篇講述了如何使用和來(lái)構(gòu)建一個(gè)簡(jiǎn)單筆記的單頁(yè)應(yīng)用的文章。 鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇 vue2.0 下的 vuex 使用方法,傳送門:使用 Vuex + Vue.js 構(gòu)建單頁(yè)應(yīng)用【新篇】 ---------...

    cnsworder 評(píng)論0 收藏0
  • 使用 Vuex + Vue.js 構(gòu)建單頁(yè)應(yīng)用

    摘要:鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇下的使用方法,傳送門使用構(gòu)建單頁(yè)應(yīng)用新篇華麗的分割線原文地址前言在最近學(xué)習(xí)的時(shí)候,看到國(guó)外一篇講述了如何使用和來(lái)構(gòu)建一個(gè)簡(jiǎn)單筆記的單頁(yè)應(yīng)用的文章。 鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇 vue2.0 下的 vuex 使用方法,傳送門:使用 Vuex + Vue.js 構(gòu)建單頁(yè)應(yīng)用【新篇】 ---------...

    levius 評(píng)論0 收藏0
  • 使用 Vuex + Vue.js 構(gòu)建單頁(yè)應(yīng)用

    摘要:鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇下的使用方法,傳送門使用構(gòu)建單頁(yè)應(yīng)用新篇華麗的分割線原文地址前言在最近學(xué)習(xí)的時(shí)候,看到國(guó)外一篇講述了如何使用和來(lái)構(gòu)建一個(gè)簡(jiǎn)單筆記的單頁(yè)應(yīng)用的文章。 鑒于該篇文章閱讀量大,回復(fù)的同學(xué)也挺多的,特地抽空寫了一篇 vue2.0 下的 vuex 使用方法,傳送門:使用 Vuex + Vue.js 構(gòu)建單頁(yè)應(yīng)用【新篇】 ---------...

    UsherChen 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<