关于前后端分离,前端日常开发模式
作用
- 后端提供restful api接口
- 前端提供页面展示
而前端日常开发时,大致有以下几种开发模式(vue2.0版本)
使用npm run dev模式,且通过配置proxyTable,将axios的前端请求转发给实际的后端地址(常用)
项目根下的config目录
- index.js
'use strict' // Template version: 1.3.1 // see http://vuejs-templates.github.io/webpack for documentation. const path = require('path') module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: { '/api': { target: 'http://127.0.0.1:8080', // 后端接口地址 changeOrigin: true, // 是否允许跨域 pathRewrite: { '^/api': '' // 重写 } } }, // Various Dev Server settings host: 'localhost', // can be overwritten by process.env.HOST port: 80, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined autoOpenBrowser: true, errorOverlay: true, notifyOnErrors: true, poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- // Use Eslint Loader? // If true, your code will be linted during bundling and // linting errors and warnings will be shown in the console. useEslint: true, // If true, eslint errors and warnings will also be shown in the error overlay // in the browser. showEslintErrorsInOverlay: false, /** * Source Maps */ // https://webpack.js.org/configuration/devtool/#development devtool: 'cheap-module-eval-source-map', // If you have problems debugging vue-files in devtools, // set this to false - it *may* help // https://vue-loader.vuejs.org/en/options.html#cachebusting cacheBusting: true, cssSourceMap: true }, build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: '/', /** * Source Maps */ productionSourceMap: false, // https://webpack.js.org/configuration/devtool/#production devtool: '#source-map', // Gzip off by default as many popular static hosts such as // Surge or Netlify already gzip all static assets for you. // Before setting to
true
, make sure to: // npm install --save-dev compression-webpack-plugin productionGzip: true, productionGzipExtensions: ['js', 'css'], // Run the build command with an extra argument to // View the bundle analyzer report after build finishes: //npm run build --report
// Set totrue
orfalse
to always turn it on or off bundleAnalyzerReport: process.env.npm_config_report } }
- dev.env.js
'use strict' const merge = require('webpack-merge') const prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"', BASE_API: '"/api"' })
- prod.env.js
'use strict' module.exports = { NODE_ENV: '"production"', // BASE_API: '"http://georege.slhk.com/"' }
项目根下的src目录下自己封装api目录
- axios-filter.js
import axios from 'axios' import { Message } from 'element-ui' import router from '@/router' // 根据不同环境自动读取不同的baseurl if (process.env.NODE_ENV === 'development') { axios.defaults.baseURL = process.env.BASE_API } // 读取cookie中的csrftoken axios.defaults.xsrfCookieName = 'csrftoken' // axios header设置X-CSRFTOKEN axios.defaults.xsrfHeaderName = 'X-CSRFTOKEN' // 设置Content-Type axios.defaults.headers = { 'Content-Type': 'application/json;charset=UTF-8' } // 设置超时时间 axios.defaults.timeout = 50000 // request拦截器 axios.interceptors.request.use( config => { // sessionStorage 如果存在jwt token if (sessionStorage.token) { // 则JWT token认证格式,写入header config.headers.Authorization = 'JWt ' + sessionStorage.token // console.log(sessionStorage.token) } return config }, error => { // console.log(error) return Promise.reject(error) } ) // reponse自定义拦截器 start function customAxiosResponseInterceptor () { const interceptor = axios.interceptors.response.use( response => response, error => { // console.log(error) var config = error.config if (error.response.status === 401) { axios.interceptors.response.eject(interceptor) const v = sessionStorage.getItem('refresh') if (typeof v === 'undefined' || v === null || v === '') { Message({ showClose: true, message: error.response.data.msg, type: 'error' }) } else { let data = { 'refresh': v } return axios.post('/api-token-refresh/', data).then(response => { sessionStorage.setItem('token', response.data.access) console.log('刷新 access token 成功') // 重新发送请求 return axios(config) }).catch(error => { Message({ showClose: true, message: '登录超时,请重新登录!!!', type: 'error' }) redirectLoginWithQuery() console.log(error) return Promise.reject(error) }).finally(customAxiosResponseInterceptor) } } else { console.log(error.response) // Message({ // showClose: true, // message: error.response.data.msg, // type: 'error' // }) return Promise.reject(error) } } ) } customAxiosResponseInterceptor() // reponse自定义拦截器 end // login with redirect function redirectLoginWithQuery () { router.push({ path: '/login', query: { redirect: router.currentRoute.fullPath } }) } export default axios
项目目录结构
使用npm run build模式,直接dist下打包编译出生产所需静态文件
使用npm run watch模式(需要安装watch组件,且需要配置package.json文件中的scripts的内容)
package.json
"scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "lint": "eslint --ext .js,.vue src", "build": "node build/build.js", "watch": "nodemon --watch src -e html,vue,js,less build/build.js" },