nodejs vue-element-admin (實(shí)訓(xùn)1)

1.安裝 nodejs

2.安裝 git

3.下載 vue-element-admin

建議
本項(xiàng)目的定位是后臺(tái)集成方案狂塘,不太適合當(dāng)基礎(chǔ)模板來(lái)進(jìn)行二次開發(fā)录煤。因?yàn)楸卷?xiàng)目集成了很多你可能用不到的功能凶掰,會(huì)造成不少的代碼冗余粉捻。如果你的項(xiàng)目不關(guān)注這方面的問題,也可以直接基于它進(jìn)行二次開發(fā)搂根。


# clone the project
git 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
啟動(dòng)成功
啟動(dòng)成功圖片
  • 刪除多余界面 router/index
    刪除后的界面如下
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語(yǔ)法插件

npm install --save es6-promise

本人使用了自己寫的Axios 插件


http.js存放位置

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){//用戶登錄時(shí)每次請(qǐng)求將token放入請(qǐng)求頭中
  //   config.headers["token"] = user.state.token;
  // }

  if (config['Content-Type'] === 'application/x-www-form-urlencoded;') {//默認(rèn)發(fā)application/json請(qǐng)求硝训,如果application/x-www-form-urlencoded;需要使用transformRequest對(duì)參數(shù)進(jìn)行處理
    /*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

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 = {
  /**
   * You will need to set publicPath if you plan to deploy your site under a sub path,
   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
   * then publicPath should be set to "/bar/".
   * In most cases please use '/' !!!
   * Detail: https://cli.vuejs.org/config/#publicpath
   */
  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)

調(diào)用接口:


index.vue

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>

6.全局安裝koa-generator,執(zhí)行下面命令

npm install -g koa-generator

7.構(gòu)建koa2項(xiàng)目代碼如下

koa2 projectName

構(gòu)建成功信息:

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>

初始化后臺(tái)項(xiàng)目插件响委,命令屬下:

cd projectName

初始化項(xiàng)目,如果沒有安裝git會(huì)報(bào)錯(cuò).

npm install

項(xiàng)目試運(yùn)行

npm run dev

這里koa2模板提示信息做的并不好窖梁,沒有輸出測(cè)試地址赘风,成功后出現(xiàn)如下界面代表成功了。

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/
出現(xiàn)koa2的歡迎界面就代表成功了纵刘。

8.安裝本地mongodb或者在mongodb官網(wǎng)新建免費(fèi)的云端服務(wù)器邀窃。

本人在這里用的mongodb免費(fèi)云端數(shù)據(jù)庫(kù)。
抱歉密碼不能公開,請(qǐng)自行換成自己的密碼
鏈接如下:

本人數(shù)據(jù)庫(kù)名為test

mongodb+srv://xxwozixin:<password>@cluster0-7d5kk.mongodb.net/test?retryWrites=true&w=majority

安裝mongoose

npm install mongoose --save

在第7步建好的nodejs項(xiàng)目中根目錄創(chuàng)建db目錄
作者用的webstorm,可以根據(jù)自己需要下載編輯器


db目錄
下面代碼中連接密碼需要修改成自己的

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,
    //人物標(biāo)簽
    labels:Number
}
//自動(dòng)添加更新時(shí)間創(chuàng)建時(shí)間:
let personSchema = new mongoose.Schema(feld, {timestamps: {createdAt: 'created', updatedAt: 'updated'}})
module.exports= mongoose.model('User',personSchema)

修改根目錄app.js


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 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/bar 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

重啟項(xiàng)目
關(guān)掉前面我們啟動(dòng)的服務(wù)在運(yùn)行

npm run dev

如下結(jié)果代表成功連接數(shù)據(jù)庫(kù)


運(yùn)行成功

到這里前后端就連接通了瞬捕,可以開始操作數(shù)據(jù)庫(kù)鞍历。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市肪虎,隨后出現(xiàn)的幾起案子劣砍,更是在濱河造成了極大的恐慌,老刑警劉巖扇救,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刑枝,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡迅腔,警方通過查閱死者的電腦和手機(jī)装畅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)沧烈,“玉大人掠兄,你說我怎么就攤上這事⌒咳福” “怎么了徽千?”我有些...
    開封第一講書人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)汤锨。 經(jīng)常有香客問我,道長(zhǎng)百框,這世上最難降的妖魔是什么闲礼? 我笑而不...
    開封第一講書人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮铐维,結(jié)果婚禮上柬泽,老公的妹妹穿的比我還像新娘。我一直安慰自己嫁蛇,他們只是感情好锨并,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著睬棚,像睡著了一般第煮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抑党,一...
    開封第一講書人閱讀 49,785評(píng)論 1 290
  • 那天包警,我揣著相機(jī)與錄音,去河邊找鬼底靠。 笑死害晦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的暑中。 我是一名探鬼主播壹瘟,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼鲫剿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了稻轨?” 一聲冷哼從身側(cè)響起灵莲,我...
    開封第一講書人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎澄者,沒想到半個(gè)月后笆呆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粱挡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年赠幕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片询筏。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡榕堰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嫌套,到底是詐尸還是另有隱情逆屡,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布踱讨,位于F島的核電站魏蔗,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏痹筛。R本人自食惡果不足惜莺治,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帚稠。 院中可真熱鬧谣旁,春花似錦、人聲如沸滋早。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)杆麸。三九已至搁进,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昔头,已是汗流浹背拷获。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留减细,地道東北人匆瓜。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親驮吱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茧妒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 基于Vue的一些資料 內(nèi)容 UI組件 開發(fā)框架 實(shí)用庫(kù) 服務(wù)端 輔助工具 應(yīng)用實(shí)例 Demo示例 element★...
    嘗了又嘗閱讀 1,142評(píng)論 0 1
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫(kù) m...
    王喂馬_閱讀 6,448評(píng)論 1 77
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫(kù) m...
    你猜_3214閱讀 11,043評(píng)論 0 118
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫(kù) m...
    柴東啊閱讀 15,849評(píng)論 2 140
  • 經(jīng)常聽到有人說,我好像天生瞌睡蟲左冬,每天都有睡不完的覺桐筏,每天都很困,粘床就睡拇砰;與此同時(shí)梅忌,每次睡醒起來(lái),卻不見得精神抖...
    輕暖艷陽(yáng)閱讀 750評(píng)論 0 0