VUE+Express+MongoDB前后端分離實(shí)現(xiàn)一個(gè)便簽墻
計(jì)劃來(lái)實(shí)現(xiàn)一個(gè)便簽墻系列,這個(gè)東西做簡(jiǎn)單也簡(jiǎn)單,往復(fù)雜了做功能也很多,記錄一下從零到有的開(kāi)發(fā)過(guò)程吧,希望最后能把這個(gè)項(xiàng)目做得很完善。
首先是前后端分離架構(gòu),前端用vue,后臺(tái)我們就用express,數(shù)據(jù)庫(kù)用mongodb吧。
在腦袋里過(guò)一下,最最開(kāi)始,要完成一個(gè)怎樣的雛形呢?先把用戶登錄管理放在一邊,當(dāng)然是便簽的增刪改查+顯示啊!
那么,我們就來(lái)實(shí)現(xiàn)“初號(hào)機(jī)”,一張張便簽的顯示,增加,修改,刪除。
1、怎么說(shuō)也得先把樣式畫出來(lái)
先別管接口,先把純前端的問(wèn)題解決先,我們先來(lái)一個(gè)像模像樣的“黑板”,對(duì)了,這里推薦一個(gè)網(wǎng)站https://www.transparenttextures.com/,可以生成你喜歡的壁紙素材,于是就有了:

好了,我們要在這塊黑板上“貼上”我們的便簽了,這一塊就是css的東西了,這個(gè)就看大家的美術(shù)設(shè)計(jì)功底了,我隨意了:

那么重要的一點(diǎn)是,在這塊背景板上,便簽就應(yīng)該是可以隨意貼在你想要的位置,所以對(duì)于便簽,用戶應(yīng)該可以拖拽并記錄位置。
所以將便簽div采取position: absolute,然后用top: y px和left: x px來(lái)實(shí)現(xiàn)定位。
于是我們考慮單個(gè)便簽對(duì)象包含的屬性有:
x: 便簽距容器左側(cè)距離, left的值
y: 便簽距容器上邊界距離, top得值
txt: 便簽的內(nèi)容
title: 標(biāo)題
color: {
bg: "", // 背景色
pin: "" // 回形針顏色
}
接下來(lái)我們就來(lái)實(shí)現(xiàn)便簽的拖動(dòng):
(1) 在便簽的div上綁定鼠標(biāo)點(diǎn)擊函數(shù):
@mousedown="mousedown($event)"
(2) 實(shí)現(xiàn)拖動(dòng):
mousedown: function(event) {
let _this = this;
if (!this.isEdit) {
this.startX = event.x;
this.startY = event.y;
this.note.moving = true;
document.onmousemove = event => {
if (!_this.note.moving) return false;
let dx = event.x - _this.startX;
let dy = event.y - _this.startY;
if (
_this.note.x + dx <= 0 ||
_this.note.x + dx >= _this.width - 250 ||
_this.note.y + dy <= 60
) {
return false;
}
_this.note.x1 = _this.note.x + dx;
_this.note.y1 = _this.note.y + dy;
};
document.onmouseup = () => {
if (!this.isEdit) {
this.note.moving = false;
this.note.x = this.note.x1;
this.note.y = this.note.y1;
this.saveNote();
document.onmousemove = null;
document.onmouseup = null;
}
};
}
}
初始記錄x和y的副本為x1,y1。用startX和startY記錄下最開(kāi)始鼠標(biāo)按下的位置,然后在拖動(dòng)過(guò)程中和原始值計(jì)算偏移量,賦值給x1和y1進(jìn)行定位,在鼠標(biāo)抬起時(shí)更新x,y為最終值。
這里有個(gè)關(guān)鍵點(diǎn)就是,如果用@mousemove,會(huì)導(dǎo)致在鼠標(biāo)拖動(dòng)過(guò)快的情況下,便簽不能及時(shí)跟隨鼠標(biāo),鼠標(biāo)就會(huì)移出div,造成拖動(dòng)失效。
所以這里只把mousedown綁定在目標(biāo)上,而把mousemove和mouseup綁定在document上,這樣就不會(huì)擔(dān)心鼠標(biāo)移快后出了便簽導(dǎo)致便簽卡住了。
2、對(duì)于便簽的內(nèi)容,該怎么編輯
這里設(shè)計(jì)一個(gè)按鈕,鼠標(biāo)hover上去后,顯示按鈕;點(diǎn)擊編輯按鈕,讓便簽內(nèi)容變成可編輯的狀態(tài),當(dāng)內(nèi)容區(qū)域blur的時(shí)候自動(dòng)保存。


由于div便簽沒(méi)有blur事件,所以在編輯狀態(tài)下,將內(nèi)容區(qū)域變?yōu)閠extarea:
<div
class="note-content"
v-if="!isEdit"
v-html="content"
:ref="'note' + index"
></div>
<el-input
v-else
class="note-content my-textarea"
type="textarea"
placeholder="請(qǐng)輸入內(nèi)容"
:autosize="{ minRows: 10 }"
v-model="content"
:ref="'note' + index"
@blur="handleChange"
></el-input>
很明顯,這里的內(nèi)容得用innerHTML結(jié)果保存,因?yàn)槲覀円4鎿Q行回車空格這些樣式,使顯示保持一致,所以在獲取編輯的字符串我們要用正則進(jìn)行替換:
this.content = this.content
.replace(/\r\n/g, "<br/>")
.replace(/\n/g, "<br/>")
.replace(/\s/g, " ");
變成編輯狀態(tài)時(shí),我們要把形式再轉(zhuǎn)換一下給textarea:
this.content = this.content
.replace(/ /g, " ")
.replace(/<br\/>/g, "\r\n");

3、下面不就是調(diào)接口的時(shí)候了
express框架這里就不再贅述了,我們用mongoose連接mongodb數(shù)據(jù)庫(kù),創(chuàng)建controller文件夾,增加note.js來(lái)實(shí)現(xiàn)數(shù)據(jù)庫(kù)操作:
// controller/note.js
const Notes = require("../model/notes");
var mongoose = require('mongoose');
module.exports = {
updateNote(obj) {
if (!obj.params._id) {
obj.params._id = new mongoose.mongo.ObjectID();
}
return Notes.findByIdAndUpdate(
obj.params && obj.params._id,
{
$set: obj.body
},
{
upsert: true,
new: true,
setDefaultsOnInsert: true
}
)
.then(function (newobj) {
return Promise.resolve({
status: 200,
messgae: "OK"
});
})
.catch((err) => {
return Promise.reject(err);
});
},
getNotes() {
return new Promise(function (resolve, reject) {
Notes.find()
.then(function (newobj) {
resolve(newobj);
})
.catch((err) => {
reject(err);
});
});
},
deleteNoteById(_id) {
return Notes.findByIdAndDelete(_id)
.then(function (newobj) {
return Promise.resolve({
status: 200,
messgae: "OK"
});
})
.catch((err) => {
return Promise.reject(err);
});
}
};
這里先簡(jiǎn)單寫寫,還可以進(jìn)一步封裝好返回結(jié)果。
創(chuàng)建model文件夾,增加note.js存放Schema:
// model/note.js
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
// 聲明一個(gè)數(shù)據(jù)集 對(duì)象
var noteSchema = new Schema({
txt: {
type: String,
required: false
},
x: {
type: Number
},
y: {
type: Number
},
color: {
type: Object
},
title:{
type: String,
default: "未命名"
},
createTime: {
type: Date,
default: Date.now
}
});
mongoose.set("useCreateIndex", true);
mongoose.set('useFindAndModify', false);
// 將數(shù)據(jù)模型暴露出去
module.exports = mongoose.model("Notes", noteSchema, "notes");
所以,在拖動(dòng)結(jié)束時(shí)、便簽blur時(shí)都要自動(dòng)保存。
于是數(shù)據(jù)庫(kù)里就會(huì)保存我們的便簽了:

于是一個(gè)初步的雛形完成了,我們創(chuàng)建便簽,拖動(dòng),編輯,刪除,這些都是實(shí)時(shí)保存的,刷新頁(yè)面后便簽的位置都是能保留的。
下面看看效果:

接下來(lái),還有好多任務(wù)清單沒(méi)做呢,隨便一想,功能上能完善的就很多,例如:用戶管理、時(shí)間分類、多條件查詢、便簽內(nèi)容支持富文本、便簽支持自定義樣式、備忘提醒功能等等。
再接再厲,任重道遠(yuǎn)~~~~
大家也可關(guān)注一下Cavans小游戲系列:
《VUE實(shí)現(xiàn)一個(gè)Flappy Bird~~~》
《VUE+Canvas 實(shí)現(xiàn)桌面彈球消磚塊小游戲》
《VUE+Canvas實(shí)現(xiàn)雷霆戰(zhàn)機(jī)打字類小游戲》
到此這篇關(guān)于VUE+Express+MongoDB前后端分離實(shí)現(xiàn)一個(gè)便簽墻的文章就介紹到這了,更多相關(guān)vue前后端分離便簽墻內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue項(xiàng)目如何實(shí)現(xiàn)Echarts在label中獲取點(diǎn)擊事件
這篇文章主要介紹了vue項(xiàng)目如何實(shí)現(xiàn)Echarts在label中獲取點(diǎn)擊事件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
vue中v-model雙向綁定input輸入框問(wèn)題
這篇文章主要介紹了vue中v-model雙向綁定input輸入框問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
vue使用腳手架vue-cli創(chuàng)建并引入自定義組件
這篇文章介紹了vue使用腳手架vue-cli創(chuàng)建并引入自定義組件的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
vue項(xiàng)目出現(xiàn)頁(yè)面空白的解決方案
今天小編就為大家分享一篇vue項(xiàng)目出現(xiàn)頁(yè)面空白的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10
vue項(xiàng)目中全局引入1個(gè).scss文件的問(wèn)題解決
這篇文章主要跟大家介紹了vue項(xiàng)目中全局引入1個(gè).scss文件的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
基于element-ui封裝可搜索的懶加載tree組件的實(shí)現(xiàn)
這篇文章主要介紹了基于element-ui封裝可搜索的懶加載tree組件的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05

