element-ui+mongodb+express项目的实现(含源代码)

项目介绍:此项目前端使用的Vue+Element-UI框架,后端使用的express(express 是nodejs的一个web开发框架),数据库使用了mongdb数据库。

通过express Web框架分别和Element-UI、MongoDB数据库进行交互,完成Vue页面和MongoDB数据库的增删改查等操作。

Vue.js 是一个JavaScriptMVVM库,是一套构建用户界面的渐进式框架。它是以数据驱动和组件化的思想构建的,采用自底向上增量开发的设计。相比于Angular.js,Vue.js提供了更加简洁、更易于理解的API,使得我们能够快速地上手并使用Vue.js。

Element-UI,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的组件库,提供了配套设计资源,帮助你的网站快速成型。

Node.js ,简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。使用 Express 可以快速地搭建一个完整功能的网站。

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

先上一张效果图:

一、项目开发环境设置

1、安装Mongodb数据库

2、安装node.js开发环境

3、安装淘宝npm镜像

4、安装全局vue-cli脚手架

5、开始进入主题,初始化一个vue项目(再次创建项目就可以从这一步开始了)

6、安装 Element UI

二、项目运行需要运行的操作

1、运行程序之前的操作

2、遇到的问题及解决办法:

三、项目代码编写:

四、项目的运行和效果

五、总结


一、项目开发环境设置

1、安装Mongodb数据库

安装教程:https://blog.csdn.net/m0_52560366/article/details/110239332

2、安装node.js开发环境

前端开发框架和环境都需要 Node.js ,安装node.js开发环境。

下载地址:https://nodejs.org/en/,下载后安装,一直点击next就行,安装完成后,在cmd中查看node版本号。

node -v

3、安装淘宝npm镜像

vue的运行是要依赖于node的npm的管理工具来实现

npm是国外的,使用起来比较慢,这里使用淘宝的cnpm镜像来安装vue。

npm install -g cnpm --registry=https://registry.npm.taobao.org

4、安装全局vue-cli脚手架

淘宝镜像安装成功之后,我们就可以安装全局vue-cli脚手架。

cnpm install --global vue-cli

5、开始进入主题,初始化一个vue项目(再次创建项目就可以从这一步开始了)

先用d:的命令进入d盘,输入下面命令回车,创建项目element,默认创建项目的信息,利用vue-cli自动构建一个基础项目即可。

vue init webpack element

出现下面提示,说明初始化成功。

cd element

npm run dev

输入cd element进入基础项目,输入命令npm run dev,运行基础项目element,弹出访问地址。

如果地址可以访问,说明可以安装Element UI,之后引入Element UI组件。

6、安装 Element UI

在刚刚创建的vue项目中创建element工程项目

Vue-cli3.0以上执行:vue add element

接下来就可以使用HbuilderX、WebStorm等工具,打开项目进行编写了。

二、项目运行需要运行的操作

1、运行程序之前的操作

1、服务端操作时,设计后端可以访问跨越:

npm i express@next mongoose cors

2、运行express服务:

使用node server/index.js命令,没有自动重载,更改完项目后需要关闭服务,重新运行,太麻烦了,所以我们进行全局安装nodemon。

npm install -global nodemon

然后运行命令:nodemon  server/index.js即可运行后端项目。

3、必须启动数据库

net stop MongoDB   启动数据库       net start MongoDB    关闭数据库

4、npm iaxios前后端通用的请求接口

npm i axios -S

2、遇到的问题及解决办法:

1、nodemon : 无法加载文件因为在此系统上禁止运行脚本。

https://blog.csdn.net/weixin_44324124/article/details/107039380 

2、These dependencies were not found:

* axios in ./src/main.js

* vue-router in ./src/router/index.js

To install them, you can run: npm install --save axios vue-router

说明没有添加依赖

cmd在文件位置npm install --save axios vue-router

3、注意(安装3.0以上需要参考这一部分):

       全局安装过旧版本的 vue-cli(1.x 或 2.x)要先卸载它,否则跳过此步:

       npm uninstall vue-cli -g

       vue cli3需要 node.js ≥ 8.9 (官方推荐 8.11.0+,你可以使用 nvm 或 nvm-windows在同一台电脑中管理多个 Node 版本)。

4、如果报错未定义,运行这一条语句。

npm install express --save

三、项目代码编写:

文件位置:

server/index.js代码:

// TODO  导入express 模块
// todo expsrss 是nodejs的一个web开发框架
// todo 后台请求的url
const express = require("express");
const app = express();

// todo 解决前台访问后台的跨域问题
// 这种解决方式是后台解决方式,后台允许前台跨域访问
app.use(require("cors")());

//post 提交数据的 req.body 的数据解析
const bodyParse = require('body-parser');
app.use(bodyParse.json());
app.use(bodyParse.urlencoded({extended:true}));

// app.use(bodyParse());
// app.use(express.json());

//连接数据库,只要在本机上安装了mongodb就可以了,数据库不存在会自动创建(数据库要启动)
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/mongoose_test", {
	//屏蔽弃用的警告
	useCreateIndex: true,
	useNewUrlParser: true,
	useUnifiedTopology: true,
	useFindAndModify: true,
}, function(err) {
	if (err) {
		console.log('Connection Error:' + err)
	} else {
		console.log('Connection success!')
	}
});

//数据库建模,文章模型
const ArticleModel = mongoose.model(
	"element", // 模型的名称 
	new mongoose.Schema({ //模型的结构
		title: {
			type: String
		},
		desc: {
			type: String
		}
	})
);

//Restful 风格的 CRUD
//后台接收前台的数据(方式)
//req.body  (post)
//req.query (get)
//URL ->  "/api/articleById/:id"  ->  req.params.id

// 文章列表
app.get("/api/articleList", async (req, res) => {
	console.log()
	const result = await ArticleModel.find();
	res.send(result);
});

// async await是简化异步操作的写法,create是mongoose提供的方法
// 添加文章
app.post("/api/addArticle", async (req, res) => {
	console.log(req.body);
	const result = await ArticleModel.create(req.body);
	if (result) {
		res.send({
			code: "01",
			message: "添加成功",
		});
	} else {
		res.send({
			code: "02",
			message: "添加失败",
		});
	}
});

// 删除文章
app.delete("/api/deleteArticle/:id", async (req, res) => {
  const result = await ArticleModel.findByIdAndDelete(req.params.id);
  if (result) {
    res.send({
      code: "01",
      message: "删除成功",
    });
  } else {
    res.send({
      code: "02",
      message: "删除失败",
    });
  }
});

// 文章详情
app.get("/api/articleById/:id", async (req, res) => {
	const result = await ArticleModel.findById(req.params.id);
	res.send(result);
});

// 更改文章(by:木心小白菜)
app.put("/api/articleUpdate/:id", async (req, res) => {
	const result = await ArticleModel.findByIdAndUpdate(req.params.id, req.body);
	if (result) {
		res.send({
			code: "01",
			message: "更改成功",
		});
	} else {
		res.send({
			code: "02",
			message: "更改失败",
		});
	}
});


//后台访问端口
app.listen(3005, () => {
	console.log("http://localhost:3005");
});

router/index.js代码:

import Vue from "vue";
import VueRouter from "vue-router";
import ListArticle from "../views/ListArticle.vue";
import CreateArticle from "../views/CreateArticle.vue";
import EditArticle from "../views/EditArticle.vue";

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "home",
    component: ListArticle,
    redirect: "/article/list",
  },
  {
    path: "/article/list",
    name: "ListArticle",
    component: ListArticle,
  },
  {
    path: "/article/create",
    name: "CreateArticle",
    component: CreateArticle,
  },
  {
    path: "/article/edit/:id",
    name: "EditArticle",
    component: EditArticle,
  }
];

const router = new VueRouter({
  routes,
});

export default router;

CreateArticle.vue代码:

<template>
  <div>
    <el-form
      :model="formData"
      :rules="rules"
      ref="formData"
      label-width="100px"
      @submit.native.prevent="saveArtice"
    >
      <el-form-item label="文章标题" prop="title">
        <el-input v-model="formData.title"></el-input>
      </el-form-item>
      <el-form-item label="文章内容" prop="desc">
        <el-input type="textarea" v-model="formData.desc"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" native-type="submit">立即创建</el-button>
        <el-button @click="resetForm('formData')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      formData: {
        title: "",
        desc: "",
      },
      rules: {
        title: [{ required: true, message: "请输入文章标题", trigger: "blur" }],
        desc: [{ required: true, message: "请填写文章内容", trigger: "blur" }],
      },
    };
  },
  methods: {
    saveArtice() {
		//参数:请求路径,请求体 then 返回数据
      this.$http.post("/addArticle", this.formData).then((res) => {
        if (res.data.code === "01") {
          this.$message({
            message: res.data.message,
            type: "success",
          });
        } else {
          this.$message({
            message: res.data.message,
            type: "error",
          });
        }
      });
      this.$router.push("/article/list");
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
  },
};
</script>

EditArticle.vue代码:

<template>
  <div>
    <el-form
      :model="formData"
      :rules="rules"
      ref="formData"
      label-width="100px"
      @submit.native.prevent="saveArtice"
    >
      <el-form-item label="文章标题" prop="title">
        <el-input :readonly="readonly" v-model="formData.title"></el-input>
      </el-form-item>
      <el-form-item label="文章内容" prop="desc">
        <el-input
          type="textarea"
          :readonly="readonly"
          v-model="formData.desc"
        ></el-input>
      </el-form-item>
      <el-form-item v-show="!readonly">
        <el-button type="primary" native-type="submit">保存</el-button>
        <el-button @click="resetForm('formData')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      formData: {
        title: "",
        desc: "",
      },
      rules: {
        title: [{ required: true, message: "请输入文章标题", trigger: "blur" }],
        desc: [{ required: true, message: "请填写文章内容", trigger: "blur" }],
      },
      readonly: false,
    };
  },
  props: ["flag"],
  created() {
    if (this.$route.query.flag) {
      this.readonly = true;
      this.rules = {}
    }
    this.getArticle();
  },
  methods: {
    getArticle() {
      this.$http.get(`/articleById/${this.$route.params.id}`).then((res) => {
        this.formData = res.data;
      });
    },
    saveArtice() {
      this.$http
        .put(`/articleUpdate/${this.$route.params.id}`, this.formData)
        .then((res) => {
          if (res.data.code === "01") {
            this.$message({
              message: res.data.message,
              type: "success",
            });
          } else {
            this.$message({
              message: res.data.message,
              type: "error",
            });
          }
        });
      this.$router.push("/article/list");
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
  },
};
</script>

ListArticle.vue代码:

<template>
	<div>
		<el-table :data="tableData" style=" 100%">
			<el-table-column prop="title" label="文章标题" width="260">
			</el-table-column>
			<el-table-column prop="desc" label="文章内容" width="400">
			</el-table-column>
			<el-table-column fixed="right" label="操作">
				<template slot-scope="scope">
					<el-button @click="handleView(scope.row._id)" type="text" size="small">查看</el-button>
					<el-button @click="handleEdit(scope.row._id)" type="text" size="small">编辑</el-button>
					<el-button @click="handleRemove(scope.row._id)" type="text" size="small">删除</el-button>
				</template>
			</el-table-column>
		</el-table>
	</div>
</template>
<script>
	export default {
		name: "app",
		data() {
			return {
				tableData: [],
			};
		},
		created() {
			this.getArticleList();
		},
		methods: {
			getArticleList() {
				this.$http.get("/articleList").then((res) => {
					this.tableData = res.data;
				});
			},
			handleView(id) {
				this.$router.push({
					path: `/article/edit/${id}`,
					query: {
						flag: true,
					},
				});
			},
			handleEdit(id) {
				this.$router.push(`/article/edit/${id}`);
			},
			
			handleRemove(id) {
				console.log(id);
				this.$http.delete(`/deleteArticle/${id}`).then((res) => {
					if (res.data.code === "01") {
						this.$message({
							message: res.data.message,
							type: "success",
						});
					} else {
						this.$message({
							message: res.data.message,
							type: "error",
						});
					}
					this.getArticleList();
				});
			},
		},
	};
</script>

App.vue代码:

<template>
	<div id="app">
		<el-container style="height: 100vh; border: 1px solid #eee">
			<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
				<el-menu router :default-openeds="['1']">
					<el-submenu index="1">
						<template slot="title"><i class="el-icon-message"></i>内容管理</template>
						<el-menu-item index="/article/list">文章列表</el-menu-item>
						<el-menu-item index="/article/create">新建文章</el-menu-item>
					</el-submenu>
				</el-menu>
			</el-aside>
			<el-container>
				<el-header style="text-align: right; font-size: 12px">
					<el-dropdown>
						<i class="el-icon-setting" style="margin-right: 15px"></i>
						<el-dropdown-menu slot="dropdown">
							<el-dropdown-item>查看</el-dropdown-item>
							<el-dropdown-item>新增</el-dropdown-item>
							<el-dropdown-item>删除</el-dropdown-item>
						</el-dropdown-menu>
					</el-dropdown>
					<span>By:木心李白菜</span>
				</el-header>
				<el-main>
					<router-view></router-view>
				</el-main>
			</el-container>
		</el-container>
	</div>
</template>

<style>
	body,
	html {
		margin: 0;
		padding: 0;
	}

	.el-header {
		background-color: #b3c0d1;
		color: #333;
		line-height: 60px;
	}

	.el-aside {
		color: #333;
	}
</style>

main.js代码:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'

/* 参考https://www.cnblogs.com/itgezhu/p/11949621.html */
Vue.config.productionTip = false

//导入axios库前后端通用的请求接口,创建axios的请求实例,有了它我们就可以定义接口和地址,如果没有它我们每个地方都需要重复的写接口和地址。
import axios from 'axios'

//这样$http可以全局调用
Vue.prototype.$http = axios.create(
  {
    baseURL:'http://localhost:3005/api'
  }
)

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

四、项目的运行和效果

项目的运行:

必须已经启动了mongodb数据库:net start MongoD

使用的工具Hbuilder,可以使用其他工具。

现在即可在浏览器通过http://localhost:8080/访问网址了。

从下面的三张图的不同,可以看出完成了增删改查功能。

五、总结

关于具体的操作:

  1. 安装mongodb数据库
  2. 安装nodo.js
  3. 安装淘宝npm镜像
  4. 安装全局vue-cli脚手架
  5. 利用vue-cli自动构建一个基础项目
  6. vue项目按需要引入Element UI
  7. 基础项目中需要配置element-UI、router路由、express、mongoose等
  8. 程序运行过程中需要安装nodemon mongoose cors express@next axios等,可以在提示需要安装的时候在进行安装。

体会:在解决问题的过程中学习。

ElementUI官网地址。https://element.eleme.cn/#/zh-CN/component/installation

Mongodb菜鸟操作文档。https://www.runoob.com/mongodb/mongodb-tutorial.html

B站Element UI+Express全栈开发后台管理界面地址。https://www.bilibili.com/video/BV1t441187pL?p=1

原文地址:https://www.cnblogs.com/mxxbc/p/14105415.html