axios
請求接口├── @vue/cli@4.1.2css
├── @vue/cli-init@4.1.2前端
vue init webpack ./
// 先切換到/client
目錄下npm i -S axios
// 先切換到/client
目錄下npm run start
查看頁面是否能正常訪問localhost:8080
本身的項目,沒特殊要求,選擇本身熟悉的element-ui
UI庫、scss
預編譯語言快速搭建頁面。vue
// 更新文件:/client/src/App.vue <template> <div id="app"> <router-view/> </div> </template> <script> export default { name: 'App' } </script>
// 更新文件:/client/src/router/index.js // 順便刪除文件:/client/src/components/Helloworld.vue import Vue from 'vue' import Router from 'vue-router' import Login from '@/views/login' Vue.use(Router) export default new Router({ routes: [ { path: '/', redirect: '/login' }, { path: '/login', name: 'login', component: Login } ] })
// 新建文件: /client/src/views/login/index.vue <template> <div> Login </div> </template>
展現效果 //更新不及時,能夠重啓前端服務node
element-ui
和scss
npm i -S element-ui node-scss sass-loader@7
// sass-loader安裝7.版本,目前最新版8.編譯失敗// 更新文件:/client/src/main.js // The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import App from './App' import router from './router' Vue.config.productionTip = false Vue.use(ElementUI) /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
// 更新文件:/client/src/views/login/index.vue <template> <div> <el-button type="primary">Login</el-button> <p class="red">這是scss</p> </div> </template> <style lang="scss" scoped> $color: red; .red { color: $color; } </style>
爲了省事,直接從Element
官網 > 組件 > Form表單,拷貝一份帶校驗的示例改改webpack
// 更新文件:/client/src/views/login/index.vue <template> <div class="page-login"> <el-form :ref="formName" class="form-login" :model="form" :rules="rules"> <el-form-item label="賬號" prop="account"> <el-input v-model="form.account" placeholder="請輸出賬號"></el-input> </el-form-item> <el-form-item label="密碼" prop="password"> <el-input type="password" v-model="form.password" placeholder="請輸出密碼"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onLogin">登錄</el-button> <el-button type="primary" @click="onRegister">註冊</el-button> </el-form-item> </el-form> </div> </template> <script> export default { name: 'Login', data () { return { formName: 'LoginForm', form: { account: '', password: '' }, rules: { account: [ { required: true, message: '請輸入賬號', trigger: 'blur' }, { min: 5, message: '長度至少5個字符', trigger: 'blur' } ], password: [ { required: true, message: '請輸入密碼', trigger: 'blur' }, { min: 3, message: '長度至少3個字符', trigger: 'blur' } ] } } }, methods: { async onLogin () { console.log('login') }, async onRegister () { console.log('register') } } } </script> <style lang="scss" scoped> @import './index.scss'; </style>
// 新建文件:client/src/views/login/index.scss .form-login { width: 600px; margin: 0 auto; }
在準備工做時,已經npm i -S axios
安裝axios
。ios
// 新建配置文件:client/src/config/http.js export const BASE_URL = 'http://localhost:3000/' export const TIMEOUT = 15000
// 新建axios實例文件:client/src/utils/http.js import axios from 'axios' import { BASE_URL, TIMEOUT } from '@/config/http' const instance = axios.create({ baseURL: BASE_URL, timeout: TIMEOUT, validateStatus: function (status) { // return status >= 200 && status < 300; // default return status >= 200 // 可攔截狀態碼>=200的請求響應 } }) export default instance
注意:axios默認只返回Http Code爲2**
請求的響應nginx
//更新文件:server/control/users.js async function list (ctx) { try { const users = await userModel.find(); //查出所有用戶 ctx.body = { code: '200', data: users, msg: '查詢成功' } } catch (err) { ctx.body = { code: '403', data: null, msg: err.message } } }
//更新文件:client/src/views/login/index.vue ... <script> import http from '@/utils/http' ... methods: { async onLogin () { console.log('register') }, async onRegister () { console.log('register') } }, async created () { const res = await http.get('/users') console.log(res) } ... </script> ...
發生跨域請求,這裏咱們切換到/server/
目錄下,安裝依賴npm i -S koa2-cors
(線上的話,可使用nginx
作代理)git
// 更新文件:server/app.js const koa = require('koa'); const bodyParser = require('koa-body'); const cors = require('koa2-cors'); const routes = require('./router'); const app = new koa(); app.use(cors()); ...
重啓後端服務,便可在頁面http://localhost:8080/#/login
看到請求結果github
從返回接口能夠看出,請求服務端成功時,只須要res.data
便可,使用instance.interceptors
對返回數據進行過濾。web
// 更新文件:client/src/utils/http.js ... // Add a response interceptor instance.interceptors.response.use( async res => { if (/^20./.test(res.status)) { return res.data } console.log('------response=======', res) return res }, error => { return Promise.reject(error) } ) export default instance
請求結果
//更新文件:client/src/views/login/index.vue ... async onLogin () { try { const valid = await this.$refs[this.formName].validate() if (valid) { const { account, password } = this.form const res = await http.post( '/users?action=login', { account, password, } ) console.log(res) if (res && res.code === '200') { this.$router.replace('/home') } else { this.$message({ // 沒有使用this.$message.error('') type: 'error', message: res.msg }) } } } catch (err) { console.error(err) } }, ...
this.$message({})
,而沒有使用this.$message.error()
,由於發現若是res沒有返回的話,會報Element
的錯誤,形成信息誤導。更新路由文件,使登陸成功跳轉到Home
組件
// 更新路由文件: import Vue from 'vue' import Router from 'vue-router' import Login from '@/views/login' import Home from '@/views/home' Vue.use(Router) export default new Router({ routes: [ { path: '/', redirect: '/login' }, { path: '/login', name: 'login', component: Login }, { path: '/home', name: 'home', component: Home } ] })
// 新建文件:client/src/views/home/index.vue <template> <div>Home</div> </template>
使用上節經過Postman
建立的admin
帳戶登陸,結果展現
緩慢的動圖以下:
//更新文件:client/src/views/login/index.vue ... async onRegister () { try { const valid = await this.$refs[this.formName].validate() if (valid) { const { account, password } = this.form const res = await http.post( '/users?action=register', { account, password } ) if (res.code === '200') { this.$refs[this.formName].resetFields() this.$message({ type: 'success', message: '註冊成功' }) } else { this.$message({ type: 'error', message: res.msg }) } } } catch (err) { console.error(err) } } ...
測試失敗結果
測試成功結果
可使用新建立的賬號登陸,發現能夠成功/查看數據庫,是否成功新增用戶