摘要:使用訪問后端服務使用的美化組件的方法整合全棧服務其中的指的是。所幸是在這個教程內,你不需要學習太多就可以把案例跑起來。另外一個組件負責顯示全部項目,并接受刪除事件,刪除指定的項目。它們分別是組件和組件這兩個組件的代碼實現,分別在文件和內。
自從一年前發布了Vuejs小書的電子書,也有些日子沒有碰過它們了,現在因為項目的緣故,需要使用JavaScript全棧開發。所以,我得把這個全棧環境搭建起來。
整個系列,是會采用我的一貫風格,就是不疾不徐,娓娓道來,學習完畢,你可以掌握我提到的全系列的知識,并且得到一個可以直接拷貝的代碼模板,并把它用到你的項目中。
完成操練下來,得半小時到一個小時吧。騰出你的時間再來學習。
前端的復雜度很多人是看不起JavaScript開發的。這玩意不就是玩具嘛,一些腳本和標簽而已。說這話的時候,他們可能是就翹起二郎腿的,或者抱著膀子的。
然而,前端因為還在快速發展,因此很多東西在變,構造環境的選擇比較多,技術種類也不少,很多事情得自己做。因此它其實并不比那么簡單的。這篇文章的圖,可以窺視到前端復雜的一角了。Modern Frontend Developer in 2018。
我看了不少資料,很多都是講解這張圖中的一個技術,講解全棧的肯定是有的,但是往往過于復雜。本文試圖通過一組文章,把JavaScript的全棧開發做一個全景的展示,力圖使用一個案例,全須全尾的貫穿整個系列,便于初學者對技術的急速理解。
大綱所以,文章會包括這些:
使用Vuejs腳手架,快速搭建一個CRD用戶界面。會使用vuex管理狀態,使用vue-router管理路由。
使用Mongodb存儲和提供后端CRD服務。
使用Nodejs搭建后端CRD服務。
使用Fecth|Axios訪問后端CRD服務
使用bulfy的美化組件的方法
整合全棧服務
其中的CRD指的是Create、Read、Delete。針對的數據對象,就是一個Todo對象,看起來是這樣的:
{id:1,subject:"Loving"}
如果是多個數據對象,看起來是這樣的:
[ {id:1,subject:"Loving"}, {id:1,subject:"Writing"}, {id:1,subject:"Preying"} ]
這個看起來很簡單平實的JS對象,會在一組組函數、模塊和對象之間流動,甚至跨越網絡邊界,從內存到硬盤。它會被存儲在Mongodb內,也會從Mongodb提取出來,在用戶界面、HTTP客戶端,HTTP服務器傳遞。
整個App看起來就是一臺機器,可以說代碼在運轉這個機器,但是也不妨說是數據在驅動這個它。
使用Vuejs腳手架,快速搭建Todo App界面我們給自己命題,做一個TODO應用,它看起來是這樣的:
用戶可以看到一個編輯框,和一個清單。
在編輯框內加入新的todo項目,按回車即可加入到列表
列表內每個項目有一個按鈕,點擊按鈕,可以刪除當前項目
環境要求說起來搭建JS全棧開發環境,涉及到的東西真的不少。大的選擇是這樣的:
前端采用Vuejs
后端采用Nodejs
存儲使用Mongodb。
大的選擇定了,小的配套也就跟著來,前端配套的話需要一系列的技術,特別是前端,對應著Vuejs,配套管理路由、狀態、組件的都有相應的技術手段。自己搭配的話,還是非常麻煩的。
幸好Vuejs還有一個前端腳手架工具vue-cli,它可以把以上的組件整合起來到一個工程內。一個最為基礎的vue-cli工程腳手架的創建,現在得需要160M左右的空間占用。在我的電腦和網絡情況下,需要2分半的時間才會完成。
前端 Vuejsvue-router,前端路由管理
vuex,前端數據管理,專業一點的說法,就是狀態管理,這些數據,可能是屬性,數組,對象等等,可以跨組件訪問,而不像是data函數那樣提供的數據只能被本組件訪問,可以想到,稍微大一點的前端工程都必須前端狀態管理的。
axios,前端HTTP訪問,以promise的形式,封裝了類似fetch,AJAX的能力
buefy,前端微型框架,可以使用自定義標簽使用自定義組件,并且CSS框架為Bulma
Bulma,盡管使用了微框架,只是讓對CSS framework的了解降到最低,但是不是說就不需要了解了。還是得學習的。Bulma相對于老牌的Bootstrap,是不需要依賴于JS框架,也沒有任何JS代碼,因此可以和任何一框架很好的結合,比如這里的Vuejs。這就是我選擇它的原因
后端 cli-service為了給前端開發提供工具鏈和開發便利性,我們常常需要webpack&babel。有了它們,就可以使用ES6的語法,以及代碼更新后自動刷新等。這些都是非常便利的特性,用了就離不開的。有了vue-cli,對webpack&babel的了解可以降到最低,但是也不能不學,稍微需要一些定制的配置,也是必須要掌握的,起碼得知道如何啟動一個開發服務器,已經發布build,還有把前端服務經過proxyChain跳轉到后端服務去等等。所幸是在這個教程內,你不需要學習太多就可以把案例跑起來。
App Server + Mongodb接下來看后端,一般習慣就是使用Nodejs+Express.js的搭配。這個沒有多少說的,都是老東西了。為了訪問Mongodb,也需要一套框架,基于Callback的,或者基于Promise+Await+Async的,也是需要選擇的。
為了便于理解,我會用一個最小的案例完成整個開發過程,就是案例在現實中并不存在,但是也是有用的,就是你可以當它們是模板,直接拷貝代碼,然后填充你的內容。天下代碼一大抄嘛,沒有什么不對的,畢竟這些寫代碼是最快的。這個案例的數據模型就是對一個{id,name}的對象進行CRD(創建刪除列表)。
安裝運行環境安裝環境相對簡單,特別是如果使用Mac OS X的話。有一些工具鏈可以幫助快速搭建環境。當然Windows也并不多麻煩就是了,它常常提供的是一個安裝程序,大部分時間,你需要的就是點擊下一步。
這里以MAC為例,講解安裝。
mongodb安裝和運行Mongodb Daemon:
brew install mongodb mongodb
訪問驗證,首先執行Mongodb Shell:
mongo
輸入命令,查詢數據庫清單:
> show dbs local 0.000GB
能夠看到這些信息,說明mongodb安裝成功。
Node.js安裝并驗證:
$brew install nodejs $node -v 10.7.0
能夠看到這些信息,說明Node.js安裝成功。
開始前端編碼 安裝編碼環境首先安裝vue-cli,方法和一般的NPM模塊一樣的,我們安裝的版本是3.0:
npm i @vue/cli
查看版本:
vue -V 3.0.0
看到如下信息,說明成功。然后創建App的腳手架代碼:
vue create todoapp
注意,在此創建過程中,命令行會指示你做出選擇,我們會選擇Manual select feature,然后選擇router和vuex,其他不選。然后并執行此代碼:
cd todoapp npm run serve
可以在瀏覽器中訪問localhost:8080看到Vue的啟動畫面。說明創建腳手架成功。
此時,vue-cli已經幫助安裝了vuex和router的模塊依賴。本節一次性的安裝全部剩余的全部NPM依賴,免得以后用一個安裝一個,麻煩而且啰嗦。
npm install buefy --save npm install axios --save
buefy是一個基于Bulma的Vuejs用戶界面組件庫。這次的UI的CSS方案,使用Bulma,Vuejs如果想要以定制組件的形式去使用它的話,那么需要安裝Buefy模塊。實際上,我研究過Bulma和Bootstrap,還寫了一本免費的電子書,我覺得Bulma相對于Bootstrap的優勢在于1.不依賴任何JS框架2.用戶接口設計更加簡明。這就是我現在選擇使用Bulma的原因。
Axios是一個封裝了HTTPClient的庫,提供了promise接口。我們使用它訪問后端的HTTP Server的數據。之前提到的數據對象,就是由Axios提取到客戶端,也會是通過Axios把數據對象提交到服務器的。
前端編碼首先,我們從狀態開始。我們之前提到的Vuex,是Vuejs管理狀態的官方插件。所謂的狀態,就是應用程序的數據對象們。也就是我們提到的Todo對象和Todo對象集合。我們在App用戶界面上看到的很多數據都是來自于狀態對象。狀態對象在src/store.js。不僅僅是的應用狀態信息,還有和對這些的操作函數。既然需要一個todo項目清單,因此應該加入如下代碼:
import Vue from "vue" import Vuex from "vuex" Vue.use(Vuex) const defaultTodo = [ {id:1,subject:"Eating"}, {id:2,subject:"Loving"}, {id:3,subject:"Preying"}, ] function indexById(todos,id){ for (var i = 0; i < todos.length; i++) { if (id == todos[i].id) return i } return -1 } import axios from "axios" export default new Vuex.Store({ state: { msg:"Todo App", todos:defaultTodo }, mutations: { add(state,subject){ var todo = {id:subject,subject:subject} state.todos.push(todo) }, remove(state,id){ state.todos.splice(indexById(state.todos,id),1) }, reload(state){ state.todos = defaultTodo } }, actions: { add: (context, link) => { context.commit("add", link) }, remove: (context, link) => { context.commit("remove", link) }, reload: (context) => { context.commit("reload") } } })
其中的state.todos屬性,就是我們的主要的數據對象了。state.msg這是提供了一個App的標題字符串。mutations屬性內是對數據修改提供的方法,比如
我們需要添加一個todo,使用add()方法,相應的
刪除一個todo,使用remove()方法
刷新一個todo列表,就會使用load()方法
有時候,對數據的修改可能是比較消耗時間的,因此為了避免阻塞客戶端的主線程,這個對象也提供了異步的方法,actions對象內就是對應修改操作的異步方法,這里的方法功能上和mutations一致,但是是異步的。Vuex提供了類似:
context.commit()
的語法,提供和actions和mutations方法的對接。第一個參數是mutations的方法名稱,之后的參數最為mutations方法的參數傳遞給mutations方法。
特別說下,mutations內的add()方法,其中用戶界面會提供一個Todo.subject屬性,而ID是需要自動生成的,我們這里臨時使用subject的值作為id,就是一個偷懶,只要subject不要輸入重復,也暫時可以蒙混過關。因為知道本項目內的后臺存儲會采用Mongodb,在Mongodb內插入一個新的對象后,會自動生成一個ID,我們的Todo對象的id會采用這個ID。這里就沒有必要自己生成了。
在src/views/home.vue內,粘貼為如下代碼:
{{msg}}
...mapState,mapActions的解說。
就是說,我們這個Todo App劃分為為兩個組件,其中一個組件負責顯示編輯框,并接受回車事件,把新的Todo項目加入到應用狀態內。另外一個組件負責顯示全部Todo項目,并接受刪除事件,刪除指定的Todo項目。它們分別是NewTodo組件和TodoList組件:
這兩個組件的代碼實現,分別在文件src/components/NewTodo.vue和src/components/TodoList.vue內。NewTodo代碼:
TodoList代碼:
- {{todo.subject}}
在src/main.js文件內,添加如下代碼,引入Buefy:
import Buefy from "buefy" import "buefy/lib/buefy.css" Vue.use(Buefy)
現在可以使用Buefy組件了。我們可以把NewTodo組件內的標準的input變成組件化的input,把標簽換成b-input即可。代碼如下:
現在看瀏覽器,input變成了比較有吸引力的Bulma風格的控件了。
訪問網絡使用axios。需要首先找到src/home.vue在代碼的開頭部分引用此庫:
import axios from "axios"
在Vue單頁組件內使用此庫了。比如在src/home.vue內代碼對象中加入新方法:
mounted(){ var url = "https://api.coindesk.com/v1/bpi/currentprice.json" axios ({ url:url, method: "get", }) .then( res => {console.log(res.data.chartName)} ) .catch( err => cosole.error(err)) }
我們來看看適應效果。啟動cli-service:
npm run serve
然后打開瀏覽器,輸入地址localhost:8080,如果可以在瀏覽器內看到我們期望的用戶界面,并且都可以看到console打印了Bitcoin,那么就說明用戶界面代碼和初步的訪問HTTP網絡的axios代碼以及狀態管理功能都是成功了的。
后端編碼現在,我們已經可以看到UI了,但是用戶界面內的數據來自于客戶端,而不是來自于服務器。我們的數據當然應該來源于服務器的了。因此我們需要啟動給一個自己的服務器,這個服務器可以接受客戶在界面上錄入的新的Todo對象,也可以提供后端數據庫內的Todo清單。
為了測試的目的,常常需要準備一個todo應用的后臺JSON服務,可以通過HTTP方式,提供todo項目的增加刪除修改和查詢。
這樣的服務器,使用了nodejs作為服務器端,并且使用了兩個node模塊,可以使用npm安裝它們:
npm install express body-parser
body-parser是一個中間件,可以解析請求內容并把解析結果放到req.body屬性內。最常見的做法就是解析json內容。
代碼如下(文件名為:jsonserver.js):
var express = require("express"); var app = express(); var path = require("path") var bodyParser = require("body-parser") app.use(bodyParser.json()) var todos = [] var public = path.join(__dirname, "/") app.use("/",express.static(public)) const defaultTodo = [ {id:1,subject:"Eating"}, {id:2,subject:"Loving"}, {id:3,subject:"Preying"}, ] function rs(){ todos = defaultTodo } function indexById(id){ for (var i = 0; i < todos.length; i++) { if (id ==todos[i].id)return i } return -1 } rs() app.delete("/api/todo/:id", function (req, res) { var userkey = +req.params.id todos.splice(indexById(userkey),1) res.end( JSON.stringify(todos)); rs() }) app.get("/api/todos", function (req, res) { res.end( JSON.stringify(todos)); }) app.post("/api/todo", function (req, res) { todos.push(req.body) res.end(JSON.stringify(todos)) rs() }) var server = app.listen(8081, function () { var host = server.address().address var port = server.address().port console.log("listening at http://%s:%s", host, port) })
可以使用命令執行:
node jsonserver.js
Curl命令驗證可以通過curl命令驗證服務的有效性:
GET操作
$curl http://localhost:8081/todo/1 $curl http://localhost:8081/todos
DELETE操作
$ curl -X "DELETE" http://localhost:8081/api/todo/1
POST操作
$curl -X POST -H "Content-Type: application/json" -d "{"subject":"s4"}" http://localhost:8081/api/todo前端HTML驗證
創建一個index.html文件,并放置到和jsonserver.js代碼同一目錄,代碼如下:
todos todo/1
可以提供創建,刪除,列表的測試,其中部分結果在console內顯示。
說起來,JS訪問HTTP的庫真的是不少,這里 提到的庫都有9種。其中的fetch api使用起來非常的簡潔趁手,可是它不支持IE。如果你需要支持IE的話,使用Axios更好。這就是為什么Vuejs官方推薦Axios的原因吧:
The Fetch API is a powerful native API for these types of requests. You may have heard that one of the benefits of the Fetch API is that you don’t need to load an external resource in order to use it, which is true! Except… that it’s not fully supported yet, so you will still need to use a polyfill. There are also some gotchas when working with this API, which is why many prefer to use axios for now. This may very well change in the future though.axios訪問方法
相比fetch,使用axios必須依賴于外部文件。為了方便,我們直接使用unpkg網站提供的庫文件。
axios的語法和fetch的大同小異,看著也是比較簡潔美觀的。以下代碼,把create和remove函數的內部實現換掉,其他不變。
todos todo/1
現在,后端也是可以跑起來了的。
整合:前端后端 建立cli-service到App Server的通道每次執行命令:npm run serve,都會啟動vue定制腳手架的服務器代碼,它會提供不少方便開發的特性。但是我希望一部分URL可以轉發到我自己的服務器內。比如把所有的/api打頭的URL全部轉過來。只要在工程根目錄內加入此文件vue.config.js,錄入如下內容:
module.exports = { devServer: { proxy: { "/api": { target: "http://localhost:8181", secure: false } } } };
我們自己的測試服務器在這里:
var http = require("http"); http.createServer(function (req, res) { res.write("Hello World!"); res.end(); }).listen(8181);
我們的定制服務器,就可以監聽8181的本地機器端口,等待客戶端的匹配的URL轉發過來,并轉發我們服務器的響應代碼到客戶端。
但是正常開發過程中,是需要自己的服務器端代碼的,如何在利用Vue腳手架服務器的方便性的基礎上,加入自己的代碼呢。做法是另外做一個定制的服務器,然后讓vue定制腳手架的服務器轉發URL到此服務器。
為了測試的目的,我們把函數mounted修改為:
mounted(){ var url = "/api/1" axios ({ url:url, method: "get", }) .then( res => {console.log(res.data)} ) .catch( err => console.error(err)) }
即可看到瀏覽器console內打印Hello World!。
整合前端到后端我們已經通過配置,要求cli-service轉移全部api打頭的URL到App Server。只要在工程根目錄內加入此文件vue.config.js,錄入如下內容:
module.exports = { devServer: { proxy: { "/api/*": { target: "http://localhost:8181/api", secure: false } } } };
現在,我們可以修改前端的Axios使用代碼,分別替代前端代碼的數據裝入、數據刪除、數據添加的代碼,讓這些代碼可以支持網絡操作。為了避免網絡操作代碼和業務邏輯代碼混合在一起,我決定包裝三個網絡操作函數,并把它們放置到src/store.js文件內:
import axios from "axios" function httpadd(subject,cb){ axios ({ method: "POST", url:"/api/todo", headers:[{"Content-Type":"application/json"}], data: {subject:subject} }) .then( res => cb(res.data)) .catch( err => console.error(err)) } function httpremove(id,cb){ axios ({ url:"/api/todo/"+id, method: "delete", }) .then( res => { cb() }) .catch( err => console.error(err)) } function httpreload(cb){ axios ({ url:"/api/todos", method: "get", }) .then( res => { cb(res.data) }) .catch( err => console.error(err)) }
分別完成添加、刪除、查找的任務,當完成工作后,都會調用一個callback函數,在此函數內,可以消費訪問網絡后得到的響應數據。
然后把文件內src/store.js的mutations對象改成如下代碼:
mutations: { add(state,subject){ httpadd(subject,function(todo){ state.todos.push(todo) }) }, remove(state,id){ httpremove(id,function(){ state.todos.splice(indexById(state.todos,id),1) }) }, reload(state){ httpreload(function(todos){ // console.log(todos) state.todos = todos }) // state.todos = defaultTodo } },
最后,在TodoList內加入一個新函數,并通過mapActions引入src/store.js的load()函數到當前對象內:
methods:{ ...mapActions([ "remove","load" ]) }, mounted(){ this.load() }
以便在啟動后調用this.load()裝入它。
整合:后端和數據庫要完成后端到數據庫的整合,需要做如下的修改:
原本在后端App Server內Todo數據數組,現在應該從Mongodb獲得
原本在添加Todo對象的時候只是添加到AppServer對象內,現在需要同時寫入Mongodb
原本在刪除時只是從數組刪除,現在需要同時在Mongodb內刪除
因此,現在我們需要添加三個函數,分別做針對Mongodb的獲取清單、添加和刪除的工作:
var mongo = require("mongodb") function insertDoc(subject,callback){ const connectionString = "mongodb://localhost:27017"; (async () => { const client = await MongoClient.connect(connectionString, { useNewUrlParser: true }); const dbo = client.db("todos"); try { var res = await dbo.collection("todo").insertOne( {subject:subject}) callback(undefined,res.insertedId) } catch(err){ callback(err) } finally { client.close(); } })().catch(err => console.error(err)); } function deleteDoc(_id,callback){ const MongoClient = mongo.MongoClient; const connectionString = "mongodb://localhost:27017"; (async () => { const client = await MongoClient.connect(connectionString, { useNewUrlParser: true }); const dbo = client.db("todos"); try { var myquery = {_id:new mongo.ObjectID(_id)} var r = await dbo.collection("todo").deleteMany(myquery) } catch(err){ callback(err) } finally { client.close(); callback() } })().catch(err => console.error(err)); } function allDoc(callback){ const MongoClient = mongo.MongoClient; const connectionString = "mongodb://localhost:27017"; (async () => { const client = await MongoClient.connect(connectionString, { useNewUrlParser: true }); const dbo = client.db("todos"); try { var r = await dbo.collection("todo").find().toArray() var ts = [] for (var i = 0; i < r.length; i++) { ts.push({id:r[i]._id,subject:r[i].subject}) } callback(undefined,ts) } catch(err){ callback(err) } finally { client.close(); } })().catch(err => console.error(err)); }
這三個函數的功能和使用方法如下:
函數allDoc會從Mongodb內獲取全部todo集合,并通過callback傳遞這個集合給調用者函數。
函數deleteDoc會從Mongodb內刪除指定id的todo條目,完成刪除后,通過callback通知調用者。
函數deleteDoc會向Mongodb內添加一個todo條目,完成添加后,通過callback通知調用者,并傳遞新的todo對象給調用者。
這里的代碼本身并不復雜,但是因為涉及到如何訪問Mongodb,因此涉及到比較多的概念,這里不做具體的解釋,你可以先把它們用起來。如果完成了本教程后,希望對Mongodb的訪問做具體了解的話,可以查看后文附錄的“Mongodb快速參考”。
并且和App Server對應的代碼接駁,把原來的路由代碼替換如下:
app.delete("/api/todo/:id", function (req, res) { var userkey = req.params.id deleteDoc(userkey,function(){ todos.splice(indexById(userkey),1) res.end( JSON.stringify(todos)); }) }) app.get("/api/todos", function (req, res) { allDoc(function(err,todos){ res.end( JSON.stringify(todos)); }) }) app.post("/api/todo", function (req, res) { insertDoc(req.body.subject,function(err,_id){ var obj ={id:_id,subject:req.body.subject} todos.push(obj) res.end(JSON.stringify(obj)) rs() }) })Mongodb快速參考
本文會把一個對象todo對象(有屬性{id,name})存儲到Mongodb,做查詢刪除的測試(Create Remove Delete = CRD)。這個測試包括使用Mongodb Shell,使用CallBack古典風格的訪問代碼,以及使用Await/Async的現代風格的代碼。完成這個這個驗證后,就可以掌握最初步的Mongodb了。
我使用的Nodejs是10.7 。操作系統環境為Mac OS X High Sierra。
準備環境安裝和運行Mongodb Daemon
brew install mongodb mongodb訪問驗證
首先執行Mongodb Shell:
mongo
輸入命令,查詢數據庫清單:
> show dbs local 0.000GB
創建一個數據庫
use todos
(若database不存在,則會創建一個,此時若不做任何操作直接退出,則MongoDB會刪除該數據庫)
db.todos.insert({id:1,name:"reco"}) db.todos.insert({id:2,name:"rita"})
查詢 :
db.todos.find() { "_id" : ObjectId("5b727c0846b6c71a98d3af52"), "id" : 1, "name" : "reco" } { "_id" : ObjectId("5b727c7046b6c71a98d3af53"), "id" : 2, "name" : "reta" }
刪除記錄:
db.todo.remove({id:1})
刪除數據庫
db.todo.drop()使用nodejs方式訪問Mongodb
使用nodejs執行類似Shell對對象的CRD,代碼如下:
var MongoClient = require("mongodb").MongoClient; var url = "mongodb://localhost:27017/todos"; MongoClient.connect(url, function(err, db) { if (err) throw err; console.log("Database created!"); var dbo = db.db("todos"); // var myobj = { id: 1, name: "reco" }; // dbo.collection("todo").insertOne(myobj, function(err, res) { // if (err) throw err; // console.log("1 document inserted"); // db.close(); // }); var myobj = [ { id: 1, name: "reco"}, { id: 2, name: "rita"}, ]; dbo.collection("todo").insertMany(myobj, function(err, res) { if (err) throw err; console.log("Number of documents inserted: " + res.insertedCount); dbo.collection("todo").find({}).toArray(function(err, result) { if (err) throw err; console.log(result); var myquery = { id: 1 }; dbo.collection("todo").deleteMany(myquery, function(err, obj) { if (err) throw err; console.log("document deleted"); db.close(); }); }); }); })
代碼非常簡單,無需更多解釋。此代碼使用了mongodb模塊,需要首先安裝:
npm init -y npm i mongodb --save
然后使用node index.js運行即可看到效果:
Database created! Number of documents inserted: 2 [ { _id: 5b72ab9e3245f169ef5f43d2, id: 1, name: "reco" }, { _id: 5b72ab9e3245f169ef5f43d3, id: 2, name: "rita" } ] document deleted利用高級異步特性
使用Await/Async特性,可以有效的減少代碼中的回調地獄現象。同樣的功能,可以使用這樣的代碼:
const MongoClient = require("mongodb").MongoClient; const connectionString = "mongodb://localhost:27017"; (async () => { const client = await MongoClient.connect(connectionString, { useNewUrlParser: true }); const dbo = client.db("todos"); try { var res = await dbo.collection("todo").insertMany( [{id:1,name:"reco"}, {id:2,name:"rita"}]); console.log("Number of documents inserted: " + res.insertedCount); var r = await dbo.collection("todo").find().toArray() console.log(r); var myquery = { id: 1 }; var r = await dbo.collection("todo").deleteMany(myquery) console.log("document deleted"); } finally { client.close(); } })().catch(err => console.error(err));
執行此代碼,輸出如下:
Number of documents inserted: 2 [ { _id: 5b72ae8a1c674a6ac1c5aa6e, id: 1, name: "reco" }, { _id: 5b72ae8a1c674a6ac1c5aa6f, id: 2, name: "rita" } ] document deletedVuejs快速參考
Vuejs本身要學的還真不少,這也是我會編寫一本書來介紹它的原因。但是說到入門的話,我倒是寫過一篇簡單的介紹文章。不妨去閱讀看看。
上面的文章,也就對Vuejs了解個大概,提起一個興趣。如果真的想要學習Vuejs的話,還是得看書的。這里也放一個我的書的廣告,歡迎參閱。
購買
問題索引麻雀雖小五臟俱全,雖然是一個小小的示例的應用,但是每樣技術也都需要用到,遇到的技術問題也是要一個個的解決的。這里列出我遇到的問題,作為索引,也算記錄我在寫作過程中解決的問題,也可以作為你學習完畢后的一個查漏補缺的索引,在這里重新看到問題,然后使用代碼驗證自己對問題的理解和學習。
使用Nodejs如何搭建一個RESTFUL的服務?
如何把cli-service中來自客戶端但是需要去應用服務器的URL訪問轉移到應用服務器?
如何解析前端提交的Json?
如何打包Json到響應內?
如何創建一個唯一的ID?本來是用于創建一個唯一ID,這樣就不必使用MongoDB生成的ObjectID了,因此插入效率會更高。但是,最后還是按慣例采用了Mongo的了。
如何加入新的單頁組件?
在哪里插入獲取服務端數據的代碼?
如何使用Buefy?
在Vuejs應用中內使用Buefy?
在Vuejs單頁組件內使用Buefy?
如何關閉input的自動完成特性?這個自動完成每次當你輸入的時候,都會顯示一個曾經的輸入的列表,真的很煩。
如何在組件之間共享狀態?
為何需要共享前端狀態?
如何區別使用同步和異步狀態操作?
如何映射狀態操作到組件內,以方便組件對方法的調用?
如何訪問Mongo?
如何安裝Mongo,并快速驗證Mongo?
如何命令行插入、刪除、列表一個Collection?
有哪些訪問Mongo的Nodejs庫,差別在哪里?
如何使用Await風格的代碼做插入刪除和列表?
如何獲取插入項目后的項目ID?
如何使用ObjectId查詢對應的項目?
如何訪問網絡,包括curl、axios、fetch等幾種方法?
如何提交Get請求?
如何提交Put請求?
如何在Body內提交json?
如何指定請求頭內容類型為json?
如何獲取響應中的Json數據?
參考文章這個App雖然很小,但是并非一次寫成的,我之前已經完成了若干個更加細小的、特定方面的文章,也寫了一些代碼。當然外部參考肯定也是不少,特別是Medium和Stack Overflow網站,對我支持很多。這里列出關鍵的一些參考文章。
這里會使用vuex管理狀態,之前有寫過文章,到底Vuex是什么,閱讀量和評價還不少呢。當然,我舉例的案例,有些勉強,為了用而用,實際案例并不需要Vuex,使用組件內狀態即可。
使用Mongodb存儲和提供后端CRD服務
使用Nodejs搭建{id,name}的對象的后端CRD服務。計劃參考之前我自己的2篇文章和一個SO關于如何在AJAX內創建PUT請求的問答
準備 JSON 服務器并訪問它
vuejs api server開發小抄
Axios PUT request to serveraxios-put-request-to-server
使用Fecth|Axios訪問后端CRD服務。此文章列舉了幾種訪問網絡庫的方法,給了我一個全局的視野,因此我很受益于它。[Fetch vs. Axios.js for making http requests
](https://medium.com/@thejasonf...
使用buefy的美化組件的方法。這個很小眾了,因此就只能看看官方文檔了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108462.html
摘要:使用訪問后端服務使用的美化組件的方法整合全棧服務其中的指的是。所幸是在這個教程內,你不需要學習太多就可以把案例跑起來。另外一個組件負責顯示全部項目,并接受刪除事件,刪除指定的項目。它們分別是組件和組件這兩個組件的代碼實現,分別在文件和內。 自從一年前發布了Vuejs小書的電子書,也有些日子沒有碰過它們了,現在因為項目的緣故,需要使用JavaScript全棧開發。所以,我得把這個全棧環境...
摘要:之前寫的文章急速全棧教程得到了不錯的閱讀量,霸屏掘金頭條天,點贊過千,閱讀近萬,甚至還有人在評論區打廣告,可見也是一個小小的生態了。今天看到的霸屏的,也是講全棧的,見參考文章接下來要寫的是模塊。全局命名污染和命名沖突依賴管理。 之前寫的文章急速Js全棧教程得到了不錯的閱讀量,霸屏掘金頭條3天,點贊過千,閱讀近萬,甚至還有人在評論區打廣告,可見也是一個小小的生態了;)。看來和JS全棧有關...
摘要:版本發布月日,官博發文宣告正式發布。官方文檔提供了如下的示例終端上的輸出熱門文章我在阿里云做前端抓住我們核心的競爭力,并同時發現業務中的問題,跨端推進解決,這是最好的出路。 showImg(https://segmentfault.com/img/remote/1460000019038442); 【阿里云 TXD 前端月刊】- 熱門前端技術快報,聚焦業界新視界;前端領域急速發展的節奏...
摘要:版本發布月日,官博發文宣告正式發布。官方文檔提供了如下的示例終端上的輸出熱門文章我在阿里云做前端抓住我們核心的競爭力,并同時發現業務中的問題,跨端推進解決,這是最好的出路。 showImg(https://segmentfault.com/img/remote/1460000019038442); 【阿里云 TXD 前端月刊】- 熱門前端技術快報,聚焦業界新視界;前端領域急速發展的節奏...
閱讀 2452·2021-11-22 09:34
閱讀 3063·2021-10-25 09:43
閱讀 1975·2021-10-11 10:59
閱讀 3361·2021-09-22 15:13
閱讀 2323·2021-09-04 16:40
閱讀 418·2019-08-30 15:53
閱讀 3186·2019-08-30 11:13
閱讀 2602·2019-08-29 17:30