管理系统"/>
通过Express+vue2实现笔记管理系统
项目地址 .git
目录
后端Express 部分
一.express生成器
二.解决前后端跨域
三.连接、封装操作MySQL
四.创建注册用户接口
五.创建首页图片接口
六.创建笔记接口增删改查
前端 vue2
main.js 配置根路径
配置request
配置路由 创建相应文件
配置用户接口
创建登陆界面
下载element
头部导航栏
编辑
首页
创建弹框组件
新增笔记组件
笔记功能
后端Express 部分
一.express生成器
1.概述
应用程序生成器工具 (express-generator
) 可以快速创建应用程序框架。
2.全局安装express生成器
npm install -g express-generator
3.在当前工作目录中创建名为 myapp 的 Express 应用程序并将视图引擎将设置为 Pug
express --view=pug myapp
4.然后进入myapp根目录安装依赖项:
cd myapp
npm install
5.启动项
npm start
二.解决前后端跨域
1.通过安装cors模块 解决
npm i cors
2.app.js
const cors = require('cors')app.use(cors())
三.连接、封装操作MySQL
// 1.导入mysql包
const mysql = require('mysql')// 2.创建mysql连接
const pool = mysql.createPool({connectionLimit: 150, host:'localhost', // 主机user: 'root', // 用户名password: '', // 密码database: 'hw3_1' // 数据库名称
})// 3.连接mysql
function query (sql) {return new Promise(function (resolve,reject) {pool.getConnection(function (err, connection) {if (err) return;// 4. 执行sqlconnection.query(sql, function (err, data) {if (err) return;resolve(data)console.log(data);// 5.释放连接connection.release()})})})
}// 查询数据module.exports=query
四.创建注册用户接口
使用mysql创建表格
//创建存储用户数据的表格
ALTER TABLE `hw3_1`.`user`CHANGE `password` `password` INT NULL FIRST,CHANGE `username` `username` CHAR (11) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL AFTER `password`;
routers/login.js
const express = require('express')
const router = express.Router()
const query = require('../db/query')// 新增用户
//将用户名称 密码插入user表中 同一管理
router.post('/adduser', async function (req, res) {// post 请求参数const { username, password } = req.bodyconst sql = `insert into users(username,password) values( '${username}', '${password}')`const insert= await query(sql)console.log(req.body) res.send({status:200,message:'数据插入成功',insert})
})// 通过用户名创建存储用户数据的表
router.post('/formate', async function (req, res) {// post 请求参数const {username} = req.bodyconst sql = `CREATE TABLE ${username} ( id INT NOT NULL AUTO_INCREMENT,formname VARCHAR(255) NOT NULL,fordata TEXT,PRIMARY KEY (id))`const insert= await query(sql)console.log(req.body) res.send({status:200,message:'数据插入成功',insert})
})//查询表
//用于判断表中是否有该用户用于登陆
router.post('/formate', async function (req, res) {// post 请求参数const {username} = req.bodyconst sql = `CREATE TABLE ${username} ( id INT NOT NULL AUTO_INCREMENT,formname VARCHAR(255) NOT NULL,fordata TEXT,PRIMARY KEY (id))`const insert= await query(sql)console.log(req.body) res.send({status:200,message:'数据插入成功',insert})
})module.exports = router
使用sql创建图片表
CREATE TABLE `images` (`switch` text NOT NULL,`id` int NOT NULL AUTO_INCREMENT,PRIMARY KEY (`id`)
)
五.创建首页图片接口
home.js
查询首页图片表格
const express = require('express')
const router = express.Router()
const query = require('../db/query')
// 用于获取首页图片
router.get('/image',async function (req, res) {const sql = 'SELECT * FROM images'const data= await query(sql)res.send({status: 200,message: '数据请求成功',data})})module.exports = router
六.创建笔记接口增删改查
const express = require('express')
const router = express.Router()
const query = require('../db/query')// 笔记系统的增删改查
//查
router.post('/getformdata',async function (req, res) {const{formnaem} = req.bodyconst sql = `SELECT * FROM ${formnaem}`const insert= await query(sql)res.send({status: 200,message: '数据请求成功',insert})})// 改router.post('/updateformdata',async function (req, res) {const{formnaem,fordata,formwhere} = req.bodyconst sql = `UPDATE ${formnaem} SET fordata='${fordata}' WHERE formname='${formwhere}'`const insert= await query(sql)res.send({status: 200,message: '数据修改成功',insert})})// 增加router.post('/addformdata',async function (req, res) {const{name,formnaem,fordata} = req.bodyconst sql = `INSERT INTO ${name} (formname,fordata) VALUES('${formnaem}','${fordata}')`const insert= await query(sql)res.send({status: 200,message: '数据增加成功',insert})})// 删除router.post('/deleteformdata',async function (req, res) {const{name,formname} = req.bodyconst sql = `DELETE FROM ${name} WHERE formname = '${formname}'`const insert= await query(sql)res.send({status: 200,message: '数据删除成功',insert})})module.exports = router;
前端 vue2
main.js 配置根路径
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import axios from 'axios'
import store from './store/index'Vue.use(ElementUI)Vue.config.productionTip = false
// 配置根路径
axios.defaults.baseURL = 'http://localhost:3000/'
new Vue({store,render: h => h(App),router
}).$mount('#app')
配置request
//until/request
import axios from "axios";
// 创建 axios 实例对象
const service = axios.create({timeout: 5000
})export default service
配置路由 创建相应文件
//router/index.js
import Vue from 'vue';
import vueRouter from 'vue-router';
Vue.use(vueRouter)const routes= [{path: '/home',component: () => import('@/view/User-Home.vue'),children:[{path: '/', component: () => import('@/view/home-Website')},{path: 'Website', component: () => import('@/view/home-Website')},{path:'takenotes',component: () => import('@/view/Take-notes')},{path:'noterec',component: () => import('@/view/Note-recommendation')},{path:'sysstem',component: () => import('@/view/System')}]},{path: '/login',component: () => import('@/view/User-login')},{path: '',redirect: '/login'},]
const router = new vueRouter({routes,mode:'history',})export default router;
配置用户接口
//api/lgoin.jsimport request from '@/utils/request'// 用户列表获取
export function getuser() {return request({url: 'login/usernaem'})
}// 用户注册
export function adduser(data) {return request({url: `login/adduser?${data}`,method: 'post',data})
}//通过用户创建用户表
export function addfome(data) {return request({url: `login/formate?${data}`,method: 'post',data})
}
创建登陆界面
//view/user-login
<template><div class="login"><div class="mylogin" align="center"><div class="LoginModeSwitch"><div @click="AccountLogin" :class="showlding ? '' : 'tabactive'">账号登录</div><div @click="VisitorLogin" :class="showlding ? 'tabactive' : ''">注册账号</div></div><!-- 账号登录界面 --><el-formv-show="showlding":model="loginForm":rules="loginRules"ref="loginForm"label-width="0px"><el-form-item label="" prop="account" style="margin-top: 10px"><el-row><el-col :span="2"><span class="el-icon-s-custom"></span></el-col><el-col :span="22"><el-inputclass="inps"placeholder="用户名"v-model="loginForm.account"></el-input></el-col></el-row></el-form-item><el-form-item label="" prop="passWord"><el-row><el-col :span="2"><span class="el-icon-lock"></span></el-col><el-col :span="22"><el-inputclass="inps"type="password"placeholder="密码"v-model="loginForm.passWord"></el-input></el-col></el-row></el-form-item><el-form-item style="margin-top: 55px"><el-button type="primary" round class="submitBtn" @click="submitForm">登录</el-button></el-form-item></el-form><!-- 账号注册界面 --><el-formv-show="!showlding":model="loginForm":rules="loginRules"ref="loginForm"label-width="0px"><el-form-item label="" prop="account" style="margin-top: 10px"><el-row><el-col :span="2"><span class="el-icon-s-custom"></span></el-col><el-col :span="22"><el-inputclass="inps"placeholder="用户名"v-model="loginForm.account"></el-input></el-col></el-row></el-form-item><el-form-item label="" prop="passWord"><el-row><el-col :span="2"><span class="el-icon-lock"></span></el-col><el-col :span="22"><el-inputclass="inps"type="password"placeholder="密码"v-model="loginForm.passWord"></el-input></el-col></el-row></el-form-item><el-form-item style="margin-top: 55px"><el-buttontype="primary"roundclass="submitBtn"@click="submitregister">注册账号</el-button></el-form-item></el-form></div></div>
</template><script>
import { mapMutations } from "vuex";
import { getuser, adduser } from "@/api/login";export default {name: "Login",data: function () {return {loginForm: {account: "",passWord: "",},loginRules: {account: [{ required: true, message: "请输入账号", trigger: "blur" }],passWord: [{ required: true, message: "请输入密码", trigger: "blur" }],},showlding: false,res: "", //接受数据logintoken: false, //判断账号密码foem: false, // 判断是否注册 成功};},created() {this.getuser();},methods: {...mapMutations(["changeLogin"]),// 登录submitForm() {const userAccount = this.loginForm.account;const userPassword = this.loginForm.passWord;// 校验 规则if (!userAccount) {return this.$message({type: "error",message: "账号不能为空!",});}if (!userPassword) {return this.$message({type: "error",message: "密码不能为空!",});}this.logintoken = this.res.some((item) => {if (item.username == userAccount && item.password == userPassword) {return true;}});if (this.logintoken) {this.$message.success("登录成功");this.$router.push("/home");console.log(this.res);this.$storemit("getuserinfo", { name: userAccount });} else {this.$message({type: "error",message: "登录失败",});}},// 注册async submitregister() {const userAccount = this.loginForm.account;const userPassword = this.loginForm.passWord;// 校验 规则if (!userAccount) {return this.$message({type: "error",message: "账号不能为空!",});}if (!userPassword) {return this.$message({type: "error",message: "不能将密码设为空",});}await adduser({username: `${userAccount}`,password: `${userPassword}`,}).then(() => {this.foem = true;console.log(this.foem);// 处理成功this.$message.success("注册成功");}).catch((err) => {// 报错console.log(err);this.$message({type: "error",message: "注册失败,请检查账号是否重复注册",});return;});if (this.foem) {this.showlding = true}// 重新获取数据let res = await getuser();this.res = res.data.data;},// 登录显示隐藏AccountLogin() {this.showlding = true;},// 登录显示隐藏VisitorLogin() {this.showlding = false;},//获取数据async getuser() {let res = await getuser();this.res = res.data.data;},},
};
</script><style>
.login {background-size: cover;background-repeat: no-repeat;background-position: center center;width: 101%;height: 101%;width: 100vw;padding: 0;margin: 0;height: 100vh;font-size: 16px;background-position: left top;background-color: #242645;color: #fff;font-family: "Source Sans Pro";position: relative;
}.mylogin {width: 240px;height: 280px;position: absolute;top: 0;left: 0;right: 0;bottom: 0;margin: auto;padding: 50px 40px 40px 40px;box-shadow: -15px 15px 15px rgba(6, 17, 47, 0.7);opacity: 1;background: linear-gradient(230deg,rgba(53, 57, 74, 0) 0%,rgb(0, 0, 0) 100%);
}.inps input {border: none;color: #fff;background-color: transparent;font-size: 12px;
}.submitBtn {background-color: transparent;color: #39f;width: 200px;
}
.tourist {float: right;
}
.LoginModeSwitch {display: flex;justify-content: space-around;
}
.VisitorLogin {height: 100%;display: flex;flex-direction: column;justify-content: center;align-items: center;
}
.VisitorLoginsubmit {background-color: transparent;color: #39f;width: 200px;
}
.VisitorLoginsubmitRouter {text-decoration: none;color: #fff;
}
.tabactive {color: rgb(155, 155, 120);
}
</style>
下载element
npm i element-ui -S
// element官网
//
头部导航栏
//view/User-Home
<template><div><div><el-menu:default-active="activeIndex2"class="el-menu-demo"mode="horizontal"@select="handleSelect"background-color="#545c64"text-color="#fff"active-text-color="#ffd04b"><el-menu-item><span class="titleloge">NOTES</span></el-menu-item><el-menu-item index="1" @click="toWebsite" class="topnabbier">首页</el-menu-item><el-menu-item index="2" @click="takenotes" class="topnabbier">写笔记</el-menu-item><el-menu-item index="3" @click="noterec" class="topnabbier">笔记推荐</el-menu-item><el-menu-item index="4" @click="sysstem" class="topnabbier">技术栈</el-menu-item></el-menu></div><router-view></router-view></div>
</template><script>
export default {data() {return {activeIndex: "1",activeIndex2: "1",};},methods: {handleSelect(key, keyPath) {console.log(key, keyPath);},// 导航跳转toWebsite() {this.$router.push("/home/Website");},takenotes() {this.$router.push("/home/takenotes");},noterec() {this.$router.push("/home/noterec");},sysstem() {this.$router.push("/home/sysstem");},},
};
</script>
<style>
.titleloge {font-size: 4vw;
}
.topnabbier{font-size: 1.4vw;
}
</style>
首页
<template><div><el-carousel :interval="4000" type="card" height="250x" class="top"><el-carousel-item v-for="item in images" :key="item.id"><img :src="item.switch" alt="" class="carouselimaeg" /></el-carousel-item></el-carousel><div class="login1"><img src="@/img/166839387137969.png" alt="" /></div><h3 class="topbox">NOTE managenment 更好的方便用户管理信息,更加方便的整理自己的笔记,拥有方便的笔记分享平台,让你拥有更高效的笔记</h3><el-row type="flex" class="row-bg"><el-col :span="8"><div class="row-bg-item"><i class="el-icon-user"></i><p>用户:{{ this.$store.state.user.name }}</p></div></el-col><el-col :span="8"><div class="row-bg-item"><i class="el-icon-edit"></i><p>用户笔记</p></div></el-col><el-col :span="8"><div class="row-bg-item"><i class="el-icon-message"></i><p>用户信息</p></div></el-col></el-row></div>
</template><script>
import { getswiper } from "@/api/home";
import { addfome } from "@/api/login";
export default {data() {return {images: "",};},methods: {async getswiper() {try {let { data: res } = await getswiper();this.images = res.data;await addfome({username: this.$store.state.user.name,});} catch (err) {console.log(err);}},},created() {this.getswiper();// console.log(`${this.$store.state.user.name}`);},
};
</script><style>
.topbox{margin-top:5vw ;text-align: center;width: 60vw;margin: 0 auto ;
}
.login1 img{padding-left:35vw ;width: 40vw;height: 10vw;
}
.el-carousel__item:nth-child(2n) {background-color: #99a9bf;
}.el-carousel__item:nth-child(2n + 1) {background-color: #d3dce6;
}
.carouselimaeg {width: 100%;height: 100%;
}
.top {margin-top: 10px;
}
<style > .el-col {border-radius: 4px;
}
.bg-purple-dark {background: #99a9bf;
}
.bg-purple {background: #d3dce6;
}
.bg-purple-light {background: #e5e9f2;
}
.grid-content {border-radius: 4px;min-height: 36px;
}
.row-bg {padding-top: 5vw;background-color: #f9fafc;
}
.row-bg-item {text-align: center;
}
.row-bg {width: 70vw;margin: 0 auto;font-size: 1.4vw;
}</style>
创建弹框组件
<template><div><el-dialog title="NOTE" :visible.sync="dialogFormVisible"><el-form :model="form"><el-form-item label="新增笔记" :label-width="formLabelWidth"><el-input v-model="form.name" autocomplete="off"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="btnCancel">取消</el-button><el-button type="primary" @click="btnok">确 定</el-button></div></el-dialog></div>
</template><script>
import {addnote} from '@/api/note'
export default {data() {return {dialogFormVisible: false,showloding: false, // 控制页面form: {name: "",},formLabelWidth: "120px",};},methods: {async btnok() {this.dialogFormVisible = false;this.showloding = true;this.$emit("change", this.showloding);// console.log(this.$store.state.user.name);// console.log(this.form.name);// 增加表await addnote({name:`${this.$store.state.user.name}`,formnaem:`${this.form.name}`,fordata:``});// 获取 父组件方法重新渲染this.$parent.getformdata()// 将笔记名字重新置为空this.form.name=''},btnCancel() {this.dialogFormVisible = false;this.showloding = false;this.$emit("change", this.showloding);},},
};
</script><style>
</style>
新增笔记组件
安装wangEditor
npm install @wangeditor/editor-for-vue --save
官网地址 .html#npm
//components/Note-Input.vue
<template><div style="border: 1px solid #ccc"><Toolbarstyle="border-bottom: 1px solid #ccc":editor="editor":defaultConfig="toolbarConfig":mode="mode"/><Editorstyle="height: 500px; overflow-y: hidden"v-model="html":defaultConfig="editorConfig":mode="mode"@onCreated="onCreated"@onChange="onChange"@onDestroyed="onDestroyed"@onMaxLength="onMaxLength"@onFocus="onFocus"@onBlur="onBlur"@customPaste="customPaste"/></div>
</template>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<script>
import Vue from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";export default Vue.extend({components: { Editor, Toolbar },data() {return {editor: null,html: "<p>hello</p>",toolbarConfig: {},editorConfig: { placeholder: "请输入内容..." },mode: "default", // or 'simple' };},methods: {onCreated(editor) {this.editor = Object.seal(editor);console.log("onCreated", editor);},onChange(editor) {console.log("onChange", editor.children);console.log(this.html); // 数据this.$storemit("gethtml", this.html);},onDestroyed(editor) {console.log("onDestroyed", editor);},onMaxLength(editor) {console.log("onMaxLength", editor);},onFocus(editor) {console.log("onFocus", editor);},onBlur(editor) {console.log("onBlur", editor);},customPaste(editor, event, callback) {console.log("ClipboardEvent 粘贴事件对象", event);// const html = event.clipboardData.getData('text/html') // 获取粘贴的 htmlconst text = event.clipboardData.getData('text/plain') // 获取粘贴的纯文本// const rtf = event.clipboardData.getData('text/rtf') // 获取 rtf 数据(如从 word wsp 复制粘贴)// 自定义插入内容editor.insertText(text);// 返回 false ,阻止默认粘贴行为event.preventDefault();callback(false); // 返回值(注意,vue 事件的返回值,不能用 return)// 返回 true ,继续默认的粘贴行为// callback(true)},insertText() {const editor = this.editor; // 获取 editor 实例if (editor == null) return;// 调用 editor 属性和 APIeditor.insertText("一段文字");console.log(editor.children);},upinput () {this.html = `${this.$store.state.input}`;// console.log(this.html);}},mounted() {// 模拟 ajax 请求,异步渲染编辑器setTimeout(() => {this.html = `${this.$store.state.input}`;}, 1500);},beforeDestroy() {const editor = this.editor;if (editor == null) return;editor.destroy(); // 组件销毁时,及时销毁编辑器},
});
</script>
笔记功能
//Take-notes.vue
<template><div class="big"><!-- :class="showlding ? '' : 'tabactive'" --><el-container :class="!show ? '' : 'allblur'"><!-- 左边导航栏 --><el-aside width="200px" style="background-color: rgb(238, 241, 246)"><el-menu :default-openeds="['1', '2']"><el-submenu index="1"><template slot="title"><i class="el-icon-message"></i>笔记工具</template><el-menu-item-group><template slot="title">基础功能</template><!-- 新增功能 --><el-menu-item index="1-1" @click="showupdate">新增笔记</el-menu-item><!-- 删除功能 --><el-menu-item index="1-2" @click="del"> 删除笔记 </el-menu-item><!-- 保存功能 --><el-menu-item index="1-3" @click="updatad">保存笔记</el-menu-item></el-menu-item-group><!-- 跟多工具 --><el-submenu index="1-4"><template slot="title">更多工具</template><el-menu-item index="1-4-1">选项4-1</el-menu-item></el-submenu></el-submenu><!-- 笔记内容 --><el-submenu index="2"><template slot="title"><i class="el-icon-menu"></i>笔记内容</template><el-menu-item-group><template slot="title">笔记栏</template><el-menu-itemv-for="(item, i) in formdata":key="item.id":index="`2-${i}`"@click="updataformi(i)">{{ item.formname }}</el-menu-item></el-menu-item-group></el-submenu></el-menu></el-aside><!-- 右侧内容 --><el-main><div v-show="!show"><el-empty><el-button type="primary" @click="showupdate">新增笔记</el-button></el-empty></div><!-- 笔记 --><div v-show="show"><noteinput ref="ChildComponents" inputvalue></noteinput></div></el-main></el-container><!-- 弹窗内容 --><addelementclass="addelement"ref="child"@change="costPlannedAmountChange($event)"></addelement></div>
</template><script>
import addelement from "@/components/add-emplass.vue";
import noteinput from '@/components/Note-Input.vue'
import { getnote, delnote, noteupdata } from "@/api/note";
export default {components: { addelement,noteinput},data() {return {uniqueOpened: false,textarea: "",show: false, // 控制 笔记显示隐藏formdata: "", // 保存请求数据formi: 0, // 判断点击的下标inputvalue: "", // 笔记内容delshow: false, //判断删除是否成红};},methods: {updataformi(i) {this.formi = i;this.inputvalue = this.formdata[this.formi].fordata;// console.log(this.inputvalue);this.show = true;this.$storemit("getinput",this.inputvalue);this.$refs.ChildComponents.upinput()},// 控制 显示隐藏async showupdate() {this.$refs.child.dialogFormVisible = true;//this.$store.state.user.name},// 获取弹框组件数据async costPlannedAmountChange(value) {this.show = value;},// 获取数据接口async getformdata() {// console.log(this.$store.state.user.name,'111111111111');var formdata = await getnote({formnaem: `${this.$store.state.user.name}`,}); this.formdata = formdata.data.insert;// console.log(this.formdata, "222222222222222");this.formi = this.formdata.length - 1;this.inputvalue = this.formdata[this.formdata.length - 1].fordata;this.$storemit("getinput", this.inputvalue);},//删除async del() {// 删除玩重新获取await delnote({name: `${this.$store.state.user.name}`,formname: `${this.formdata[this.formi].formname}`,});this.getformdata();this.$message({ type: "success", message: "删除成功" });this.show=false},//保存async updatad() {console.log(this.$store.state.html);await noteupdata({formnaem: `${this.$store.state.user.name}`,fordata: `${this.$store.state.html}`,formwhere: `${this.formdata[this.formi].formname}`,});this.getformdata();this.$message({ type: "success", message: "保存" });},},created() {this.getformdata();},
};
</script><style>
</style>
更多推荐
通过Express+vue2实现笔记管理系统
发布评论