关于前后端分离,前端日常开发模式

作用

  1. 后端提供restful api接口
  2. 前端提供页面展示

而前端日常开发时,大致有以下几种开发模式(vue2.0版本)

  1. 使用npm run dev模式,且通过配置proxyTable,将axios的前端请求转发给实际的后端地址(常用

    1. 项目根下的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 to true or false 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/"'
      }
      
    2. 项目根下的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
      
    3. 项目目录结构

  2. 使用npm run build模式,直接dist下打包编译出生产所需静态文件

  3. 使用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"
        },

您可能还喜欢...