Nodejs+Vue+MySQL实现简单的增删改查

3,321 阅读5分钟


起初是想搭建一个环境直接操作数据库表,然后在网上搜索通过搭建一个Nodejs+vue+mysql的环境来实现。代码部分有参考,主要是将起整个流程走一遍。也碰到了不少问题。主要是数据库连接过程中的问题。将其记录一下希望能帮助到大家。

项目技术栈

  • Vue.js全家桶:vue-cli、vue-router、axios
  • UI:Element-UI部分组件
  • 后台接口:express。

安装vue-cli3脚手架

现在使用前端工程化开发项目是主流的趋势,也就是说,我们需要使用一些工具来搭建vue的开发环境,一般情况下我们使用webpack来搭建,在这里我们直接使用vue官方提供的,基于webpack的脚手架工具:vue-cli。

(1)全局安装webpack

cnpm install webpack -g

(2)全局安装yarn

cnpm install yarn  -g

(3)全局安装vue-cli

cnpm install -g @vue/cli

OR

yarn global add @vue/cli

(4)查看安装结果

我的电脑已经安装过了,依次执行命令:

node -v
yarn -v
vue -V (注意这里是大写的“V”)

vue项目创建

第一步:打开终端,创建一个vue项目,demo是自己命名的文件名,配置直接default默认的就好。

vue create demo

vue create报错

使用vue create 提示 bash: vue command not found有可能是环境变量的配置问题

首先找到yarn 全局安装vue的路径 : 我的路径是 C:\Users\xxx\AppData\Local\Yarn\Data\global\node_modules\.bin配置到环境变量 ->系统变量 ->Path 后再重新创建。

第二步:项目创建好之后按照提示进入项目文件夹,并运行它。

cd demo
npm run serve

第三步:在项目文件demo中打开终端,安装 Element-ui 和 router

npm i element

vue add router

最终package.json中所需的依赖

  "dependencies": {
    "axios": "^0.19.2",
    "core-js": "^3.6.5",
    "cors": "^2.8.5",
    "element": "^0.1.4",
    "element-ui": "^2.13.2",
    "mysql": "^2.18.1",
    "vue": "^2.6.11",
    "vue-router": "^3.3.2"
  },

最终的项目目录结构如下:


详细代码

server/app.js

const express = require('express') // 引入 express
const app = express() // 实例一个 express 对象
app.use(require('cors')()) // 解决跨域
app.use(express.json()) // express处理json数据

const mysql = require('mysql'); //调用 MySQL模块

// 创建连接
var db = mysql.createConnection({
  host: 'localhost',
  user: 'root', // 用户名
  password: 'asd123456', // 密码
  database: 'Article',// 数据库名
  port: 3306   // 端口号
})
db.connect( (err) => {
  if(err) throw err;
  console.log('连接成功');
})


app.get('/', (req, res) => {
  res.send('index')
})

// 新增文章
app.post('/api/article', (req, res) => {
  let data = req.body;
  let sql = "INSERT INTO posts SET ?";
  db.query(sql, data, (err, result) => {
    if(err) {
      console.log(err);
    } else {
      console.log(result);
      res.send(result)
    }
  })
})

// 获取文章列表
app.get('/api/article', (req, res) => {
  let sql = "SELECT * FROM posts";
  db.query(sql, (err, result) => {
    if(err) {
      console.log(err);
    } else {
      console.log(result);
      res.json(result);
    }
  })
})

// 删除文章
app.delete('/api/article/:id', (req, res) => {
  let sql = `DELETE FROM posts WHERE id= ${req.params.id}`;
  db.query(sql, (err, result) => {
    if(err) {
      console.log(err);
    } else {
      console.log(result);
      res.json(result);
    }
  })
})

// 获取文章详情
app.get('/api/article/:id', (req, res) => {
  let sql = `SELECT * FROM posts WHERE id= ${req.params.id}`
  db.query(sql, (err, result) => {
    if(err) {
      console.log(err);
    } else {
      res.json(result)
    }
  })
})

// 修改文章
app.put('/api/article/:id', (req, res) => {
  let newTitle = req.body.title;
  let newBody = req.body.body;
  let sql = `UPDATE posts SET title = '${newTitle}',body = '${newBody}' WHERE ID = ${req.params.id}`
  db.query(sql, (err, result) => {
    if(err) {
      console.log(err);
    } else {
      res.json(result)
    }
  })
})

// 监听端口3000
app.listen(3000, () => {
  console.log('http://localhost:3000/')
})

plugins/element.js

import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(Element)

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
// 分别引入三个 view
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',
    redirect: '/article/index' // 访问根路径,重定向到 /article/index
  },
  {
    path: '/article/index',
    name: 'List-article',
    component: ListArticle
  },
  {
    path: '/article/create',
    name: 'create-article',
    component: CreateArticle
  },
  {
    path: '/article/:id/edit',
    name: 'edit-article',
    component: EditArticle
  }
]

const router = new VueRouter({
  routes
})

export default router

views/CreateArticle.vue

<template>
	<el-form @submit.native.prevent="saveArticle" ref="form" :model="article" label-width="80px">
		<el-form-item label="文章标题">
			<el-input v-model="article.title"></el-input>
		</el-form-item>

		<el-form-item label="文章内容">
			<el-input type="textarea" v-model="article.body"></el-input>
		</el-form-item>
		<el-form-item>
			<el-button type="primary" native-type="submit">立即创建</el-button>
			<el-button>取消</el-button>
		</el-form-item>
	</el-form>
</template>
<script>
	export default {
		data() {
			return {
				article: {
					title: "",
					body: "",
					id: 0
				}
			};
		},
		methods: {
			saveArticle() {
				this.article.id = Math.floor(Math.random() * 1000) // 随机生成[0-1000]的整数id
				this.$http.post('/article', this.article).then(res => {
					console.log(res.config.data)
					this.$message({
						message: '文章创建成功',
						type: 'success'
					});
					this.$router.push('/article/index')
				})
			}
		}
	};
</script>

views/EditArticle.vue

<template>
  <el-form @submit.native.prevent="saveArticle" ref="form" :model="article" label-width="80px">
    <el-form-item label="文章标题">
      <el-input v-model="article.title"></el-input>
    </el-form-item>

    <el-form-item label="文章内容">
      <el-input type="textarea" v-model="article.body"></el-input>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" native-type="submit">保存</el-button>
      <el-button>取消</el-button>
    </el-form-item>
  </el-form>
</template>
<script>
export default {
  data() {
    return {
      article: {
        title: "",
        body: ""
      }
    };
  },
  methods: {
    saveArticle() {
      this.$http.put(`/article/${this.$route.params.id}`, this.article).then(res => {
        console.log(res.config.data)
        this.$message({
          message: '文章更新成功',
          type: 'success'
        });
        this.$router.push('/article/index')
      })
    },
    fetch() {
      this.$http.get(`/article/${this.$route.params.id}`).then(res => {

        this.article = res.data[0]
      })
    }
  },
  created() {
    this.fetch()
  }
};
</script>

views/ListArticle.vue

<template>
	<div>
		<el-table :data="articles">
			<el-table-column prop="title" label="标题" width="140"></el-table-column>
			<el-table-column prop="body" label="内容" width="220"></el-table-column>
			<el-table-column fixed="right" label="操作" width="100">
				<template slot-scope="scope">
					<el-button @click="edit(scope.row.id)" type="text" size="small">编辑</el-button>
					<el-button @click="remove(scope.row.id)" type="text" size="small">删除</el-button>
				</template>
			</el-table-column>
		</el-table>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				articles: []
			};
		},
		methods: {
			fetch() {
				this.$http.get("/article").then(res => {
					this.articles = res.data
				})
			},
			edit(id) {
				this.$router.push(`/article/${id}/edit`)
			},
			remove(id) {
				this.$http.delete(`/article/${id}`).then(res => {
					console.log(res.data)
					this.$message({
						message: '文章删除成功',
						type: 'success'
					});
				})
				this.fetch()
			}
		},
		created() {
			this.fetch()
		}
	};
</script>

App.vue

<template>
   <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-tickets"></i>内容管理
           </template>
           <el-menu-item index="/article/index">文章列表</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>用户1</span>
       </el-header>
 
       <el-main>
         <router-view></router-view>
       </el-main>
     </el-container>
   </el-container>
 </template>
 
 <style>
 html,
 body {
   padding: 0;
   margin: 0;
 }
 .el-header {
   background-color: #b3c0d1;
   color: #333;
   line-height: 60px;
 }
 
 .el-aside {
   color: #333;
 }
 </style>
 
 <script>
 export default {
   data() {
     return {
     };
   }
 };
 </script>

main.js

import Vue from 'vue'
import App from './App.vue'

import router from './router' // 引入 router文件夹下的 index.js
import './plugins/element.js' // 引入 element-ui

Vue.config.productionTip = false

import axios from 'axios' // 引入 axios
Vue.prototype.$http = axios.create({ // 将 axios方法定义到vue的原型上
  baseURL: 'http://127.0.0.1:3000/api' // 基础url,前端发起请求要先拼接上这个地址
})

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

运行项目

最后在项目目录demo打开终端执行

npm run serve


进入serve进入文件夹后启动node服务前需连接数据库服务,且建相应的article库建posts


在server文件夹目录打开终端执行

node app


最后访问localhost:8080查看页面。直接通过页面操作即可修改数据库中的数据。可以通过修改数据库表中的数据刷新页面查看修改后的数据。一个简单的通过nodejs+vue+mysql的增删改查功能即实现。

总结

以上总结都只是提交项目中遇到的一些坑,予以总结。分享给大家,还是要感谢前辈的总结,如果本文影响到您的利益,那么还请告知,在写本文时的初衷就是想给更多小伙伴,也为了以后方便查阅。

参考文章:1,hanxueqing.github.io/Douban-Movi…