美文网首页
Express+mysql+vue博客项目

Express+mysql+vue博客项目

作者: noyanse | 来源:发表于2018-03-29 12:20 被阅读0次

连接mysql数据库

const mysql = require('mysql');
const db = mysql.createPool({
    host:'localhost',
    user:'root',
    'password':'123456',
    database:'blog'
})
db.getConnection((err,conn) => {
  if(err) console.log('connect failed')//数据库连接失败
  conn.query('SELECT * FROM article_table',(err,data) => {//数据库连接成功
            if(err) console.log(err)
            res.send(data).end();
        })
        conn.release()//释放连接池
})

获取所有文章接口

//获取文章
router.post('/article',function(req,res,next){
    db.getConnection(function(err,conn){//连接数据库
        if(err) console.log('connect failed')//数据库连接失败
        conn.query('SELECT * FROM article_table',(err,data) => {//数据库连接成功
            if(err) console.log(err)
            // console.log(data)
            res.send(data).end();
        })
        conn.release()//释放连接池
    })
})

获取文章详情页

//获取文章详情页
router.get('/article/detail',function(req,res,next){
    db.getConnection(function(err,conn){//连接数据库
        if(err) console.log('connect failed')//数据库连接失败
        conn.query(`SELECT * FROM article_table WHERE id=${req.query.id}`,(err,data) => {//数据库连接成功
            if(err) console.log(err)
            // console.log(data)
            res.send(data).end();
        })
        conn.release()//释放连接池
    })
})
  • router
{
      path: '/index',
      name: 'Home',
      component: Home
    },
    {
      path: '/articles/detail/:id',//添加路由参数
      name: 'Article',
      component: Article
    },
  • index.vue
<router-link 
  class="read-more" 
  :to="'/articles/detail/' + item.ID"  //获取文章的ID并作为路由参数
  :key="item.ID" 
  tag="li" 
  v-for="item in articleList">
</router-link>


created(){
    Vue.axios.post('/api/article')
        .then(res => {
            this.articleList = res.data;            
        })
        .catch(err => console.log(err))
},

  • detail.vue
    data() {
        return {
            articleDetail: []
        }
    },
    created(){
        const artId=this.$route.params.id;//获取路由参数
        Vue.axios.get(`/api/article/detail?id=${artId}`)
              //获取后台详情api并加上id
            .then(res => {
                this.articleDetail = res.data[0];
                console.log(res.data[0])
            })
            .catch(err => console.log(err))
        }

登录接口

//登陆/验证API  通用
router.post('/login', function(req, res){
    var username = req.body.username;//获取表单提交的name属性值
    var password = common.md5(req.body.password+common.MD5_SUFFIX);
    var resBody = {state:''}//前台根据返回状态验证
    db.query(`SELECT * FROM user_table WHERE username='${username}'`,(err, doc) => {
        if(err){
            res.status(500).send('err').end();
        }else{
            if(doc.length==0){
              resBody.state = 'no admin';
              res.send(resBody);
            } else{
              if(doc[0].password==password){
                req.session['admin_id']=doc[0].ID;
                resBody.state = 'success';
                res.send(doc).end();
               }else{
                resBody.state = 'pwderr';              
                res.send(resBody).end();
              }
            }
        }
    })
})
  • md5
const crypto=require('crypto');
module.exports={
    //这东西不能丢
    MD5_SUFFIX: 'ergveringnvginbiojncrurugbb*&^5$4$###bregbj哈哈哈哈',
    md5: function(str){
        var obj=crypto.createHash('md5');

        obj.update(str);

        return obj.digest('hex');
    }
}
  • 存在数据库的密码需要先用md5加密
  • login.vue
<template>
    <div class="login">
            <form  @submit.prevent="login">
           <div class="grid-content login">
              <p class="loginTitle">登陆  | Login</p>
            <input type="text" v-model="username" placeholder="请输入你的用户名">
            <input type="password" v-model="password" placeholder="请输入你的密码">
            <button type="submit">登录</button>
            <!-- <button type="submit" @click="login">登录</button> -->
          </div>
        </form>
    </div>
</template>
<script>
import Vue from 'vue'
export default {
    data() {
        return {
          username: '',
          password: ''
        }
      },
    methods: {
        login() {
        Vue.axios.post('/api/login',{//把数据传过来
          username: this.username,
          password: this.password
        })
        .then((res) => {
            const data = res.data;
            if(data.state === "pwderr"){
              alert('密码错误')
              return false
            }else if(data.state==='no admin'){
               alert('账号不存在')
               return false
            }else{
               alert('success')
               let userid = data[0].id;
               this.$store.dispatch('setUsername', {name: this.username,id: userid});//添加到vuex中
               this.$router.push({path: '/admin/write-blog'})//提交到的路径
            }
           
          })
        .catch(err => console.log(err))
      }
    }
}
</script>

删除数据库

//删除数据库数据
router.post('/del',(req,res) => {
    var id = req.body.id
    db.query(`DELETE FROM article_table WHERE ID='${id}'`,(err,data) => {
        if(err){
            console.log(err);
            res.status(500).send('database err').end();
        }else{
            res.send('删除成功')
        }
    })
})
  • 数据表格vue
<table class="tab" width="100%" cellpadding="0" cellspacing="0">
                <thead>
                    <tr>
                        <th width="2%">ID </th>
                        <th width="15%">标题</th>
                        <th width="48%">描述</th>
                        <th width="15%">发表时间</th>
                        <th width="20%">操作</th>             
                    </tr>
                </thead>
                <tbody v-for="(item,index) in articleList">                 
                    <tr>
                        <td>{{index+1}}</td>
                        <td>{{item.title}}</td>
                        <td>{{item.summary}}</td>   
                        <td>{{item.post_time}}</td>         
                        <td>
                            <el-button @click="visible = true,mod(item.ID,index)">修改</el-button>
                            <el-button @click="del(item.ID,index)">删除</el-button>
                            <!-- <a href="javascript:;" @click="mod(item.ID,index)">修改</a>                   -->
                            <!-- <a href="javascript:;" @click="del(item.ID,index)">删除</a> -->
                        </td>
                        
                    </tr>
                </tbody>
            </table>
methods: {
        del(db,index) {
            if(confirm("确定要清空数据吗?")){
                this.articleList.splice(index,1);//删除视图层,并自动刷新页面,数据库中并没有删除
                Vue.axios.post('/api/del', { id:db })
                    .then(data => {
                        // console.log(db)//当前行id
                    })  
            }                                               
        },
    }

写文章接口

/* 写文章*/
router.post('/edit',(req,res)=>{
    var title = req.body.title;
    var summary = req.body.summary;
    var context = req.body.context;
    var post_time = new Date().getTime();//获取当前时间
//处理时间戳
    moment.locale('zh-cn');
    var today = {};
    var _today = moment();
    today.year = _today.format('yyyy'); /*现在的年*/
    today.date = _today.format('YYYY-MM-DD'); /*现在的时间*/
    today.yesterday = _today.subtract(1, 'days').format('YYYY-MM-DD'); /*前一天的时间*/
    var postFormatDate = moment(post_time).format('YYYY-MM-DD HH:mm:ss'); /*格式化时间*/
    
    db.query(`INSERT INTO article_table(author,author_src,title,context,post_time,n_like,summary) VALUES("mottoko@163.com","","${title}","${context}","${postFormatDate}","0","${summary}")`,(err,data)=>{
        if(err){
            console.log(err);
            res.status(500).send('数据库错误').end();
        }else{
            res.json(data.insertId).end();//插入的id
        }
    })  
})
  • 获取新插入参数的id用data.insertId

  • 返回给前台要用res.json

  • 前台

<el-tab-pane label="写博客">
            <div class="write-blog">                
                <form @submit.prevent="addblog">
                    <label for="title">标题:</label><input type="text" id="title" v-model="title" class="int title"><br>
                    <label for="summary">描述:</label><input type="text" v-model="summary" id="summary" class="int summary"><br>
                    <mavon-editor v-model="context" :toolbars="toolbars" @keydown="" />
                    <button type="submit" @click="insertBlog" class="addbtn">添加</button>
                </form>
            </div>
        </el-tab-pane>
methods: {
  addblog(){//添加文章在数据库中
        addblog() {
            Vue.axios.post('/api/edit',{
                author: this.author,
                title: this.title,
                summary: this.summary,
                context: this.context,
                post_time: this.post_time
            })
            .then(res => {                  
                alert('发表成功')
//更新视图已经找到方法,不用重新刷新页面了
                // location.reload()//实在搞不定把新增数据添加到表格中了,以后有时间再整吧
                // this.blogId = res.data   //获取新增ID
                this.$router.push('/admin/write-blog')              
            })
            .catch(err => console.log(err))

        },
  },
  insertBlog(){//更新视图
            var obj={};
                var myDate = new Date();
                var y = myDate.getFullYear();
                var m = myDate.getMonth() + 1;
                var d = myDate.getDate();
                var h = myDate.getHours();
                var min = myDate.getMinutes();
                var s = myDate.getSeconds();
                if (m >= 1 && m <= 9) {
                    m = "0" + m;
                }
                if (d >= 0 && d <= 9) {
                    d = "0" + d;
                }
                this.post_time = y + '-' + m + '-' + d + ' ' + h + ':' + min + ':' + s;
                obj.author=this.author;
                obj.title=this.title;
                obj.summary=this.summary;
                obj.context=this.context;
                obj.post_time=this.post_time;
                this.articleList.push(obj);
  }
}



错误

  • Expected Array, got Number 想要的是Array,你却给我Number
  • mysql [Err] 1064 - You have an error in your SQL syntax;sql语句出现空格或者不正确的符号
  • 注意防止sql注入,后台可以加上var id = db.escape(req.body.id)

修改页面数据接口

修改数据首要要获取点击的数据,然后在此基础上修改,这里后台我做了两个API,一个是获取当前选中的一行数据接口,一个是修改接口

  • 后台:
//当前选中的一行数据的详细
router.post('/mod_data',(req,res) => {
    db.query(`SELECT * FROM article_table WHERE id=${req.body.id}`,(err,data)=>{
        if(err){
            console.log(err);
            res.status(500).send('database err').end();
        }else if(data.length==0){
            res.status(404).send('data not found').end();
        }else{
            db.query(`SELECT * FROM article_table`,(err,blogdetail)=>{
            if(err){
                console.log(err);
                res.status(500).send('database err').end();
            }else{
                res.send(data[0])
                }
            });
        }
    })
})
//修改页面数据
router.post('/mod',(req,res) => {
    var mod_title = req.body.mod_title;
    var mod_summary = req.body.mod_summary;
    var mod_context = req.body.mod_context
    db.query(`UPDATE article_table SET title='${mod_title}',context='${mod_context}',summary='${mod_summary}' WHERE ID='${req.body.id}'`,(err,data)=>{
            if(err){
                console.log(err);
                res.status(500).send('database err').end();
            }else{
                res.send('修改成功');
            }
        })
})

  • 前台
    当点击修改按钮后,弹出下面的dialog,点修改按钮,传入此文章后台id,然后将此id传到后台,后台用,req.body.id接受,就可获取此文章详细信息,然后将此id传出去,修改数据的接口接收,进行修改操作。
    v-model是要绑定修改的数据的,但默认是提前出来的数据,所以就让
    v-model="mod_summary=mod_data.summary"

<el-button @click="visible = true,mod(item.ID,index)">修改</el-button>
//修改dialog
    <div class="mod_dialog" v-show="isshow">
        <form @submit.prevent="mod_add">
            <el-dialog :visible.sync="visible" title="修改">
                <div class="update">
                    标题:<input type="text" v-model="mod_title=mod_data.title" class="int title"><br>
                    描述:<textarea v-model="mod_summary=mod_data.summary" cols="30" rows="5" class="int summary"><!-- {{mod_data.summary}} --></textarea><br>
                    <label class="lab-content">内容:</label><textarea v-model="mod_context = mod_data.context" cols="30" rows="10" class="textarea"><!-- {{mod_data.context}} --></textarea><br>
                    <input type="submit" value="添加" class="addbtn">
                </div>          
            </el-dialog>
                            
        </form>
    </div>

methods:{
      mod(db,index) {                       
            Vue.axios.post('/api/mod_data', { id:db })
                .then(res => {
                    this.isshow=true;   
                    this.mod_data = res.data    
                    this.currentId = db 
                    console.log(db)         
            })
        },
        mod_add() {         
            Vue.axios.post('/api/mod', { 
                id:this.currentId, 
                mod_title: this.mod_title,
                mod_summary: this.mod_summary,
                mod_context: this.mod_context
            })
                .then(res => {
                    alert('修改成功')
                    this.visible = false
                    console.log(res.data)       
                })
        }       
}

相关文章

  • Express+mysql+vue博客项目

    连接mysql数据库 获取所有文章接口 获取文章详情页 router index.vue detail.vue 登...

  • 博客项目

    项目概述 项目运行环境 Python3.6+ Django 1.11 MySQL 5.7 其他插件(图片处理、分页...

  • 博客项目

    1.基本配置 数据库DATABASES = { 'default': { 'ENGINE': 'django....

  • 项目博客

    在seetings配置数据库 迁移文件 python manage.py makemigrations 执行迁移 ...

  • 博客项目

    案例初始化 创建对应的文件 public 静态资源文件夹 router 路由 views 模板 model 数据库...

  • Django(博客项目)

    一、项目概述 项目运行环境 Python3.6+Django 1.11MySQL 5.7其他插件(图片处理、分页、...

  • 个人博客项目

    源码地址:github示例:Yui_tycc的博客 (好久没更博客,等服务器换好之后也会在个人博客网站上更新,同时...

  • 博客项目重启

    又一周过去了。 计划这周开始接着写我的博客项目,之前数据库已经建好了,后端环境也搭好了,但是中间隔了一个多月,忘的...

  • vue+Node打造个人博客(一)——前端项目结构

    这篇博客我将用vue+elementUI+Node.js搭建个人博客项目,项目已经上传到github。这个项目我打...

  • [项目蓝图] 个人博客项目

    此项目属于萌新学习(>▽<),还请大佬们多多指教 _(:」∠)_该日记主要记录写Bug和改Bug的过程 项目介绍 ...

网友评论

      本文标题:Express+mysql+vue博客项目

      本文链接:https://www.haomeiwen.com/subject/ywrmcftx.html