zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    What's the difference between tilde(~) and caret(^) in package.json?
    腾迅股票数据接口
    dddd
    https://wrapbootstrap.com
    http://tpl.amazeui.org/
    http://www.ajaxload.info/
    基于Sublime Text搭建Python IDE
    IDAPython: importing “site” failed
    IDA_Python命令行使用
    “error LNK2019: 无法解析的外部符号”之分析
  • 原文地址:https://www.cnblogs.com/mxxbc/p/14105415.html
Copyright © 2011-2022 走看看