VUE+Express+MongoDB front-end and back-end separation to realize a note wall

VUE+Express+MongoDB front-end and back-end separation to realize a note wall

I plan to realize a series of sticky note walls. This thing is simple if it is simple, and it has many functions if it is complex. I will record the development process from scratch. I hope that this project can be perfected in the end.

First of all, we have a front-end and back-end separation architecture. We use Vue for the front-end, Express for the back-end, and MongoDB for the database.

Think about it in your mind, what kind of prototype do you want to complete at the very beginning? Let’s put user login management aside for now, of course, the focus is on adding, deleting, modifying, checking and displaying notes!

Then, we will implement "Unit-01" to display, add, modify and delete notes one by one.

1. You have to draw the style first.

Don’t worry about the interface first, let’s solve the pure front-end problem first. Let’s make a decent “blackboard”. By the way, here is a website https://www.transparenttextures.com/, which can generate your favorite wallpaper material, so we have it:

OK, we are going to "stick" our sticky notes on this blackboard. This is the CSS stuff. It depends on your art design skills. I'll just do it casually:

The important point is that on this background board, the sticky notes should be able to be attached anywhere you want, so for the sticky notes, users should be able to drag and record the location.

So set the note div to position: absolute, and then use top: y px and left: x px to achieve positioning.

So we consider the properties of a single note object:

x: the distance between the sticky note and the left side of the container, the value of left

y: The distance between the sticky note and the top edge of the container, the value of top

txt: content of the note

title: title

color:

bg: "", // background color

pin: "" // paper clip color

}

Next we will implement the dragging of sticky notes:

(1) Bind the mouse click function to the note's div:

@mousedown="mousedown($event)"

(2) Implementing dragging:

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;
          }
        };
      }
    }

The copies of the initial records x and y are x1,y1. Use startX and startY to record the initial position of the mouse press, then calculate the offset with the original value during the dragging process, assign it to x1 and y1 for positioning, and update x and y to the final value when the mouse is lifted.

The key point here is that if you use @mousemove, the sticky note will not be able to follow the mouse in time if the mouse is dragged too fast, and the mouse will move out of the div, causing the dragging to fail.

So here we only bind mousedown to the target, and mousemove and mouseup to the document, so that we don't have to worry about the sticky note getting stuck when the mouse moves too fast.

2. How to edit the content of a note?

Here we design a button. When the mouse hovers over it, the button is displayed. Click the edit button to make the note content editable. It will be automatically saved when the content area is blurred.

Since the div note has no blur event, in the editing state, change the content area to textarea:

 <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="Please enter content"
      :autosize="{ minRows: 10 }"
      v-model="content"
      :ref="'note' + index"
      @blur="handleChange"
    ></el-input>

Obviously, the content here must be saved with the innerHTML result, because we want to save the styles such as line breaks, carriage returns, and spaces to keep the display consistent, so when getting the edited string we need to replace it with a regular expression:

this.content = this.content

.replace(/\r\n/g, "<br/>")

.replace(/\n/g, "<br/>")

.replace(/\s/g, "&nbsp;");

When it becomes editable, we need to convert the format to textarea:

this.content = this.content

.replace(/&nbsp;/g, " ")

.replace(/<br\/>/g, "\r\n");


3. Now it’s time to adjust the interface

The express framework will not be described here. We use mongoose to connect to the mongodb database, create a controller folder, and add note.js to implement database operations:

// 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);
      });
  }
};

Here we will write a simple one first, and we can further encapsulate the returned results.

Create a model folder and add note.js to store the Schema:

// model/note.js
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
 
//Declare a dataset object var noteSchema = new Schema({
  txt: {
    type: String,
    required: false
  },
  x: {
    type: Number
  },
  y: {
    type: Number
  },
  color:
    type: Object
  },
  title:{
    type: String,
    default: "unnamed"
  },
  createTime: {
    type: Date,
    default: Date.now
  }
});
mongoose.set("useCreateIndex", true);
mongoose.set('useFindAndModify', false);
// Expose the data model module.exports = mongoose.model("Notes", noteSchema, "notes");

Therefore, it should be automatically saved when dragging ends and when the sticky note blurs.

Then our notes will be saved in the database:

So a preliminary prototype was completed. We created notes, dragged, edited, and deleted them. These were all saved in real time, and the position of the notes could be retained after refreshing the page.

Let’s take a look at the effect:

Next, there are still a lot of task lists that have not been done. If you think about it casually, there are many functions that can be improved, such as: user management, time classification, multi-condition query, note content support for rich text, note support for custom styles, memo reminder function, etc.

Keep up the good work, there is still a long way to go~~~~

You can also pay attention to the Cavans mini-game series:

《VUE implements a Flappy Bird~~~》

《VUE+Canvas realizes desktop pinball brick-breaking game》

《VUE+Canvas implements a typing game of Thunder Fighter》

This is the end of this article about VUE+Express+MongoDB front-end and back-end separation to realize a sticky note wall. For more related Vue front-end and back-end separation sticky note wall content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Solve the problem of Vue+springboot cross-domain session+cookie invalidation when separating front-end and back-end
  • Detailed explanation of the elegant solution for separating the front-end and back-end of Vue WeChat authorized login
  • SpringBoot+Vue.js realizes the file upload function of front-end and back-end separation
  • Sample code for separating front-end and back-end using nginx+vue.js
  • Vue+springboot front-end and back-end separation to achieve single sign-on cross-domain problem solution

<<:  MYSQL updatexml() function error injection analysis

>>:  A brief analysis of mysql index

Recommend

How to modify the mysql table partitioning program

How to modify the mysql table partitioning progra...

Alibaba Cloud Server Domain Name Resolution Steps (Tutorial for Beginners)

For novices who have just started to build a webs...

VMware Workstation download and installation detailed tutorial

Virtual machines are very convenient testing soft...

The complete code of the uniapp packaged applet radar chart component

Effect picture: The implementation code is as fol...

HTML+CSS to achieve charging water drop fusion special effects code

Table of contents Preface: accomplish: Summarize:...

HTML code to add icons to transparent input box

I was recently writing a lawyer recommendation we...

The difference and use of json.stringify() and json.parse()

1. Differences between JSON.stringify() and JSON....

Example of how to enable Slow query in MySQL

Preface Slow query log is a very important functi...

MySQL example of getting today and yesterday's 0:00 timestamp

As shown below: Yesterday: UNIX_TIMESTAMP(CAST(SY...

How to Change Colors and Themes in Vim on Linux

Vim is a text editor that we use very often in Li...

Summary on Positioning in CSS

There are four types of positioning in CSS, which...

VMware15/16 Detailed steps to unlock VMware and install MacOS

VMware version: VMware-workstation-full-16 VMware...