vue2-koa-mongoDB-

vue2+koa+mongoDB搭建博文分享系统,主要功能有本地上传图片,token验证等

7 months after

从设计到前端重构后端交互数据库存储一手操作,新手全栈入门

(请先创建用户发布一篇文章以供数据测试)

Blink前后端

运行方式:(一定要安装mongodb) mongodb安装教程: https://segmentfault.com/a/1190000002547229

//启动mongo服务
cd: /mongo
./mongod

//安装前端依赖,启动服务
cd: /fornt
npm install all
npm run dev

//安装后端依赖,启动服务
cd: /server
npm install all
npm run dev

跳过设计流程(这里把自己内部分享直接复制来了)

“闪现”制作流程之(二):再讲前端

前端用的就是vue渲染,当然还有webpac,vuex,vue-router,vue-resource等冚家大礼包。只不过这次全面升级,变成冚家2.0

记录点自己遇到的坑吧:
1,vue-router2.0的动态路由

//html
<router-link :to="{
    name: 'article', params: { articleId: item._id }
}">
</router-link>

//js
this.$router.push({ path: ' ', params:' ' })

1.1,main.js里要用特殊的姿♂势导入路由才可执行:

const app = new Vue({
  el: 'app',
  router,
  store,
  render: h => h(App)
})

2,在vue组件里面只允许一个根节点,即:

<template>
  //要是>1的同级层就算再不乐意也得创建一个空div包裹所有层
  <div>
      .....
  </div>
</template>

3,使用formdata传输input上传图片

<form id="form" name="multiUploadForm" method="post" enctype="multipart/form-data">
   <input name="thisInput">
</from>

var data = new FormData(document.getElementById("form"));
//formdata也可以使用append方法添加数据
//data.append("other", value)

3.1,form的enctype选择“multipart/form-data”才可以上传多图
3.2,要想vue-resouce正确提交formdata数据就必须加“emulateJSON: true”参数

Vue.resource(API_ROOT + 'users{/id}', { emulateJSON: true });

3.4,每一条formdata数据必须带上name参数

4,marked+hightLight.js没什么好说,监听编辑框输入,预览框对应输出,对于图片处理我有自己的方法:将上传图片存入数组1,转为二进制保存在数组2,图片显示名字不显示地址(临时预览不上传服务器),预览端输出数组2显示图片,若用户更换图片顺序,索引图片名称对应位置重新排序数组2

//生成base64图片,临时预览,FileReader跟formdata一样为H5新增方法
var reader = new FileReader();
reader.readAsDataURL(thisFile);
//监听图片上传完毕,onload事件
reader.onload = function(e){
      self.insertPicAry.push( {
           result : this.result,
           name : thisFile.name,
           file : thisFile,
      );
      self.picAddress = thisFile.name;
 }

其他文本输出逻辑思路有:插入编辑功能的自动选中、区分、输出;用户手动选中区分、输出;二次进入编辑时赋值;各种状态判断等

5,token验证
涉及到用户修改数据都会加入token验证,还必须得是异步函数,验证完了才能执行下一步。vue-rouce提供了拦截器interceptos,在请求发出前获取用户登录后存储在sessionStorge的用户token,插入请求头,发出请求

//vue-resource拦截器
Vue.http.interceptors.push((request, next) => {
  Vue.http.headers.common['token'] = sessionStorage.token || '';
  next((response) => {
    //在响应之后传给then之前对response进行修改和逻辑判断
    if (response.status == 401) {
      store.state.loginJudge = false;
      sessionStorage.removeItem('token');
    }
  })
})

//token验证使用promise对象
 getUserLogin ( {commit}, opts){
    opts = opts || "";
    return new Promise((resolve, reject) => {
      api.getUserLogin(opts).then(function (res) {
        if (res.body.state) {
          resolve();
        }else {
          reject(res.body.msg)
        }
      }).catch(function(e){
         reject(e.body.msg)
      })
    })
  },
## “闪现”制作流程之(三): 三话后台

使用koa搭建服务器,使用MongoDB存储数据

讲讲main.js里各类插件处理各类问题:

1,路由匹配:koa-router

let koa = require('koa-router')();

//注册路由,router.routes()返回处理匹配到了请求对应的路由的router中间件
//router.use([path], middleware, [...])  Use given middleware(s) before route callback.
//router.use(),匹配到设置的接口地址后,进入回调中间件,再中间件里设置路由路径匹配对应后的回调函数
koa.use('/users', users.routes(), users.allowedMethods());

2,前后端分别配置两个域名,当然地址是本机,只是端口号不一样,既然是跨域就必须解决接口跨域的问题:kcros
3,想要通过地址访问本地存储的图片就必须暴露此服务器地址(文件夹位置):koa-static

let cors = require('kcors'),
     static = require('koa-static');

//cors解决跨域问题
app.use(cors());
//static配置静态文件,可直接访问该文件夹下的文件
app.use(static(__dirname + '/public/'));

4,token签发认证:koa-jwt

app.use(jwt({
  secret: 'Blink_1.0',
  passthrough: true
}));

app.use(function *(next){
  var ctx = this,
      thisUrl = ctx.request.url;
  console.log(thisUrl)
  // 如果不是create或者checkOut路径,直接跳过该中间件
  if (thisUrl.indexOf('create') === -1 && thisUrl.indexOf('checkOut') == -1) {
    return yield next;
  }
  var token = ctx.request.headers.token || '';
  if (token) {
    var profile = jwt.verify(token, 'Blink_1.0');
    if (profile) {
      // 设置过期时间为1天
      if (Date.now() - profile.original_iat  < 12 * 60 * 60 * 1000) {
        yield next;
      } else {
        ctx.status = 401;
        ctx.body = {
          state: false,
          msg: 'token已过期'
        };
      }
    } else {
      ctx.status = 401;
      ctx.body = {
        state: false,
        msg: 'token认证失败'
      }
    }
  } else {
    ctx.status = 401;
    ctx.body = {
      state: false,
      msg: 'token认证失败'
    }
  }
});

5,想要全局使用mongodb,就得赋值一个全局承诺

const mongoose = require('mongoose')

const mongooseDB = function () {
    //重点在这一句,赋值一个全局的承诺。
    mongoose.Promise = global.Promise
  mongoose.connect('mongodb://127.0.0.1:27017/my_blog')
  return mongoose.connection
}

敲黑板,划重点:
流程(二)前端里说过,图片是通过formdata形式提交数据,如何将数据流转为绝对地址保存在本地服务器:co-busboy

//上传控件
var parse = require('co-busboy');
var fs = require('fs');
var os = require('os');
var path = require('path');

while (part = yield parts){
    //一定要对流进行处理,否则while循环会被卡住
    //input上传文件就是个对象,包含了filename键值
    if (part.filename) {
      var filename = part.filename;
      fileNames.push(filename)
      var homeDir = path.resolve(__dirname, '..')
      var newpath = homeDir + '/public/images/article/'+ filename;
      //生成存储路径,要注意这里的newpath必须是绝对路径,否则Stream报错
      var stream = fs.createWriteStream(newpath);
      //写入文件流
      part.pipe(stream);

    //不是input上传文件则为数组['键','值']形式
    }else if(part.length) {
      if (part[0].indexOf("subTags") > -1) {
        subTags.push(part[1]);
        opts["subTags"] = subTags;
      }else {
        opts[part[0]] = part[1];
      }
    }

Related Repositories

awesome-vue

awesome-vue

A curated list of awesome things related to Vue.js ...

awesome-github-vue

awesome-github-vue

Vue相关开源项目库汇总 ...

koa-grace

koa-grace

A Nodejs SFB(Separation of Front and Back ends) framework, build with koa(基于koa的 ...

koa2-API-scaffold

koa2-API-scaffold

一个基于Koa2的轻量级RESTful API Server脚手架,支持ES6。 ...

awesome-vue

awesome-vue

A curated list of awesome things related to Vue.js ...