vue.js项目实践总结-2

最近做了一个知识竞赛类的web app,使用了vue全家桶 + axios + vant + animate.css,在此记录下项目中遇到的一些问题和一些笔记:

 

1. 前端发送数据的格式设置

由于后端接受的数据格式为字符串形式,不能直接向后端发送一个带json对象的post请求,这里用到了npm库中的“querystring”,其作用是对http请求所带的数据进行解析

import querystring from 'querystring'

export const getMessageCode = (person_phone) => {
  let data = {
    person_phone
  }
  // 通过querystring的stringify方法对数据进行解析处理
  return axios.post('/test', querystring.stringify(data))
}

这样后端就能收到数据了,如果不这样处理(直接发送data),前端请求会报400错误

 

2. axios全局捕获异常

项目中ajax库使用的是axios,全局对它进行了一些配置

// ajax接口调用
import { baseUrl } from '@/config/env'
import axios from 'axios'
// axios.defaults.headers.post['content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'
axios.defaults.withCredentials = true
axios.defaults.baseURL = baseUrl

// 拦截器(响应)
axios.interceptors.response.use((response) => {
  return response
}, (err) => {
  // 全局捕获异常
  alert('服务器错误, 请联系管理员')
  // throw new Error('请求服务器失败!')
  return Promise.reject(err)
})

通过axios的拦截器全局去捕获错误

 

3.  async await 处理异步请求

项目中全部使用了async + await的方式来处理异步请求,类似于

async mounted () {
    // 获取排行榜信息
    let res = await getLeaderboard()
    res = res.data
    console.log(res)
    this.boardList = res.data
  }

注意上面await关键字右边的getLeaderboard()这个方法必须返回一个promise对象时才能正确地拿到返回值

export const getLeaderboard = () => {
  let data = {
    pageNum: 1,
    pageSize: 500
  }
  // 必须返回一个promise对象
  return axios.post('/test', querystring.stringify(data))
}

 

4. 在vue组件内添加路由导航守卫

beforeRouterLeave: 这个离开守卫通常用来禁止用户在还未保存修改前突然离开

项目中使用这个守卫是为了防止用户误操作在答题未完成时点击了返回,或用户想中途离开给予用户一个提示。提示框dialog使用了vant提供的组件。

  mounted () {
    // 获取url参数
    ...
  },
  // 用户在答题过程中点击返回 提示用户答题未完成
  beforeRouteLeave (to, from, next) {
    if (to.name == 'ItemHome') {
      this.$dialog.confirm({
        title: '提醒',
        message: '答题未完成,若返回后会自动交卷,你确定还要返回吗?'
      }).then(async () => {
        // 用户确定要返回---则默认交卷
        let res = await endKnowAnswer(this.person_id)
        res = res.data
        if (res.state != 1) {
          this.$toast(res.message)
          next(false)
          return
        }
        // 交卷成功后返回到上一页
        next()
      }).catch(() => {
        // 取消 则答题继续
        next(false)
      })
    } else {
      next()
    }
  },
  destroyed () {
    // 离开页面时关闭定时器
    clearInterval(this.timer)
  }

 

5. 引入animate.css 实现css3动画效果

// 引入animate.css
import animated from 'animate.css'
Vue.use(animated)

然后就可以在vue组件的html中直接使用了

<h3 class="animated bounceInDown"><img src="../img/home_title.png" alt=""></h3>

 

6. 项目打包时的一些细节处理

在项目通过npm run build打包前,可能需要对一些配置进行修改才能保证项目在线上服务器上运行时不会报错

vue-cli脚手架用的是2.0+的版本,在根目录下的config文件夹下的index.js:

build: {
    ...

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: './',    // 把'/'改为'./'

    /**
     * Source Maps
     */

    productionSourceMap: true,    // 改为false可以不生成map文件
    ...
}

把打包后的html文件内的img,css和js等引用路径--从绝对路径改为相对路径。


 

线上运行项目还有可能出现css中使用背景图的引用地址出错的问题,需要在根目录build文件下的utils.js中找到以下代码:

    // Extract CSS when that option is specified
    // (which is the case during production build)
    if (options.extract) {
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader',
        // 添加下方代码!
        publicPath: '../../'
      })
    } else {
      return ['vue-style-loader'].concat(loaders)
    }

设置publicPath为'../../'

 

总结: 项目是接入到微信公众号当中,用苹果手机打开会在手机下方出现返回和前进的按钮,可能会影响部分页面的样式,需要做一些处理,同时处理页面的跳转限制也是必要的

posted @ 2018-12-05 10:47  allen2001  阅读(1465)  评论(0编辑  收藏  举报