我的博客練手項目

最近比較閒,學了一些雜七雜八的技術,但不知道怎麼用,想的是作一個簡單的博客項目來練手,不知道能不能堅持下去,如今把項目框架搭建好了javascript

項目技術選擇css

後端:node+express+mongoose

前端:vue2+vue-router+vue-resource+vuex

mongodbhtml

啓動:要使用MongoDB,須要指定一個文件夾讓它存放數據,我在D:\MongoDB\
   data下創建了一個名爲db的文件夾
   
   win+R打開cmd,進入D:\MongoDB\bin目錄,執行「mongod –dbpath=D:\MongoDB\data\db」,就會啓動MongoDB
    啓動了MongoDB,咱們就可使用mongo(交互式shell)來管理數據庫了

項目結構前端

clipboard.png

前端的目錄直接用的vue-cli生成的,我以爲超級方便的,不少配置都不用本身去寫。不過可能會用到jquery的一些插件,查了資料,在webpack.base.config裏面加入這段,就能夠隨時隨地用jquery了vue

plugins: [
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      jquery: "jquery",
      "window.jQuery": "jquery",
    })
  ],

前端的主入口爲main.jsjava

import Vue from 'vue'
import router from "./router/router.js"
import Vuex from 'vuex'
import vueResource from 'vue-resource'
import App from './App'
import store from "./vuex/store.js"
import {sync} from 'vuex-router-sync'
import "bootstrap/dist/js/bootstrap.min.js"
import "bootstrap/dist/css/bootstrap.min.css"
window.$router = router;
window.$resource = vueResource;
sync(store, router);

Vue.use(vueResource);
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount("#app");

前端路由node

/**
 * Created by canoe on 2016/11/10.
 */
import Vue from 'vue'
import Router from 'vue-router'
import NProgress from 'nprogress'
import userLogin from './../components/login.vue'
import home from './../components/home.vue'
import myBlog from './../components/blog.vue'
const routes = [{
  path: '/login',
  name: 'login',
  component: userLogin
},
  {
    path:'/home',
    name:'home',
    component:home,
  },{
    path:'/myBlog',
    name:'myBlog',
    component:myBlog,
  },
   {
  path: '*',
  redirect: '/login'
}];

Vue.use(Router);
const router = new Router({
  mode: 'history',
  base: '/',
  routes: routes

});
/**
 * 登陸狀態檢查
 * */
router.beforeEach((to, from, next) => {
  NProgress.start();
if (to.matched.some(to => to.meta.requiresAuth)){
  //todo  鑑權
}else{
  next()
}
});
router.afterEach(transition => {
  NProgress.done();
  NProgress.remove();
});
module.exports = router;

vuex 是用來管理狀態的,能夠用來傳遞組件之間的通訊
vuex 目錄jquery

clipboard.png

數據流動是單向的webpack

組件能夠調用 actionsweb

Actions 是用來分發 mutations 的

只有 mutations 能夠修改狀態

store 是反應式的,即,狀態的變化會在組件內部獲得反映

後端NODE

昨天就作了個簡單的登陸註冊。由於我用8080端口監聽的前端頁面,所以我另外開了個端口6600監聽的服務,知道這種方法很差,可是沒有經驗,暫時這樣作吧。所以在調本地接口的時候,遇到了跨域問題,查了下資料,在node里加上

//設置跨域訪問
app.all('*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "http://localhost:8080");
  res.header("Access-Control-Allow-Credentials", "true");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
  res.header("X-Powered-By",' 3.2.1');
  res.header("Content-Type", "application/json;charset=utf-8");
  next();
});

這裏再記錄下依賴Express 實現post 4種方式提交參數吧,由於當時我也遇到個小問題,就是我post的是application/json型的數據,可是node 裏面req.body 爲空,後來查了資料,須要bodyParser隊請求包進行解析,具體的文章http://yijiebuyi.com/blog/90c...,感受講的清晰易懂

後端入口server.js

var express = require('express');
    var bodyParser = require('body-parser');
    var cookieParser = require('cookie-parser');
    var mongoose = require('mongoose');
    var config = require('./config/config.js')
    var router = require('./router/router.js')
    var app = express();
    app.use(express.static('dist'));
    app.set('port', 6600);
    app.use(bodyParser.json({limit: '1mb'}));  //這裏指定參數使用 json 格式
    app.use(bodyParser.urlencoded({
      extended: true
    }));
    //設置跨域訪問
    app.all('*', function(req, res, next) {
      console.log(req.body)
      res.header("Access-Control-Allow-Origin", "http://localhost:8080");
      res.header("Access-Control-Allow-Credentials", "true");
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
      res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
      res.header("X-Powered-By",' 3.2.1');
      res.header("Content-Type", "application/json;charset=utf-8");
      next();
    });
    app.get('/getdata', function(req, res) {
      res.send({id:req.params.id, name: req.params.password});
    });
    app.get('/', function (req, res)
    {
      res.sendFile(__dirname + "/" + "index.html");
    });
    var db = mongoose.connect(config.database);
    db = db.connection;
    db.on('open', function (err, doc)
    {
      console.log('數據庫鏈接成功')
    });
    db.on('err', function (err, doc)
    {
      console.log('數據庫鏈接失敗')
    });
    app.use('/api', router)
    
    app.listen(app.get('port'), function (req,res)
    {
        console.log('Server up: http://localhost:' + app.get('port')+new Date().getTime());
    });

把項目框架搭建好了以後,第一步是作登陸模塊。

界面設計
圖片描述
前端實現

<template>
        <div class="login-wrap">
            <div class="blog-desc">
                <h1>螞蟻窩</h1>
                <h4>記錄一些感想而已</h4>
            </div>
            <div class="login-title">
                <span>
                    <a class="login-text" href='#' @click='type="login"'>登陸</a>
                    <b>·</b>
                    <a class="login-text" href='#' @click='type="reg"'>註冊</a>
                  </span>
            </div>
            <div class="login-box" v-if='type=="login"'>
                <form class="login-form" >
                    <div class="form-group">
                        <div class="input-group">
                          <div class="input-group-addon"><i class="fa fa-user"></i></div>
                          <input class="form-control" type="text"  name='username' placeholder="輸入用戶名" v-model='login_params.username'>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="input-group">
                          <div class="input-group-addon"><i class="fa fa-unlock-alt"></i></div>
                          <input class="form-control" type="password" placeholder="輸入密碼" name="password" v-model='login_params.password'>
                        </div>
                    </div>
                    <div class="tool-box">
                        <div class="checkbox remember">
                            <label>
                              <input type="checkbox"> 記住我
                            </label>
                        </div>
                        <a href='#' class='forget-pwd'>忘記密碼</a>
                    </div>
            <div class="login-tip" v-text="err_login"></div>
                    <button type="button" class="btn btn-lg btn-block" @click='login()'>登陸</button>
                </form>
    
            </div>
        <!--註冊-->
            <div class="reg-box" v-if='type=="reg"'>
                <form class="reg-form" name='reg-form'>
                    <div class="form-group">
                        <div class="input-group">
                          <div class="input-group-addon"><i class="fa fa-user"></i></div>
                          <input class="form-control" name="username" type="text" placeholder="輸入用戶名" v-model='reg_params.username'>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="input-group">
                          <div class="input-group-addon"><i class="fa fa-unlock-alt"></i></div>
                          <input class="form-control" name="password" type="password" placeholder="輸入密碼" v-model='reg_params.password'>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="input-group">
                          <div class="input-group-addon"><i class="fa fa-unlock-alt"></i></div>
                          <input class="form-control" name="ensure_pwd" type="password" placeholder="確認密碼" v-model='reg_params.ensure_pwd'>
                        </div>
                    </div>
                    <div class="form-group">
                            <label class="radio-inline">
                              <input type="radio" name="gender" value="1"  v-model='reg_params.gender'> 男
                            </label>
                            <label class="radio-inline">
                              <input type="radio" name="gender"  value="0" v-model='reg_params.gender'> 女
                            </label>
                    </div>
                    <button type="button" class="btn btn-lg btn-block"   @click='userReg()'>註冊</button>
                </form>
        </div>
    </template>
    <script type="text/javascript">
    import {appLogin } from './../../vuex/action.js'
    export default{
        data(){
            return{
                type:'login',
        err_login:'',
                login_params:{
                },
                reg_params:{}
            }
        },
        methods:{
            login(){
        var _this=this;
        var login_params=_this.login_params;
        if(login_params.username==''){
          _this.err_login='用戶名不能爲空'
        }else if(login_params.password==''){
          _this.err_login='密碼不能爲空'
        }else{
           _this.$store.dispatch('userLogin',_this.login_params).then(res=>{
            //權限信息
            localStorage.setItem('authorization',JSON.stringify({
              token: res.token,
              time: new Date().getTime()
            }));
             _this.$router.replace({path:"article"})
          },res=>{
            _this.err_login='用戶名或密碼錯誤'
          });
        }
            },
            userReg(){
        if(this.reg_params.ensure_pwd==this.reg_params.password){
                    this.$store.dispatch('userReg',this.reg_params);
                }else{
                }
            }
        }
    }
    </script>
    <style lang="stylus">
      @import "./user.styl";
    </style>

action.js,主要是一些行爲去觸發mutations,而後mutations中去修改狀態

import * as types from "./mutation_types.js";
import * as API  from "../api/api.js";
import Vue from  'vue'

export const setLoginState=({commit},state)=>{
  commit(types.SET_LOGIN_STATUS, state);
};

export const userLogin = ({ commit }, params) =>
{
  return new Promise((resolve, reject)=>
  {
    API.login(params).then(res=>
    {
      var data=res.data;
      Vue.http.headers.common['authorization'] = data.token;
      commit(types.SET_LOGIN_STATUS, true);
      commit(types.SET_USER_INFO, {userName : params.username});
      resolve(data)
    }, res=>
    {
      reject(res.data);
    })
  })
};

vuex module 中的 longin.js,

import {
    SET_LOGIN_STATUS,SET_USER_INFO

} from './../mutation_types.js'

const state = {
    isLogin: false,
  userInfo: {},
};

const mutations = {
    [SET_LOGIN_STATUS](state, status) {
        state.isLogin = !!status;
    },
  [SET_USER_INFO](state,data){
    state.userInfo = data;
  }
};
export default {
    state,
    mutations
}
api 設計,用的vue-resource nodejs 端提供restful接口
import Vue from "vue";
import VueResource from "vue-resource"

Vue.use(VueResource);
// HTTP相關
Vue.http.options.crossOrigin = true;
Vue.http.options.credentials = true;

Vue.http.interceptors.push((req, next)  =>
{
  next((res) =>
  {
    return res
  });

});

const api = {
  user : `http://localhost:6600/api/user`,
  article:'http://localhost:6600/api/article',
  comment:'http://localhost:6600/api/comment',
  favorite:'http://localhost:6600/api/favorite',
};
const userResource = Vue.resource(api.user + '{/id}');
const articleResource = Vue.resource(api.article + '{/id}');
const commentResource = Vue.resource(api.comment + '{/id}');
const favoriteResource = Vue.resource(api.favorite + '{/id}');

export const login = function (params)
{
  return userResource.save({id : 'userLogin'}, params)
};
export const userReg = function (params)
{
  return userResource.save({id : 'userReg'}, params)
};
export const getArticleList = function (params)
{
  return articleResource.get(params)
};
export const  createArticle=function(params){
  return articleResource.save(params)
};
export  const getArticleDetail=function(articleId){
  return articleResource.get({id:articleId})
};
export  const commentArticle=function(params){
  return commentResource.save({id:params.id},params)
};
export  const favoriteArticle=function(params){
  return favoriteResource.save({id:params.id},params)
};
nodejs 端
model 設計
var mongoose=require('mongoose');
var md5 = require("md5");

var Schema=mongoose.Schema;//建立模型
var userSchema=new Schema({
    userName:{type:String, require:true},
    passWord:{type:String, require:true},
  ensure_pwd:{type:String, require:true},
  gender:Boolean,//1 爲男,0爲女
  created:{type:Date}
});

var articleSchema=new Schema({
    title:{type:String, require:true},
    content:    {type:String, require:true},
    author:     {type:Schema.Types.ObjectId, ref:'User'},
    //category:   {type:Schema.Types.ObjectId, ref:'Category'},
    created:    {type:Date},
    hasRead:{type:Number},
    slug:       {type:String, required: true },
    published:  {type:Boolean, default: false },
    meta:       {type:Schema.Types.Mixed,favorites: 0 },
    comments:   [Schema.Types.Mixed ]
});
var CategorySchema = new Schema({
    name:      {type:String, require:true},
    slug:       {type:String, require:true},
    created:    {type:Date}
});

//MD5密碼和原密碼匹配
userSchema.methods.verifyPassword= function(password){
    var isMatch= md5(password)=== this.password;
    //console.log('UserSchema.methods.verifyPassword: ', password, this.password, isMatch);
    return isMatch;
};

var Models={
    User:mongoose.model('User',userSchema),
  Article:mongoose.model('Article',articleSchema),
  Category:mongoose.model('Category',CategorySchema),
}
module.exports = Models;
相關文章
相關標籤/搜索