實(shí)訓(xùn)(一)
1.安裝 nodejs
2.安裝 git
3.下載?vue-element-admin
git clone https://github.com/PanJiaChen/vue-admin-template.git
cd vue-admin-template
npm install
npm run dev
進(jìn)入router/index.js横蜒,刪除多余界面爱谁,刪除后結(jié)果如下:
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'/'el-icon-x'?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:?'首頁(yè)',?icon:?'dashboard'?}
????}]
??},
????{
??????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:?'班級(jí)管理',?icon:?'example'?},
??????redirect:?'/classs',
??????children:?[{
????????path:?'classs',
????????name:?'classs',
????????component:?()?=>?import('@/views/classs'),
????????meta:?{?title:?'班級(jí)管理',?icon:?'classs'?}
??????},
????????{
??????????path:?'editor',
??????????name:?'editor',
??????????component:?()?=>?import('@/views/classs/editor'),
??????????meta:?{?title:?'添加班級(jí)',?icon:?'classs'?}
????????}]
????},
????{
??????path:?'/student',
??????component:?Layout,
??????meta:?{?title:?'學(xué)生管理',?icon:?'example'?},
??????redirect:?'/student',
??????children:?[{
????????path:?'student',
????????name:?'student',
????????component:?()?=>?import('@/views/student/index'),
????????meta:?{?title:?'學(xué)生管理',?icon:?'user'?}
??????},
????????{
??????????path:?'editor',
??????????name:?'editor',
??????????component:?()?=>?import('@/views/student/editor'),
??????????meta:?{?title:?'添加學(xué)生',?icon:?'user'?}
????????}]
????},
????{
????????path:?'/teacher',
????????component:?Layout,
????????meta:?{?title:?'老師管理',?icon:?'example'?},
????????redirect:?'/teacher',
????????children:?[{
??????????path:?'teacher',
??????????name:?'teacher',
??????????component:?()?=>?import('@/views/teacher'),
??????????meta:?{?title:?'老師管理',?icon:?'user'?}
????????},
??????????{
????????????path:?'editor',
????????????name:?'editor',
????????????component:?()?=>?import('@/views/teacher/editor'),
????????????meta:?{?title:?'添加老師',?icon:?'user'?}
??????????}]
??????},
??????//?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
打開utils/http.js,編寫代碼调煎,結(jié)果如下:
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文件蘑斧,結(jié)果如下:
'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')
????????}
??????)
??}
}
在src/main.js 最后插入http,結(jié)果如下:
import?http?from?'./utils/http'
Vue.use(http)
打開views/dashboard/index.vue文件边翼,結(jié)果如下:
<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,執(zhí)行下面命令
npm install -g koa-generator
構(gòu)建koa2項(xiàng)目代碼如下
koa2 projectName
初始化后臺(tái)項(xiàng)目插件鱼响,命令屬下:
cd projectName
npm install
項(xiàng)目試運(yùn)行
npm run dev
在瀏覽器打開地址:
出現(xiàn)koa2的歡迎界面則代表成功
安裝mongoose
npm install mongoose --save
打開projectName項(xiàng)目,創(chuàng)建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'}
打開db/models/user.js组底,編寫以下內(nèi)容:
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
constKoa=require('koa')constapp=newKoa()constviews=require('koa-views')constjson=require('koa-json')constonerror=require('koa-onerror')constbodyparser=require('koa-bodyparser')constlogger=require('koa-logger')constindex=require('./routes/index')constusers=require('./routes/users')constmongoose=require('mongoose')constdbconfig=require('./db/config')mongoose.connect(dbconfig.dbs,{useNewUrlParser:true,useUnifiedTopology:true})constdb=mongoose.connectiondb.on('error',console.error.bind(console,'connection error:'));db.once('open',function(){console.log('mongoose 連接成功')});// error handleronerror(app)// middlewaresapp.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'}))// loggerapp.use(async(ctx,next)=>{conststart=newDate()awaitnext()constms=newDate()-startconsole.log(`${ctx.method} ${ctx.url} - ${ms}ms`)})// routesapp.use(index.routes(),index.allowedMethods())app.use(users.routes(),users.allowedMethods())// error-handlingapp.on('error',(err,ctx)=>{console.error('server error',err,ctx)});module.exports=app// error handleronerror(app)// middlewaresapp.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'}))// loggerapp.use(async(ctx,next)=>{conststart=newDate()awaitnext()constms=newDate()-startconsole.log(`${ctx.method} ${ctx.url} - ${ms}ms`)})// routesapp.use(index.routes(),index.allowedMethods())app.use(users.routes(),users.allowedMethods())// error-handlingapp.on('error',(err,ctx)=>{console.error('server error',err,ctx)});module.exports=app
打開routes/users.js丈积,結(jié)果如下:
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?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
啟動(dòng)的服務(wù)在運(yùn)行
npm run dev