網(wǎng)站前端開發(fā)-校園管理系統(tǒng)實訓(xùn)

實訓(xùn)一

1拾给、安裝 nodejs

進(jìn)入 node 網(wǎng)站:https://nodejs.org/zh-cn/上祈,下載nodejs

根據(jù)自己電腦系統(tǒng)及位數(shù)選擇递胧,選擇windows64位.msi格式安裝包

image.png

image.png

image.png

打開cmd窗口,執(zhí)行命令node -v查看node版本
v14.7.0
最新版的node在安裝時同時也安裝了npm,執(zhí)行npm -v查看npm版本

F:\網(wǎng)頁UI實訓(xùn)\nodejs\node_modules\npm>node -v
v14.15.1

2、安裝 git

進(jìn)入 git 網(wǎng)站:https://git-scm.com/downloads乏沸,下載git

前端:

3冲粤、下載 vue-admin-template(前端)

建議
本項目的定位是后臺集成方案美莫,不太適合當(dāng)基礎(chǔ)模板來進(jìn)行二次開發(fā)。因為本項目集成了很多你可能用不到的功能梯捕,會造成不少的代碼冗余厢呵。如果你的項目不關(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
image.png

項目運行成功后打開瀏覽器

輸入網(wǎng)址:http://localhost:9528/
可以看到以下界面:


image.png

4襟铭、開始創(chuàng)建項目

我所使用的開發(fā)軟件是JetBrains WebStorm
①下載vue-admin-template
②進(jìn)入vue-admin-template項目
③初始化vue-admin-template項目
④運行vue-admin-template

clone the project
git clone https://gitee.com/xdnclover/vue-admin-template.git* enter the project directory
cd vue-admin-template* install dependency
npm install* develop
npm run dev

image.png

image.png

5、編輯vue-admin-template項目

(1)找到vue-admin-template/src/router/index.js短曾,將以下代碼刪除

image.png
 {
    path: '/example',
    component: Layout,
    redirect: '/example/table',
    name: 'Example',
    meta: { title: 'Example', icon: 'example' },
    children: [
      {
        path: 'table',
        name: 'Table',
        component: () => import('@/views/table/index'),
        meta: { title: 'Table', icon: 'table' }
      },
      {
        path: 'tree',
        name: 'Tree',
        component: () => import('@/views/tree/index'),
        meta: { title: 'Tree', icon: 'tree' }
      }
    ]
  },
{
    path: '/form',
    component: Layout,
    children: [
      {
        path: 'index',
        name: 'Form',
        component: () => import('@/views/form/index'),
        meta: { title: 'Form', icon: 'form' }
      }
    ]
  },
  {
    path: '/nested',
    component: Layout,
    redirect: '/nested/menu1',
    name: 'Nested',
    meta: {
      title: 'Nested',
      icon: 'nested'
    },
    children: [
      {
        path: 'menu1',
        component: () => import('@/views/nested/menu1/index'), // Parent router-view
        name: 'Menu1',
        meta: { title: 'Menu1' },
        children: [
          {
            path: 'menu1-1',
            component: () => import('@/views/nested/menu1/menu1-1'),
            name: 'Menu1-1',
            meta: { title: 'Menu1-1' }
          },
          {
            path: 'menu1-2',
            component: () => import('@/views/nested/menu1/menu1-2'),
            name: 'Menu1-2',
            meta: { title: 'Menu1-2' },
            children: [
              {
                path: 'menu1-2-1',
                component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
                name: 'Menu1-2-1',
                meta: { title: 'Menu1-2-1' }
              },
              {
                path: 'menu1-2-2',
                component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
                name: 'Menu1-2-2',
                meta: { title: 'Menu1-2-2' }
              }
            ]
          },
          {
            path: 'menu1-3',
            component: () => import('@/views/nested/menu1/menu1-3'),
            name: 'Menu1-3',
            meta: { title: 'Menu1-3' }
          }
        ]
      },
      {
        path: 'menu2',
        component: () => import('@/views/nested/menu2/index'),
        meta: { title: 'menu2' }
      }
    ]
  },
  {
    path: 'external-link',
    component: Layout,
    children: [
      {
        path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
        meta: { title: 'External Link', icon: 'link' }
      }
    ]
  },

則index.js的內(nèi)容為:

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

效果圖:

image.png

(2)安裝ES6語法插件

npm install --save es6-promise
image.png

(3)編寫Axios 插件

①在vue-admin-template/src/untils中添加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;') {//默認(rèn)發(fā)application/json請求寒砖,如果application/x-www-form-urlencoded;需要使用transformRequest對參數(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代理:

添加部分為:
image.png
修改完vue.config.js的代碼為:
vue-admin-template/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')
        }
      )
  }
}

(4)在vue-admin-template/src/utils/main.js添加http的路由

import http from './utils/http'
Vue.use(http)
image.png

(5)在dashboard中調(diào)用接口

添加部分為:
image.png
vue-admin-template/src/views/dashboard/index.vue:
vue-admin-template/src/views/dashboard/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

①下載koa-generator:
npm install -g koa-generator
②構(gòu)建koa2項目(搭建后端項目平臺):
koa2 projectName
成功的信息:
E:\nodejs\vue\vue-admin-template>koa2 projectName

   create : projectName
   create : projectName/package.json
   create : projectName/app.js
   create : projectName/public
   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/bin
   create : projectName/bin/www
   create : projectName/public/stylesheets
   create : projectName/public/stylesheets/style.css

   install dependencies:
     > cd projectName && npm install

   run the app:
     > SET DEBUG=koa* & npm start projectName

   create : projectName/public/javascripts
   create : projectName/public/images
③進(jìn)入projectName項目:
cd projectName

④初始化projectName項目
npm install
⑤運行projectName項目
npm run dev

這里koa2模板提示信息做的并不好,沒有輸出測試地址嫉拐,成功后出現(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`

在瀏覽器打開地址:(默認(rèn)是3000)

http://localhost:3000/

出現(xiàn)koa2的歡迎界面就代表成功了。
http://localhost:3000/

或者
可以使用基礎(chǔ)模板:projectName
直接下載即可

7椭岩、安裝本地mongodb或者在mongodb官網(wǎng)新建免費的云端服務(wù)器

數(shù)據(jù)庫代碼(這是我的數(shù)據(jù)庫茅逮,若有建此項目時,需要換成自己的數(shù)據(jù)庫):

module.exports = {
    // dbs: 'mongodb://139.159.253.110:27017/test1'
    dbs: 'mongodb+srv://<clusers用戶名>:123@cluster0.kfozz.mongodb.net/test?retryWrites=true&w=majority'
}
module.exports = {
    // dbs: 'mongodb://139.159.253.110:27017/test1'
    dbs: 'mongodb+srv://<用戶名>:<密碼>@cluster0.kfozz.mongodb.net/<數(shù)據(jù)庫名>?retryWrites=true&w=majority'
}
如何創(chuàng)建自己的數(shù)據(jù)庫:/
找到mongodb的官網(wǎng)判哥,注冊登錄
image.png

第一步:創(chuàng)建集群


image.png

如果已經(jīng)有了集群的界面如下


image.png
第二步:創(chuàng)建用戶(注意記住帳號密碼献雅,為后邊登錄帳號密碼)

image.png

image.png

image.png

第三步:創(chuàng)建IP白名單
image.png

0.0.0.0/0代表所有IP都可以訪問!
image.png
第四步:load Sample Data
image.png

第五步:創(chuàng)建數(shù)據(jù)庫
image.png

image.png

image.png
image.png

創(chuàng)建完成如下
image.png

連接數(shù)據(jù)庫
image.png
選擇connect,就會出現(xiàn)以下界面
image.png
選擇Connect Your Application塌计,就會出現(xiàn)以下界面
image.png

8挺身、安裝mongoose

npm install mongoose --save

若安裝過程問題:卡著不動

例如如下:


image.png

解決該問題如下:

建議不要直接使用 cnpm 安裝以來,會有各種詭異的 bug锌仅≌录兀可以通過如下操作解決 npm 下載速度慢的問題

npm install --registry=https://registry.npm.taobao.org

9、編輯projectName項目

在projectName下創(chuàng)建db目錄:

db目錄

①在db下創(chuàng)建config.js

image.png

projectName/db/config.js:

module.exports = {
    // dbs: 'mongodb://139.159.253.110:27017/test1'
    dbs: 'mongodb+srv://yuejia:<password>@cluster0.kfozz.mongodb.net/test?retryWrites=true&w=majority'
}

此處需要修改為上面的數(shù)據(jù)庫鏈接热芹,還要將密碼填寫進(jìn)去

②在db下創(chuàng)建models目錄

image.png

在models創(chuàng)建user.js

projectName/db/models/user.js:

const mongoose = require('mongoose')
const feld={
    name: String,
    age: Number,
    //人物標(biāo)簽
    labels:Number
}
//自動添加更新時間創(chuàng)建時間:
let personSchema = new mongoose.Schema(feld, {timestamps: {createdAt: 'created', updatedAt: 'updated'}})
module.exports= mongoose.model('User',personSchema)

③修改app.js

添加部分為:

image.png
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:

image.png
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

10贱傀、重啟項目

關(guān)閉正在運行的dev后,重新啟動服務(wù)

npm run dev

如果出現(xiàn)了一下信息伊脓,則數(shù)據(jù)庫連接成功

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.png

到此整個前后端平臺搭建成功府寒,可以開始創(chuàng)建項目了

實訓(xùn)二

學(xué)校管理篇

一、從后端(projectName)添加學(xué)校模塊

1、在models目錄下添加school.js:

projectName/db/models/school.js:

const mongoose = require('mongoose')
const feld={
    name: String,
    //人物標(biāo)簽
    where:String,
    leixing: String
}
//自動添加更新時間創(chuàng)建時間:
let personSchema = new mongoose.Schema(feld, {timestamps: {createdAt: 'created', updatedAt: 'updated'}})
module.exports= mongoose.model('School',personSchema)

2株搔、在routes目錄下添加school.js:

const router = require('koa-router')()
//建立模塊剖淀,require(“../db/models/文件名”)
let Model = require("../db/models/school");
router.prefix('/school')

router.get('/', function (ctx, next) {
    ctx.body = 'this is a users response!'
})

//數(shù)據(jù)庫增刪改查
router.post('/add', async function (ctx, next) {
    console.log(ctx.request.body)
    let model = new Model(ctx.request.body);
    model = await model.save();
    console.log('user',model)
    ctx.body = model
})

router.post('/find', async function (ctx, next) {
    let models = await Model.
    find({})
    ctx.body = models
})

router.post('/get', async function (ctx, next) {
    // let users = await User.
    // find({})
    console.log(ctx.request.body)
    let model = await Model.find(ctx.request.body)
    console.log(model)
    ctx.body = model
})

router.post('/update', async function (ctx, next) {
    console.log(ctx.request.body)
    let pbj = await Model.update({ _id: ctx.request.body._id }, ctx.request.body);
    ctx.body = pbj
})
router.post('/delete', async function (ctx, next) {
    console.log(ctx.request.body)
    await Model.remove({ _id: ctx.request.body._id });
    ctx.body = 'shibai '
})
module.exports = router

3、在app.js中加上school模塊的路由:

添加部分為:

school模塊路由

代碼如下projectName/app.js:

const school = require('./routes/school')
app.use(school.routes(),school.allowedMethods())

總代碼:

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())
const school = require('./routes/school')
app.use(school.routes(),school.allowedMethods())
// error-handling

// routes


app.on('error', (err, ctx) => {
  console.error('server error', err, ctx)
});

module.exports = app

二纤房、從前端(vue-admin-template)添加學(xué)校模塊

1纵隔、在src/views目錄下添加school目錄(模塊),如圖所示:

前端布局的school模塊
①在school目錄下添加editor.vue:
vue-admin-template/src/views/school/editor.vue:
<template>
  <div class="dashboard-container">
    <el-form ref="form" :model="form" label-width="80px">
      <el-form-item label="學(xué)校名稱">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="位置">
        <el-input v-model="form.where"></el-input>
      </el-form-item>
      <el-form-item label="類型">
        <el-input v-model="form.leixing"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">立即創(chuàng)建</el-button>
        <el-button>取消</el-button>
      </el-form-item>

    </el-form>
  </div>
</template>

<script>
  import { mapGetters } from 'vuex'

  export default {
    name: 'school',
    computed: {
      ...mapGetters([
        'name'
      ])
    },
    data(){
      return{
        apiModel:'school',
        form:{}
      }
    },
    methods:{
      onSubmit(){
        console.log('222:', 222)
        if(this.form._id){
          this.$http.post(`/api/${this.apiModel}/update`,this.form).then(res => {
            console.log('bar:', res)
            this.$router.push({path:this.apiModel})
            this.form={}
          })
        }else
        {
          this.$http.post('/api/'+this.apiModel+'/add',this.form).then(res => {
            console.log('bar:', res)
            this.$router.push({path:this.apiModel})
            this.form={}
          })
        }
      }
    },
    mounted() {
      if(this.$route.query._id){
        this.$http.post('/api/'+this.apiModel+'/get',{_id:this.$route.query._id}).then(res => {
          if(res&&res.length>0){
            this.form = res[0]
          }
        })
      }
    }
  }
</script>

<style lang="scss" scoped>
  .dashboard {
    &-container {
      margin: 30px;
    }
    &-text {
      font-size: 30px;
      line-height: 46px;
    }
  }
</style>
效果圖:
editor.vue的效果圖
②在school目錄下添加index.vue:
vue-admin-template/src/views/school/index.vue:
<template>
  <div class="dashboard-container">
    <el-table
      :data="users"
      style="width: 100%"
      :row-class-name="tableRowClassName">
      <!--      <el-table-column-->
      <!--        prop="_id"-->
      <!--        label="學(xué)校_id"-->
      <!--        width="180">-->
      <!--      </el-table-column>-->
      <el-table-column
        prop="name"
        label="學(xué)校名稱"
        width="180">
      </el-table-column>
      <el-table-column
        prop="where"
        label="位置"
        width="180">
      </el-table-column>
      <el-table-column
        prop="leixing"
        label="類型">
      </el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button
            size="mini"
            @click="handleEdit(scope.$index, scope.row)">編輯
          </el-button>
          <el-button
            size="mini"
            type="danger"
            @click="handleDelete(scope.$index, scope.row)">刪除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
  import { mapGetters } from 'vuex'

  export default {
    name: 'school',
    computed: {
      ...mapGetters([
        'name'
      ])
    },
    data() {
      return {
        apiModel:'school',
        users: {}
      }
    },
    methods: {
      onSubmit() {
        console.log(123434)
      },
      handleEdit(index, item) {
        this.$router.push({ path: '/'+this.apiModel+'/editor', query: {_id:item._id} })
      },
      handleDelete(index, item) {
        this.$http.post('/api/'+this.apiModel+'/delete', item).then(res => {
          console.log('res:', res)
          this.findUser()
        })

      },
      findUser(){
        this.$http.post('/api/'+this.apiModel+'/find', this.user).then(res => {
          console.log('res:', res)
          this.users = res
        })
      }
    },
    mounted() {
      this.findUser()
    }
  }
</script>

<style lang="scss" scoped>
  .dashboard {
    &-container {
      margin: 30px;
    }

    &-text {
      font-size: 30px;
      line-height: 46px;
    }
  }
</style>
效果圖:
index.vue的效果圖

2炮姨、在router下的index.js中添加school模塊的路由:

添加部分:
school模塊的路由
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: '/school',
    component: Layout,
    meta: { title: '學(xué)校管理', icon: 'example' },
    redirect: 'school',
    children: [{
      path: 'school',
      name: 'school',
      component: () => import('@/views/school'),
      meta: { title: '學(xué)校管理', icon: 'school' }
    },
      {
        path: 'editor',
        name: 'editor',
        component: () => import('@/views/school/editor'),
        meta: { title: '添加學(xué)校', icon: 'school' }
      }]
  },

  {
    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

這樣學(xué)校管理模塊就構(gòu)建好了捌刮,最終的效果圖

學(xué)校管理模塊

實訓(xùn)三

學(xué)院管理篇(可將學(xué)校與學(xué)院關(guān)聯(lián)起來)

一、從后端(projectName)添加學(xué)院模塊

1剑令、在models目錄下添加academy.js:

image.png

projectName/db/models/academy.js:

const mongoose = require('mongoose')
const Schema= mongoose.Schema
const feld={
    name: String,
    //人物標(biāo)簽
    major:String,
    renshu: Number,
    school : { type: Schema.Types.ObjectId, ref: 'School' }
}
//自動添加更新時間創(chuàng)建時間:
let schema = new Schema(feld, {timestamps: {createdAt: 'created', updatedAt: 'updated'}})
module.exports= mongoose.model('Academy',schema)

2糊啡、在routes目錄下添加academy.js:

projectName/routes/academy.js:

const router = require('koa-router')()
let Model = require("../db/models/academy");
router.prefix('/academy')

router.get('/', function (ctx, next) {
    ctx.body = 'this is a users response!'
})

router.post('/add', async function (ctx, next) {
    console.log(ctx.request.body)
    let model = new Model(ctx.request.body);
    model = await model.save();
    console.log('user',model)
    ctx.body = model
})

router.post('/find', async function (ctx, next) {
    let models = await Model.
    find({}).populate('school')
    ctx.body = models
})

router.post('/get', async function (ctx, next) {
    // let users = await User.
    // find({})
    console.log(ctx.request.body)
    let model = await Model.find(ctx.request.body)
    console.log(model)
    ctx.body = model
})

router.post('/update', async function (ctx, next) {
    console.log(ctx.request.body)
    let pbj = await Model.update({ _id: ctx.request.body._id }, ctx.request.body);
    ctx.body = pbj
})
router.post('/delete', async function (ctx, next) {
    console.log(ctx.request.body)
    await Model.remove({ _id: ctx.request.body._id });
    ctx.body = 'shibai '
})
module.exports = router

3、在app.js中加上academy模塊的路由:

添加部分為:

academy模塊的路由

projectName/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`)
})


// routes
const index = require('./routes/index')
app.use(index.routes(), index.allowedMethods())
const users = require('./routes/users')
app.use(users.routes(), users.allowedMethods())
const school = require('./routes/school')
app.use(school.routes(),school.allowedMethods())
const academy = require('./routes/academy')
app.use(academy.routes(), academy.allowedMethods())
// error-handling




app.on('error', (err, ctx) => {
  console.error('server error', err, ctx)
});

module.exports = app

二吁津、從前端(vue-admin-template)添加學(xué)院模塊

1棚蓄、在src/views目錄下添加academy目錄(模塊),如圖所示:

前端布局的academy模塊
①在academy目錄下添加editor.vue:
vue-admin-template/src/views/academy/editor.vue:
<template>
  <div class="dashboard-container">
    <el-form ref="form" :model="form" label-width="80px">
      <el-form-item label="學(xué)院名稱">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="專業(yè)">
        <el-input v-model="form.major"></el-input>
      </el-form-item>
      <el-form-item label="人數(shù)">
        <el-input v-model="form.renshu"></el-input>
      </el-form-item>

      <el-form-item label="所屬學(xué)校">
        <el-select v-model="form.school" placeholder="請選擇">
          <el-option
            v-for="item in options"
            :key="item._id"
            :label="item.name"
            :value="item._id">
          </el-option>
        </el-select>
      </el-form-item>


      <el-form-item>
        <el-button type="primary" @click="onSubmit">立即創(chuàng)建</el-button>
        <el-button>取消</el-button>
      </el-form-item>

    </el-form>
  </div>
</template>

<script>
  import { mapGetters } from 'vuex'

  export default {
    name: 'academy',
    computed: {
      ...mapGetters([
        'name'
      ])
    },
    data(){
      return{
        options: [

        ],
        apiModel:'academy',
        form:{}
      }
    },
    methods:{
      onSubmit(){
        console.log('222:', 222)
        if(this.form._id){
          this.$http.post(`/api/${this.apiModel}/update`,this.form).then(res => {
            console.log('bar:', res)
            this.$router.push({path:this.apiModel})
            this.form={}
          })
        }else
        {
          this.$http.post('/api/'+this.apiModel+'/add',this.form).then(res => {
            console.log('bar:', res)
            this.$router.push({path:this.apiModel})
            this.form={}
          })
        }
      }
    },
    mounted() {
      if(this.$route.query._id){
        this.$http.post('/api/'+this.apiModel+'/get',{_id:this.$route.query._id}).then(res => {
          if(res&&res.length>0){
            this.form = res[0]
          }
        })
      }

      this.$http.post('/api/school/find').then(res => {
        if(res&&res.length>0){
          this.options = res
          console.log('res:', res)
        }
      })
    }
  }
</script>

<style lang="scss" scoped>
  .dashboard {
    &-container {
      margin: 30px;
    }
    &-text {
      font-size: 30px;
      line-height: 46px;
    }
  }
</style>
效果圖:
editor.vue的效果圖
②在academy目錄下添加index.vue:
vue-admin-template/src/views/academy/index.vue:
<template>
  <div class="dashboard-container">
    <el-table
      :data="users"
      style="width: 100%"
      :row-class-name="tableRowClassName">

      <el-table-column
        prop="_id"
        label="學(xué)院_id"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="學(xué)院名稱"
        width="180">
      </el-table-column>
      <el-table-column
        prop="major"
        label="專業(yè)"
        width="180">
      </el-table-column>
      <el-table-column
        prop="renshu"
        label="人數(shù)">
      </el-table-column>

      <el-table-column
        prop="school"
        label="學(xué)校名稱"
        width="180">
        <template slot-scope="scope" >
          <span class="" v-if="scope.row.school">
            <el-tag
              :type="scope.row.school.name === '深信' ? 'primary' : 'success'"
              disable-transitions>{{scope.row.school.name}}</el-tag>
          </span>

        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button
            size="mini"
            @click="handleEdit(scope.$index, scope.row)">編輯
          </el-button>
          <el-button
            size="mini"
            type="danger"
            @click="handleDelete(scope.$index, scope.row)">刪除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
  import { mapGetters } from 'vuex'

  export default {
    name: 'academy',
    computed: {
      ...mapGetters([
        'name'
      ])
    },
    data() {
      return {
        apiModel:'academy',
        users: {}
      }
    },
    methods: {
      onSubmit() {
        console.log(123434)
      },
      handleEdit(index, item) {
        this.$router.push({ path: '/'+this.apiModel+'/editor', query: {_id:item._id} })
      },
      handleDelete(index, item) {
        this.$http.post('/api/'+this.apiModel+'/delete', item).then(res => {
          console.log('res:', res)
          this.findUser()
        })

      },
      findUser(){
        this.$http.post('/api/'+this.apiModel+'/find', this.user).then(res => {
          console.log('res:', res)
          this.users = res
        })
      }
    },
    mounted() {
      this.findUser()
    }
  }
</script>

<style lang="scss" scoped>
  .dashboard {
    &-container {
      margin: 30px;
    }

    &-text {
      font-size: 30px;
      line-height: 46px;
    }
  }
</style>     
效果圖:
index.vue的效果圖

2碍脏、在router下的index.js中添加academy模塊的路由:

添加部分:

academy模塊的路由

academy模塊的路由

vue-admin-template/src/router/index.js:

  {
    path: '/academy',
    component: Layout,
    meta: { title: '學(xué)院管理', icon: 'example' },
    redirect: 'academy',
    children: [{
      path: 'academy',
      name: 'academy',
      component: () => import('@/views/academy'),
      meta: { title: '學(xué)院管理', icon: 'academy' }
    },
      {
        path: 'editor',
        name: 'editor',
        component: () => import('@/views/academy/editor'),
        meta: { title: '添加學(xué)院', icon: 'academy' }
      }]
  },
總體代碼如下:
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: '/school',
    component: Layout,
    meta: { title: '學(xué)校管理', icon: 'example' },
    redirect: 'school',
    children: [{
      path: 'school',
      name: 'school',
      component: () => import('@/views/school'),
      meta: { title: '學(xué)校管理', icon: 'school' }
    },
      {
        path: 'editor',
        name: 'editor',
        component: () => import('@/views/school/editor'),
        meta: { title: '添加學(xué)校', icon: 'school' }
      }]
  },

  {
    path: '/academy',
    component: Layout,
    meta: { title: '學(xué)院管理', icon: 'example' },
    redirect: 'academy',
    children: [{
      path: 'academy',
      name: 'academy',
      component: () => import('@/views/academy'),
      meta: { title: '學(xué)院管理', icon: 'academy' }
    },
      {
        path: 'editor',
        name: 'editor',
        component: () => import('@/views/academy/editor'),
        meta: { title: '添加學(xué)院', icon: 'academy' }
      }]
  },

  {
    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

這樣學(xué)院管理模塊就構(gòu)建好了梭依,最終的效果圖:

學(xué)院管理模塊

實訓(xùn)四

校園管理(可將學(xué)校、學(xué)院與班級關(guān)聯(lián)起來)

一典尾、從后端(projectName)添加班級模塊

1役拴、在models目錄下添加classs.js:
image.png
projectName/db/models/classs.js:
const mongoose = require('mongoose')
const Schema= mongoose.Schema
const feld={
    name: String,
    //人物標(biāo)簽
    level:String,
    renshu: Number,
    school : { type: Schema.Types.ObjectId, ref: 'School' },
    academy : { type: Schema.Types.ObjectId, ref: 'Academy' }
}
//自動添加更新時間創(chuàng)建時間:
let personSchema = new mongoose.Schema(feld, {timestamps: {createdAt: 'created', updatedAt: 'updated'}})
module.exports= mongoose.model('Classs',personSchema)
2、在routes目錄下添加classs.js:
image.png
projectName/routes/classs.js:
const router = require('koa-router')()
let Model = require("../db/models/classs");
router.prefix('/classs')

router.get('/', function (ctx, next) {
    ctx.body = 'this is a users response!'
})

router.post('/add', async function (ctx, next) {
    console.log(ctx.request.body)
    let model = new Model(ctx.request.body);
    model = await model.save();
    console.log('user',model)
    ctx.body = model
})

router.post('/find', async function (ctx, next) {
    let models = await Model.
    find({}).populate('academy').populate('school')
    ctx.body = models
})


router.post('/get', async function (ctx, next) {
    // let users = await User.
    // find({})
    console.log(ctx.request.body)
    let model = await Model.find(ctx.request.body)
    console.log(model)
    ctx.body = model
})

router.post('/update', async function (ctx, next) {
    console.log(ctx.request.body)
    let pbj = await Model.update({ _id: ctx.request.body._id }, ctx.request.body);
    ctx.body = pbj
})
router.post('/delete', async function (ctx, next) {
    console.log(ctx.request.body)
    await Model.remove({ _id: ctx.request.body._id });
    ctx.body = 'shibai '
})
module.exports = router
3钾埂、在app.js中加上classs模塊的路由:
添加部分為:
classs模塊的路由
projectName/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`)
})


// routes
const index = require('./routes/index')
app.use(index.routes(), index.allowedMethods())
const users = require('./routes/users')
app.use(users.routes(), users.allowedMethods())
const school = require('./routes/school')
app.use(school.routes(),school.allowedMethods())
const academy = require('./routes/academy')
app.use(academy.routes(), academy.allowedMethods())
const classs = require('./routes/classs')
app.use(classs.routes(), classs.allowedMethods())
// error-handling




app.on('error', (err, ctx) => {
  console.error('server error', err, ctx)
});

module.exports = app

二河闰、從前端(vue-admin-template)添加班級模塊

1、在src/views目錄下添加classs目錄(模塊)褥紫,如圖所示:
前端布局的classs模塊
①在classs目錄下添加editor.vue:
vue-admin-template/src/views/classs/editor.vue:
<template>
  <div class="dashboard-container">
    <el-form ref="form" :model="form" label-width="80px">
      <el-form-item label="所屬學(xué)校">
        <el-select v-model="form.school" placeholder="請選擇" @change="schoolChange">
          <el-option
            v-for="item in schools"
            :key="item._id"
            :label="item.name"
            :value="item._id">
          </el-option>
        </el-select>
      </el-form-item>
      <!--      編輯框:學(xué)院選擇列表-->
      <el-form-item label="所屬學(xué)院">
        <el-select v-model="form.academy" placeholder="請選擇">
          <el-option
            v-for="item in academys"
            :key="item._id"
            :label="item.name"
            :value="item._id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="班級名稱">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="專業(yè)">
        <el-input v-model="form.level"></el-input>
      </el-form-item>
      <el-form-item label="人數(shù)">
        <el-input v-model="form.renshu"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSubmit">立即創(chuàng)建</el-button>
        <el-button>取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
  import { mapGetters } from 'vuex'

  export default {
    name: 'classs',
    computed: {
      ...mapGetters([
        'name'
      ])
    },
    data(){
      return{
        schools:[],
        academys:[],
        //列表內(nèi)容
        options: [
        ],
        apiModel:'classs',
        form:{}
      }
    },
    methods:{
      onSubmit(){
        if(this.form._id){
          this.$http.post(`/api/${this.apiModel}/update`,this.form).then(res => {
            console.log('bar:', res)
            this.$router.push({path:this.apiModel})
            this.form={}
          })
        }else
        {
          this.$http.post('/api/'+this.apiModel+'/add',this.form).then(res => {
            console.log('bar:', res)
            this.$router.push({path:this.apiModel})
            this.form={}
          })
        }
      },
      schoolChange(val1){
        //顯示學(xué)院選擇欄目
        this.$http.post('/api/academy/get',{school:val1}).then(res => {
          if(res&&res.length>0){
            this.academys = res
            console.log('res:', res)
          }
        })
      }
    },
    mounted() {
      if(this.$route.query._id){
        this.$http.post('/api/'+this.apiModel+'/get',{_id:this.$route.query._id}).then(res => {
          if(res&&res.length>0){
            this.form = res[0]
            this.schoolChange(this.form.school)
          }
        })
      }

      //顯示學(xué)校選擇欄目
      this.$http.post('/api/school/find').then(res => {
        if(res&&res.length>0){
          this.schools = res
          console.log('res:', res)
        }
      })
    }
  }
</script>

<style lang="scss" scoped>
  .dashboard {
    &-container {
      margin: 30px;
    }
    &-text {
      font-size: 30px;
      line-height: 46px;
    }
  }
</style>

效果圖:


editor.vue的效果圖
②在classs目錄下添加index.vue:
vue-admin-template/src/views/classs/index.vue
<template>
  <div class="dashboard-container">
    <el-table
      :data="users"
      style="width: 100%"
      :row-class-name="tableRowClassName">
      <el-table-column
        prop="name"
        label="班級名稱"
        width="180">
      </el-table-column>
      <el-table-column
        prop="level"
        label="專業(yè)"
        width="180">
      </el-table-column>
      <el-table-column
        prop="renshu"
        label="人數(shù)">
      </el-table-column>
      <!--      列表添加項目
      -->
      <el-table-column
        prop="school"
        label="學(xué)校名稱"
        width="180">
        <template slot-scope="scope" >
          <span class="" v-if="scope.row.school">
            <el-tag
              :type="scope.row.school.name === '深圳信息職業(yè)技術(shù)學(xué)院' ? 'primary' : 'success'"
              disable-transitions>{{scope.row.school.name}}</el-tag>
          </span>
        </template>
      </el-table-column>
      <el-table-column
        prop="academy"
        label="學(xué)院名稱"
        width="180">
        <template slot-scope="scope" >
          <span class="" v-if="scope.row.academy">
            <el-tag
              :type="scope.row.academy.name === '軟件學(xué)院' ? 'primary' : 'success'"
              disable-transitions>{{scope.row.academy.name}}</el-tag>
          </span>

        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button
            size="mini"
            @click="handleEdit(scope.$index, scope.row)">編輯
          </el-button>
          <el-button
            size="mini"
            type="danger"
            @click="handleDelete(scope.$index, scope.row)">刪除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
  import { mapGetters } from 'vuex'

  export default {
    name: 'classs',
    computed: {
      ...mapGetters([
        'name'
      ])
    },
    data() {
      return {
        apiModel:'classs',
        users: {}
      }
    },
    methods: {
      onSubmit() {
        console.log(123434)
      },
      handleEdit(index, item) {
        this.$router.push({ path: '/'+this.apiModel+'/editor', query: {_id:item._id} })
      },
      handleDelete(index, item) {
        this.$http.post('/api/'+this.apiModel+'/delete', item).then(res => {
          console.log('res:', res)
          this.findUser()
        })

      },
      findUser(){
        this.$http.post('/api/'+this.apiModel+'/find', this.user).then(res => {
          console.log('res:', res)
          this.users = res
        })
      }
    },
    mounted() {
      this.findUser()
    }
  }
</script>

<style lang="scss" scoped>
  .dashboard {
    &-container {
      margin: 30px;
    }

    &-text {
      font-size: 30px;
      line-height: 46px;
    }
  }
</style>
效果圖:
index.vue的效果圖

2姜性、在router下的index.js中添加classs模塊的路由:

添加部分

classs模塊的路由

vue-admin-template/src/router/index.js:

  {
    path: '/classs',
    component: Layout,
    meta: { title: '班級管理', icon: 'example' },
    redirect: '/classs',
    children: [{
      path: 'classs',
      name: 'classs',
      component: () => import('@/views/classs'),
      meta: { title: '班級管理', icon: 'classs' }
    },
      {
        path: 'editor',
        name: 'editor',
        component: () => import('@/views/classs/editor'),
        meta: { title: '添加班級', icon: 'classs' }
      }]
  },

總體代碼如下:

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: '/school',
    component: Layout,
    meta: { title: '學(xué)校管理', icon: 'example' },
    redirect: 'school',
    children: [{
      path: 'school',
      name: 'school',
      component: () => import('@/views/school'),
      meta: { title: '學(xué)校管理', icon: 'school' }
    },
      {
        path: 'editor',
        name: 'editor',
        component: () => import('@/views/school/editor'),
        meta: { title: '添加學(xué)校', icon: 'school' }
      }]
  },

  {
    path: '/academy',
    component: Layout,
    meta: { title: '學(xué)院管理', icon: 'example' },
    redirect: 'academy',
    children: [{
      path: 'academy',
      name: 'academy',
      component: () => import('@/views/academy'),
      meta: { title: '學(xué)院管理', icon: 'academy' }
    },
      {
        path: 'editor',
        name: 'editor',
        component: () => import('@/views/academy/editor'),
        meta: { title: '添加學(xué)院', icon: 'academy' }
      }]
  },

  {
    path: '/classs',
    component: Layout,
    meta: { title: '班級管理', icon: 'example' },
    redirect: 'classs',
    children: [{
      path: 'classs',
      name: 'classs',
      component: () => import('@/views/classs'),
      meta: { title: '班級管理', icon: 'classs' }
    },
      {
        path: 'editor',
        name: 'editor',
        component: () => import('@/views/classs/editor'),
        meta: { title: '添加班級', icon: 'classs' }
      }]
  },

  {
    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

這樣班級管理模塊就構(gòu)建好了,最終的效果圖:

班級管理模塊
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末髓考,一起剝皮案震驚了整個濱河市部念,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌氨菇,老刑警劉巖儡炼,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異查蓉,居然都是意外死亡乌询,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門豌研,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妹田,“玉大人竣灌,你說我怎么就攤上這事「阳铮” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵及汉,是天一觀的道長沮趣。 經(jīng)常有香客問我,道長坷随,這世上最難降的妖魔是什么房铭? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮温眉,結(jié)果婚禮上缸匪,老公的妹妹穿的比我還像新娘。我一直安慰自己类溢,他們只是感情好凌蔬,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著闯冷,像睡著了一般砂心。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蛇耀,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天辩诞,我揣著相機與錄音,去河邊找鬼纺涤。 笑死译暂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撩炊。 我是一名探鬼主播外永,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼衰抑!你這毒婦竟也來了象迎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤呛踊,失蹤者是張志新(化名)和其女友劉穎砾淌,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谭网,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡汪厨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了愉择。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劫乱。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡织中,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衷戈,到底是詐尸還是另有隱情狭吼,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布殖妇,位于F島的核電站刁笙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏谦趣。R本人自食惡果不足惜疲吸,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望前鹅。 院中可真熱鬧摘悴,春花似錦、人聲如沸舰绘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捂寿。三九已至叉橱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間者蠕,已是汗流浹背窃祝。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留踱侣,地道東北人粪小。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像抡句,于是被迫代替她去往敵國和親探膊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

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