Vue和Firebase構建翻版Google Keep(1)
Google Keep 是Google 谷歌官方發佈的一款雲筆記應用,它允許你方便的創建文章、圖片、語音筆記,並及時上傳到雲端進行保存,隨時隨地,你只需要登陸你的Google賬號便能夠查看。
在本教程中,您將學習如何使用Model-View-Viewmodel(MVVM)框架Vue和Firebase作為後端創建(最小化)Google Keep克隆應用程序。
源碼:需要源碼請留言聯繫方式!^_^
演示:https://gkeep-vueifire.firebaseapp.com/
Vue以組件的形式介紹了易於使用的構建塊。
每個組件都有自己的ViewModel,可以由其他組件組成。Vue與Angular的區別在於Vue具有較不陡峭的學習曲線。它更側重於提供一個簡單的方法來組成組件,而不是更多。
Firebase是谷歌雲中的實時NoSQL數據庫。Firebase提供Android,iOS,JavaScript甚至Angular的官方圖書館。使用Firebase可以快速構建實時應用程序!
對於本教程,您將需要ES6的一些經驗,也就是ES2015,Node和一些Vue。
您的設備上必須安裝NodeJS。
本教程中有兩種可能有幫助的工具:
Vue.js Devtools:該插件可讓您瀏覽組件樹,並觀察綁定到Chrome DevTools中的ViewModel的任何值
Vulcan by Firebase:Vulcan可以讓您探索DevTools中的數據,因此您無需調整數據而不需要切換選項卡
在這部分的最後,我們的應用程序將如下所示:
您可以在Github(tag part_1)找到源代碼,並在此播放演示文稿。
#設置
在全局安裝Vue命令行(Vue在編寫本版本時為1.0.18)
使用vue-cli創建一個項目(使用默認選項)
安裝包
運行dev服務器
當您訪問localhost:8080時,您應該看到以下屏幕:
#項目結構
index.html:根HTML文件。您的JavaScript和CSS將自動注入此文件
config.js:配置文件(您可以在此更改端口,將代理添加到代理到我們自己的API等)
build:包含運行和構建應用程序的節點文件('npm run dev'運行'node build / dev-server.js')
static:包含項目所需靜態資產的公用文件夾
test:用於您的單位,集成和測試
該應用的起始點是' src / main.js '。
當您使用這樣的應用程序組件<app></app>,它將替換與所提供的模板中的app元素App.vue。此外,JavaScript和樣式將自動注入到視圖中。目前,App組件在“ index.html ”中被引用。
使用.vue文件,您可以將HTML,CSS和JS全部寫入同一個文件。這使得使用組件心態很容易開發。
注意,您可以在腳本塊中編寫ES6代碼,而不用擔心瀏覽器兼容性!Webpack將使用Babel將ES6代碼編譯成ES5。您還可以添加任何其他裝載程序的支持,如TypeScript,CoffeeScript,Sass,Less等。
如果在創建項目時遵循默認值,則默認情況下將啟用eslint。這將迫使我們遵循標準代碼風格指南。一定要注意使用2個空格,不用分號!
#掛鉤火力地堡
通過npm安裝firebase。(在撰寫本文時,Firebase是2.4.2版,而我現在使用的是舊版控制檯)
導入Firebase在頂部main.js。
接下來,將Firebase應用程序鏈接傳遞給新的Firebase實例。
現在,您可以開始使用Firebase添加,修改和刪除數據。製作一個筆記數組,並添加一個筆記對象來測試它是否正常工作。
當您瀏覽瀏覽器時,應該會彈出一個“hello world”的彈出窗口。
您只需將Firebase連接到您的Vue應用程序。接下來是創建您的第一個組件!
#創建你的第一個組件
現在我們將創建一個組件來呈現所有的註釋。首先,創建一個新的文件夾“src / components / notes”以將所有筆記相關的組件放入。index.vue在剛創建的文件夾中創建一個文件,並將以下內容複製到該文件夾中。
src/components/notes/Index.vue
這是Vue組件的準系統。請注意,如果不需要,可以省略模板,腳本和樣式。索引組件將保存所有註釋。
首先,添加數據方法使Vue瞭解筆記數組。
src/components/notes/Index.vue
現在從main.js組件中刪除Firebase代碼並導入Firebase。創建一個新的Firebase實例,並在-method中監聽child_added您的筆記的ready-event。該child_added-event將首先遍歷所有現有的音符在陣列中,當有人增加了一個紙條給陣列也立即觸發。這意味著當有人添加了一個音符時,您將立即通過該事件通知您。
在回調中獲取數據,並使用unshift方法將其添加到notes數組中。而不是將元素推到數組的末尾,unshift將元素添加到開始。這樣可以確保顯示最新的音符。
src/components/notes/Index.vue
現在添加一個簡單的模板,以便在註釋上重複(v-for),並使用json 過濾器以JSON格式打印出數據。
src/components/notes/Index.vue
當我們檢查瀏覽器時,沒有區別。那是因為我們還沒有使用該組件。
使用notes元素替換App.vue div#app中的所有內容。
此外,導入Notes組件並將其傳遞給Vue實例的components屬性。(您可以刪除該Hello.vue文件)
src/components/App.vue
如果您現在重新加載瀏覽器,以前添加的註釋main.js將以JSON格式輸出。如果沒有出現音符,請嘗試在Firebase網站上手動添加音符。
#創建第二個更具吸引力的組件
現在,您可以渲染所有筆記,為單個筆記創建一個組件。
創建文件 src/components/notes/Note.vue
通過向props屬性添加字符串,可以為組件定義自定義屬性/屬性。
定義組件note的屬性。現在,您可以通過該屬性簡單地傳遞note對象note。
請注意,我們正在使用預標記而不是段落。預標記用於預格式化的文本。該標籤將會保留來自textarea的'\ t \ n'字符。雖然句子不會自動破壞,並且會溢出寬度。使用某些CSS,預標籤與其他元素具有相同的行為。
src/components/notes/Note.vue
html:(由於截圖放不下,上代碼)
<template>
<div class="note">
<h1>{{note.title}}</h1>
<pre>{{note.content}}</pre>
</div>
</template>
<script>
export default {
props: ['note']
// here you define the attributes/props of the component, will be available via this.note
// when using component you can use the prop externally via '<note :note"{title: 'hi', content: 'lorem'}" ></note>'
}
</script>
<style>
.note{
background: #fff;
border-radius: 2px;
box-shadow: 0 2px 5px #ccc;
padding: 10px;
width: 240px;
margin: 16px;
float: left;
}
.note h1{
font-size: 1.1em;
margin-bottom: 6px;
}
.note pre {
font-size: 1.1em;
margin-bottom: 10px;
white-space: pre-wrap;
word-wrap: break-word;
font-family: inherit;
}
</style>
現在src/components/notes/Index.vue,您需要更改模板以使用Note組件。在腳本中,您還需要導入Note組件並將其傳遞給組件對象。
src/components/notes/Index.vue
html:
<template>
<div class="notes">
<note
v-for="note in notes"
:note="note"
>
</note>
</div>
</template>
<script>
import Firebase from 'firebase'
import Note from './Note'
export default {
components: {
Note
},
…
}
</script>
<style>
.notes{
padding: 0 100px;
}
</style>
當您使用冒號的屬性前綴屬性屬性:note的內容將被解釋為JavaScript。這樣,您可以將註釋對象傳遞給註釋組件。
現在添加一些樣式到App組件src/App.vue。
src/components/App.vue
html:
<template>
<div>
<notes></notes>
</div>
</template>
<script>
import Notes from './components/notes/Index'
export default {
components: {
Notes
}
}
</script>
<style>
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
html{
font-family: sans-serif;
}
body{
background: #eee;
padding: 0 16px;
}
</style>
^_^ ^_^ ^_^------真棒!您只需將兩個組件嵌套到彼此中,將數據從父組件傳遞到子組件。
接下來是創建一個表單來創建新的筆記。
#創建添加註釋的表單
到目前為止,這可能並不奇怪,您將再次為此創建一個組件(組件截圖!)。
創建一個新文件: src/components/notes/Create.vue
在新的vue文件中,在模板中創建一個表單,並在“data”方法中返回具有兩個屬性(標題和內容)的對象。使用'v-model'指令將數據綁定到輸入和文本區域。
在methods對象中創建一個名為“createNote”的方法,並將其綁定到表單的submit-event。在方法內檢查是否填寫了標題或內容。如果是這樣,創建一個新的筆記,並通過Firebase將其推送到陣列。當筆記已成功推送到Firebase時,還會傳回一個回調來重置表單。
使用v-on:submit.prevent="createNote()"你可以在提交表單時觸發'createNote'方法。'.prevent'是可選的,並且將阻止默認的提交行為event.preventDefault()。
src/components/notes/Create.vue
html:
<template><form class="create-note" v-on:submit.prevent="createNote()">
<input name="title" v-model="title" placeholder="Title"/>
<textarea name="content" v-model="content" placeholder="Text goes here..." rows="3">
</textarea>
<button type="submit">+</button>
</form>
</template>
<script>
import Firebase from 'firebase'
let firebase = new Firebase('https://<YOUR-FIREBASE-APP>.firebaseio.com/')
export default {
data () {
return {
title: '',
content: ''
}
},
methods: {
createNote () {
if (this.title.trim() || this.content.trim()) {
firebase.child('notes').push({title: this.title, content: this.content}, (err) => {
if (err) {
throw err
}
this.title = ''
this.content = ''
})
}
}
}
}
</script>
<style>
form.create-note{
position: relative;
width: 480px;
margin: 15px auto;
background: #fff;
padding: 15px;
border-radius: 2px;
box-shadow: 0 1px 5px #ccc;
}
form.create-note input, form.create-note textarea{
width: 100%;
border: none;
padding: 4px;
outline: none;
font-size: 1.2em;
}
form.create-note button{
position: absolute;
right: 18px;
bottom: -18px;
background: #41b883;
color: #fff;
border: none;
border-radius: 50%;
width: 36px;
height: 36px;
box-shadow: 0 1px 3px rgba(0,0,0,0.3);
cursor: pointer;
outline: none;
}
</style>
現在不要忘記導入和使用組件App.vue。
現在,您可以添加備註,並且它們將自動通過-event插入child_added。
應用程序應該看起來像這樣。這些筆記是相互排列在一起的,因為float: left這並不總是看起來那麼好。這就是為什麼在下一節中,您將實施將處理佈局的Masonry-library。
#讓砌體處理佈局
砌體是一個偉大的圖書館,用於構建動態網格,將根據網格項的寬度動態佈局。
通過npm安裝“磚石佈局”。
現在在Notes組件中導入它。
添加v-el:notes屬性,div.notes以便您可以在Vue實例中引用它this.$els.notes。
當時磚石被實例化,沒有筆記,所以你需要告訴砌體,在“child_added”事件的回調中有新的項目,並且還要再次佈置筆記。
這不會直接在child_added-event 的回調中工作,因為在這一點上,新的音符不會被Vue渲染。nextTick在-event 上執行,類似於NodeJS的nextTick。在那裡,您可以確定新的筆記被渲染,並且Masonry將正確地佈置新的項目。為了確保所有的筆記都很好地居中,在初始化Masonry時,用padding替換填充margin: 0 auto; 並添加fitWidth: true選項。
src/components/Index.vue
html:
<template>
<div class="notes" v-el:notes>
<note
v-for="note in notes"
:note="note"
>
</note>
</div>
</template>
<script>
import Firebase from 'firebase'
import Masonry from 'masonry-layout'
import Note from './Note'
export default {
components: {
Note
},
data () {
return {
notes: []
}
},
ready () {
let masonry = new Masonry(this.$els.notes, {
itemSelector: '.note',
columnWidth: 240,
gutter: 16,
fitWidth: true
})
let firebase = new Firebase('https://<YOUR-FIREBASE-APP>.firebaseio.com/')
firebase.child('notes').on('child_added', (snapshot) => {
let note = snapshot.val()
this.notes.unshift(note)
this.$nextTick(() => { // the new note hasn't been rendered yet, but in the nextTick, it will be rendered
masonry.reloadItems()
masonry.layout()
})
})
}
}
</script>
<style>
.notes{
margin: 0 auto;
}
</style>
在Note組件中,我們可以刪除float: left;並更改邊距margin: 8px 0;。
src/components/notes/Note.vue
現在,Masonry很好地擺放了筆記,應用程序如下所示:
#構建和部署
構建項目進行生產(這將編譯所有內容並將應用程序放在dist文件夾中)
安裝Firebase命令行工具
初始化應用程序(確保輸入“dist”作為您的公用文件夾,並選擇正確的Firebase應用程序)
如果您以前沒有登錄,請登錄Firebase
部署應用程序
在線查看您的應用程序
#包起來
我們剛剛創建了一個類似於Google Keep with VueJS和Firebase的模擬筆記應用程序。
我們創建了一個包含各個筆記的Notes組件
我們創建了一個可視化個人筆記的組件
我們創建了另一個處理創建筆記的組件
我們將Masonry與Notes組件集成,以處理我們的筆記的佈局。
我們構建了我們的應用程序並將其部署到Firebase
不幸的是,還有很多缺失。到目前為止,該程序只覆蓋了CR一個的CRUD -應用。它仍然缺少UPDATE和DELETE。
在下一部分中,我將向您展示如何實現UPDATE和DELETE功能。我還將向您展示如何將我們的Firebase邏輯抽象到獨立的數據層,以保持我們的代碼為幹。目前,每個使用該應用程序的客戶端共享這個筆記列表。在下一部分中,我還將介紹身份驗證,併為每個用戶提供自己的筆記列表。
喜歡您就點贊關注,請收看下一集如何實現update和delete功能