2020-12-17

安装nodejs

安装git

下载vue-admin-template(前端)

建议

本项目为可作为管理系统的基础模板作为二次开发,可用于初学者或学生基于它进行二次开发。(本人基于多人协助的基础开发,技术有限。)

基础模板:vue-admin-template


开始创建项目

Idle使用:WebStorm

①下载vue-admin-template

②进入vue-admin-template项目

③初始化vue-admin-template项目

④运行vue-admin-template


# clone the projectgit clone

 https://github.com/PanJiaChen/vue-admin-template.git

# enter the project directory

cd vue-admin-template

# install dependency

npm install

# develop

npm run dev

image

编辑vue-admin-template项目

到project\vue-admin-template\src\router\index.js

删除多余界面后如下


import Vue from 'vue'

import Router from 'vue-router'

Vue.use(Router)

/* Layout */

import Layout from '@/layout'

/**

* Note: sub-menu only appear when route children.length >= 1

* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html

*

* hidden: true                  if set true, item will not show in the sidebar(default is false)

* alwaysShow: true              if set true, will always show the root menu

*                                if not set alwaysShow, when item has more than one children route,

*                                it will becomes nested mode, otherwise not show the root menu

* redirect: noRedirect          if set noRedirect will no redirect in the breadcrumb

* name:'router-name'            the name is used by <keep-alive> (must set!!!)

* meta : {

    roles: ['admin','editor']    control the page roles (you can set multiple roles)

    title: 'title'              the name show in sidebar and breadcrumb (recommend set)

    icon: 'svg-name'            the icon show in the sidebar

    breadcrumb: false            if set false, the item will hidden in breadcrumb(default is true)

    activeMenu: '/example/list'  if set path, the sidebar will highlight the path you set

  }

*/

/**

* constantRoutes

* a base page that does not have permission requirements

* all roles can be accessed

*/

export const constantRoutes = [

  {

    path: '/login',

    component: () => import('@/views/login/index'),

    hidden: true

  },

  {

    path: '/404',

    component: () => import('@/views/404'),

    hidden: true

  },

  {

    path: '/',

    component: Layout,

    redirect: '/dashboard',

    children: [{

      path: 'dashboard',

      name: 'Dashboard',

      component: () => import('@/views/dashboard/index'),

      meta: { title: 'Dashboard', icon: 'dashboard' }

    }]

  },

  // 404 page must be placed at the end !!!

  { path: '*', redirect: '/404', hidden: true }

]

const createRouter = () => new Router({

  // mode: 'history', // require service support

  scrollBehavior: () => ({ y: 0 }),

  routes: constantRoutes

})

const router = createRouter()

// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465

export function resetRouter() {

  const newRouter = createRouter()

  router.matcher = newRouter.matcher // reset router

}

export default router

安装ES6语法插件


npm install --save es6-promise

引用Axios 插件,新建http.js插入如下位置

image

http.js:

···

import Vue from 'vue';

import Axios from 'axios';

import {Promise} from 'es6-promise';

import {MessageBox, Message} from 'element-ui'

Axios.defaults.timeout = 30000; // 1分钟

Axios.defaults.baseURL = '';

Axios.interceptors.request.use(function (config) {

// Do something before request is sent

//change method for get

/*if(process.env.NODE_ENV == 'development'){

  config['method'] = 'GET';

  console.log(config)

}*/

if (config['MSG']) {

// Vue.prototype.$showLoading(config['MSG']);

} else {

// Vue.prototype.$showLoading();

}

// if(user.state.token){//用户登录时每次请求将token放入请求头中

// config.headers["token"] = user.state.token;

// }

if (config['Content-Type'] === 'application/x-www-form-urlencoded;') {//默认发application/json请求,如果application/x-www-form-urlencoded;需要使用transformRequest对参数进行处理

/*config['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';*/

config.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';

config['transformRequest'] = function (obj) {

  var str = [];

  for (var p in obj)

    str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));

  return str.join("&")

};

}

//config.header['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

return config;

}, function (error) {

// Do something with request error

// Vue.$vux.loading.hide()

return Promise.reject(error);

});

Axios.interceptors.response.use(

response => {

// Vue.$vux.loading.hide();

return response.data;

},

error => {

// Vue.$vux.loading.hide();

if (error.response) {

  switch (error.response.status) {

    case 404:

      Message({

        message: '' || 'Error',

        type: 'error',

        duration: 5 * 1000

      })

      break;

    default:

      Message({

        message: '' || 'Error',

        type: 'error',

        duration: 5 * 1000

      })

  }

} else if (error instanceof Error) {

  console.error(error);

} else {

  Message({

    message: '' || 'Error',

    type: 'error',

    duration: 5 * 1000

  })

}

return Promise.reject(error.response);

});

export default Vue.prototype.$http = Axios;


配置axios代理:

vue.config.js

'use strict'

const path = require('path')

const defaultSettings = require('./src/settings.js')

function resolve(dir) {

return path.join(__dirname, dir)

}

const name = defaultSettings.title || 'vue Admin Template' // page title

// If your port is set to 80,

// use administrator privileges to execute the command line.

// For example, Mac: sudo npm run

// You can change the port by the following methods:

// port = 9528 npm run dev OR npm run dev --port = 9528

const port = process.env.port || process.env.npm_config_port || 9528 // dev port

// All configuration item explanations can be find in https://cli.vuejs.org/config/

module.exports = {

/**

*/

publicPath: '/',

outputDir: 'dist',

assetsDir: 'static',

lintOnSave: process.env.NODE_ENV === 'development',

productionSourceMap: false,

devServer: {

port: port,

open: true,

overlay: {

  warnings: false,

  errors: true

},

proxy: {

  // change xxx-api/login => mock/login

  // detail: https://cli.vuejs.org/config/#devserver-proxy

  [process.env.VUE_APP_BASE_API]: {

    target: `http://127.0.0.1:${port}/mock`,

    changeOrigin: true,

    pathRewrite: {

      ['^' + process.env.VUE_APP_BASE_API]: ''

    }

  },

  ['/api']: {

    target: `http://127.0.0.1:3000`,

    changeOrigin: true,

    pathRewrite: {

      ['^' + '/api']: ''

    }

  }

},

after: require('./mock/mock-server.js')

},

configureWebpack: {

// provide the app's title in webpack's name field, so that

// it can be accessed in index.html to inject the correct title.

name: name,

resolve: {

  alias: {

    '@': resolve('src')

  }

}

},

chainWebpack(config) {

config.plugins.delete('preload') // TODO: need test

config.plugins.delete('prefetch') // TODO: need test

// set svg-sprite-loader

config.module

  .rule('svg')

  .exclude.add(resolve('src/icons'))

  .end()

config.module

  .rule('icons')

  .test(/\.svg$/)

  .include.add(resolve('src/icons'))

  .end()

  .use('svg-sprite-loader')

  .loader('svg-sprite-loader')

  .options({

    symbolId: 'icon-[name]'

  })

  .end()

// set preserveWhitespace

config.module

  .rule('vue')

  .use('vue-loader')

  .loader('vue-loader')

  .tap(options => {

    options.compilerOptions.preserveWhitespace = true

    return options

  })

  .end()

config

// https://webpack.js.org/configuration/devtool/#development

  .when(process.env.NODE_ENV === 'development',

    config => config.devtool('cheap-source-map')

  )

config

  .when(process.env.NODE_ENV !== 'development',

    config => {

      config

        .plugin('ScriptExtHtmlWebpackPlugin')

        .after('html')

        .use('script-ext-html-webpack-plugin', [{

          // `runtime` must same as runtimeChunk name. default is `runtime`

          inline: /runtime\..*\.js$/

        }])

        .end()

      config

        .optimization.splitChunks({

        chunks: 'all',

        cacheGroups: {

          libs: {

            name: 'chunk-libs',

            test: /[\\/]node_modules[\\/]/,

            priority: 10,

            chunks: 'initial' // only package third parties that are initially dependent

          },

          elementUI: {

            name: 'chunk-elementUI', // split elementUI into a single package

            priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app

            test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm

          },

          commons: {

            name: 'chunk-commons',

            test: resolve('src/components'), // can customize your rules

            minChunks: 3, //  minimum common number

            priority: 5,

            reuseExistingChunk: true

          }

        }

      })

      config.optimization.runtimeChunk('single')

    }

  )

}

}


main.js中加入http

import http from './utils/http'

Vue.use(http)


调用接口:

index.vue:

<template>

<div class="dashboard-container">

欢迎

</div>

</template>

<script>

import { mapGetters } from 'vuex'

export default {

name: 'Dashboard',

computed: {

...mapGetters([

  'name'

])

},

mounted() {

this.$http.get('/api/users/add').then(res =>{

  console.log('this.panels',res)

})

}

}

</script>

<style lang="scss" scoped>

.dashboard {

&-container {

margin: 30px;

}

&-text {

font-size: 30px;

line-height: 46px;

}

}

</style>


# 全局安装koa-generator,执行下面命令

npm install -g koa-generator


# 构建koa2项目代码如下

koa2 projectName


构建成功信息:

D:\project>koa2 projectName

create : projectName

create : projectName/package.json

create : projectName/app.js

create : projectName/public

create : projectName/public/images

create : projectName/routes

create : projectName/routes/index.js

create : projectName/routes/users.js

create : projectName/views

create : projectName/views/index.pug

create : projectName/views/layout.pug

create : projectName/views/error.pug

create : projectName/public/stylesheets

create : projectName/public/stylesheets/style.css

create : projectName/bin

create : projectName/bin/www

install dependencies:

> cd projectName && npm install

run the app:

> SET DEBUG=koa* & npm start projectName

create : projectName/public/javascripts

D:\project>


初始化后台项目插件,命令属下:

cd projectName


初始化项目,如果没有安装git会报错.

npm install


项目试运行

npm run dev


这里koa2模板提示信息做的并不好,没有输出测试地址,成功后出现如下界面代表成功了。

D:\project\projectName>npm run dev

projectName@0.1.0 dev D:\project\projectName

nodemon bin/www

[nodemon] 1.19.4

[nodemon] to restart at any time, enter rs

[nodemon] watching dir(s): .

[nodemon] watching extensions: js,mjs,json

[nodemon] starting node bin/www


在浏览器打开地址:

[http://localhost:3000/](https://links.jianshu.com/go?to=http%3A%2F%2Flocalhost%3A3000%2F)

出现koa2的欢迎界面就代表成功了。

# 安装本地mongodb或者在[mongodb官网](https://links.jianshu.com/go?to=http%3A%2F%2Fwww.cloud.mongodb.com)新建免费的云端服务器。

> 本人在这里用的mongodb免费云端数据库。
> 
> 需要自行填写用户和密码及数据库名
> 
> 链接如下:

mongodb+srv://<用户名>:<密码填写>@cluster0.immyf.mongodb.net/<数据库名>?retryWrites=true&w=majority


安装mongoose

npm install mongoose --save


在刚刚新建好的projectName中创建db目录

![image](https://upload-images.jianshu.io/upload_images/25454112-ed6220a60a806004.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

下面代码中连接密码需要修改成自己的:

config.js:

module.exports = {

// dbs: 'mongodb://139.159.253.110:27017/test1'

dbs: 'mongodb+srv://xxwozixin:<需要修改>@cluster0-7d5kk.mongodb.net/test?retryWrites=true&w=majority'

}


user.js:

const mongoose = require('mongoose')

const feld={

name: String,

age: Number,

//人物标签

labels:Number

}

//自动添加更新时间创建时间:

let personSchema = new mongoose.Schema(feld, {timestamps: {createdAt: 'created', updatedAt: 'updated'}})

module.exports= mongoose.model('User',personSchema)


修改projectName下的app.js

app.js:

const Koa = require('koa')

const app = new Koa()

const views = require('koa-views')

const json = require('koa-json')

const onerror = require('koa-onerror')

const bodyparser = require('koa-bodyparser')

const logger = require('koa-logger')

const index = require('./routes/index')

const users = require('./routes/users')

const mongoose = require('mongoose')

const dbconfig = require('./db/config')

mongoose.connect(dbconfig.dbs, {useNewUrlParser: true,useUnifiedTopology: true})

const db = mongoose.connection

db.on('error', console.error.bind(console, 'connection error:'));

db.once('open', function() {

console.log('mongoose 连接成功')

});

// error handler

onerror(app)

// middlewares

app.use(bodyparser({

enableTypes:['json', 'form', 'text']

}))

app.use(json())

app.use(logger())

app.use(require('koa-static')(__dirname + '/public'))

app.use(views(__dirname + '/views', {

extension: 'pug'

}))

// logger

app.use(async (ctx, next) => {

const start = new Date()

await next()

const ms = new Date() - start

console.log(${ctx.method} ${ctx.url} - ${ms}ms)

})

// routes

app.use(index.routes(), index.allowedMethods())

app.use(users.routes(), users.allowedMethods())

// error-handling

app.on('error', (err, ctx) => {

console.error('server error', err, ctx)

});

module.exports = app

// error handler

onerror(app)

// middlewares

app.use(bodyparser({

enableTypes:['json', 'form', 'text']

}))

app.use(json())

app.use(logger())

app.use(require('koa-static')(__dirname + '/public'))

app.use(views(__dirname + '/views', {

extension: 'pug'

}))

// logger

app.use(async (ctx, next) => {

const start = new Date()

await next()

const ms = new Date() - start

console.log(${ctx.method} ${ctx.url} - ${ms}ms)

})

// routes

app.use(index.routes(), index.allowedMethods())

app.use(users.routes(), users.allowedMethods())

// error-handling

app.on('error', (err, ctx) => {

console.error('server error', err, ctx)

});

module.exports = app


user.js:

const mongoose = require('mongoose')

const feld={

name: String,

age: Number,

//人物标签

labels:Number

}

//自动添加更新时间创建时间:

let personSchema = new mongoose.Schema(feld, {timestamps: {createdAt: 'created', updatedAt: 'updated'}})

module.exports= mongoose.model('User',personSchema)


修改app.js:

const Koa = require('koa')

const app = new Koa()

const views = require('koa-views')

const json = require('koa-json')

const onerror = require('koa-onerror')

const bodyparser = require('koa-bodyparser')

const logger = require('koa-logger')

const mongoose = require('mongoose')

const dbconfig = require('./db/config')

mongoose.connect(dbconfig.dbs,{useNewUrlParser: true,useUnifiedTopology: true})

const db = mongoose.connection

db.on('error',console.error.bind(console,'connection error:'));

db.once('open',function () {

console.log('mongoose 连接成功')

});

// error handler

onerror(app)

// middlewares

app.use(bodyparser({

enableTypes:['json', 'form', 'text']

}))

app.use(json())

app.use(logger())

app.use(require('koa-static')(__dirname + '/public'))

app.use(views(__dirname + '/views', {

extension: 'pug'

}))

// logger

app.use(async (ctx, next) => {

const start = new Date()

await next()

const ms = new Date() - start

console.log(${ctx.method} ${ctx.url} - ${ms}ms)

})

const index = require('./routes/index')

app.use(index.routes(), index.allowedMethods())

const users = require('./routes/users')

app.use(users.routes(), users.allowedMethods())

// error-handling

// routes

app.on('error', (err, ctx) => {

console.error('server error', err, ctx)

});

module.exports = app


users.js中添加user的路由

projectName/routes/users.js:

const router = require('koa-router')()

const User = require('../db/models/user')

router.prefix('/users')

router.get('/add', function (ctx, next) {

ctx.body = 'this is a users/add response'

})

router.get('/', function (ctx, next) {

ctx.body = 'this is a users response!'

})

router.get('/bar', function (ctx, next) {

ctx.body = 'this is a users/bar response'

})

module.exports = router


# 重启项目

关闭正在运行的dev后,重新启动服务

npm run dev


如果出现了一下信息,则数据库连接成功

E:\nodejs\node.exe E:\nodejs\node_modules\npm\bin\npm-cli.js run dev --scripts-prepend-node-path=auto

projectName@0.1.0 dev E:\nodejs\vue\projectName

nodemon bin/www

[nodemon] 1.19.4

[nodemon] to restart at any time, enter rs

[nodemon] watching dir(s): .

[nodemon] watching extensions: js,mjs,json

[nodemon] starting node bin/www

mongoose 连接成功


效果图:

![image](https://upload-images.jianshu.io/upload_images/25454112-9085240612f5e1ce.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

到此整个前后端平台搭建成功,可以开始创建项目了
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容