zoukankan      html  css  js  c++  java
  • vue开发小结(上)

    前言:

      18年年底,就一个字,忙,貌似一到年底哪个公司都在冲业绩,包括我们自己开发自己公司的项目也一样得加把劲。自从18年年初立了个flag17年年终总结——走过2017,迎来2018Flag到现在又一年了。想想当时立的flag还是很多没有完成到,说的第一点就没有完成了(ps:这确实不能怪我,真的忙),健身也是落下了,而node.js的呢还在进程中,说不定稍后会出了系列的文章(ps:当然不会像之前那几篇那样,感觉写得有点云里雾里的)。当然,今天的重点不是说这些,而是我在vue项目上实践的一些小汇总和踩坑指南。另,结尾有福利喔~~~

    正文:

      这一年前前后后大概做了有四个vue相关的项目(ps:vue-cli脚手架搭建),其中包括两个移动端和两个管理后台的(ps:有一个管理端还在进行中),其中不免遇到了不少坑,还有不少的总结。

      vue-cli开发相关

      一、一般的vue-cli src的项目骨架:

    ├── App.vue
    ├── main.js
    ├── permission.js
    ├── router
    │   └── index.js
    ├── api
    │   └── index.js
    │   └── xx.js
    ├── assets
    │   ├── images
    │   ├── flexible.js
    │   └── common
    │       └── common.less
    │       └── mixin.less
    ├── components
    ├── utils
    ├── store
    │   ├── index.js
    │   └── xxStore.js
    └── views
        ├── index.vue
        └── xx.vue

      对vue-cli有了解的应该知道一般我们的源码就写在src文件夹下面。其中App.vue就是根组件,其他的组件我们就可以通过App.vue的

    <router-view/>渲染;main.js就是入口文件,一般用于引入通用组件,UI框架,router,axios,store挂载等;permission.js则用于在路由渲染先后需要设置的权限之类的;components则为通用组件的封装;utils则为通用的方法的封装;api则为通用api的封装调用等。

      例如:main.js

    import 'babel-polyfill'
    import Vue from 'vue'
    import Es6Promise from 'es6-promise'
    require('es6-promise').polyfill()
    Es6Promise.polyfill()
    import App from './App'
    import './assets/flexible'
    import axios from 'axios'
    import router from './router'
    import store from './store'
    import './permission'
    import {WechatPlugin,LoadingPlugin,ToastPlugin,AlertPlugin,ConfirmPlugin } from 'vux'
    import VueLazyload from 'vue-lazyload'
    
    //挂载axios
    Vue.prototype.axios=axios
    
    //配置微信jssdk,通过Vue.wechat直接访问wx
    Vue.config.productionTip = false
    Vue.use(WechatPlugin)
    Vue.use(LoadingPlugin)
    Vue.use(ToastPlugin)
    Vue.use(AlertPlugin)
    Vue.use(ConfirmPlugin)
    Vue.use(VueLazyload,{
      error:require('./assets/images/activity_default_loading.png'),
      loading:require('./assets/images/activity_default_loading.png')
    })
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store,
      components: { App },
      template: '<App/>'
    })

      二、axios api接口的统一封装

      现在的vue-cli开发,一般都是使用axios进行接口请求,其中一大好处就是可以进行请求和响应的拦截,进而进行一些通用的配置,所以能很好的做到了接口的封装。

      例如:request.js

    import axios from 'axios'
    import { AlertModule } from 'vux'
    
    // 创建axios实例
    const service = axios.create({
      //baseURL: process.env.ENV_CONFIG=='dev'?'/api':'', // api的base_url
      baseURL: process.env.ENV_CONFIG=='dev'?'/api':process.env.BASE_API,
      //timeout: 10000, // 请求超时时间
      headers:{
       
      }
    })
    
    // request拦截器
    service.interceptors.request.use(
      config => {
        if( config.method === 'post' ){
          config.data.http_headers={
         
          }
        }
        return config
      },
      error => {
        // Do something with request error
        // for debug
        console.log(error)
        Promise.reject(error)
      }
    )
    
    // respone拦截器
    service.interceptors.response.use(
      response => {
        if (response.data.result && response.data.result==='failed') {
          AlertModule.show({
            title:'提示',
            content:response.data.text,
            /*onHide () {
              router.push({
                name:'index'
              })
            }*/
          })
          return
        }
        else{
          return response.data
        }
      },
      error => {
        console.log('err' + error) // for debug
        /*AlertModule.show({
          title:'斑马提示',
          content:'链接超时,请重新尝试',
        })*/
        return Promise.reject(error)
      }
    )
    
    export default service

      之后,我们就可以通过api目录暴露封装的接口调用

    import request from '@/utils/request'
    
    export function doXx(data) {
      return request({
        url:'/xx',
        method:'post',
        data
      })
    }

      三、axios 请求不同数据格式的处理及表单提交处理

      看axios文档我们可以了解到,axios的其中一个特点就是将数据转换成json格式,但是有些接口由于历史等原因后台不方便调整的话,就需要前端做些处理了。

      例如,以formdata格式提交参数则可以通过axios内置的qs模块进行data的格式转换,然后设置请求头即可

    export function XXRequest(data) {
      return request({
        transformRequest: [function(data) {      //在请求之前对data传参进行格式转换
          data = qs.stringify(data)
          return data
        }],
        url:'/xx.do',
        method:'post',
        data,
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        }
      })
    }

      又例如,后台返回一个form表单,需要前端提交form表单,则需要,通过路由的resolve对象,this.$router.resolve解析接口回调参数并且打开空白页面并提交form表单

    // res为回调参数
    let routerData = this.$router.resolve({name:'apply',query:{htmls:res}})
    window.open(routerData.href,'_ blank')
    const div = document.createElement('div')
    div.innerHTML = res
     document.body.appendChild(div)
    document.forms [0] .submit()
    
    apply.vue做法
    <template>
       <div v-html ="apply">
         {{apply}}
       </div>
    </template>
    
    <script>
      export default {
        name:'apply',
        data(){
          return {
            apply:''
          }
        },
        mounted(){
          let form = this.$route.query.htmls
          this.apply = form
          this.$nextTick(()=> {
            document.forms [0].submit()
          })
        }
      }
      </script>

      四、引入css预处理器less

    npm install less less-loader --save
    
    修改webpack.base.conf.js rules
    {
            test: /.less$/,
            loader: "style-loader!css-loader!less-loader",
          }

      五、es6在低版本及IE下的不兼容

      部分低版本的手机或者IE下是不兼容es6中的promise的,如果用到了promise语法的话,就需要进行es6编译es5,所以做法需要引入

    es6-promise并且在main.js中引入

    npm install es6-promise --save
    
    main.js中引入
    import Es6Promise from 'es6-promise'
    require('es6-promise').polyfill()
    Es6Promise.polyfill()

      六、ico调整

      一般的ico都是设置在项目根目录下,然后调整build webpack.dev.conf.js和webpack.prod.conf.js中的new HtmlWebpackPlugin设置参数

    favicon:path.resolve(__dirname,'xx.ico')即可。

      七、常用组件的引入

      一般常用的vue组件的引入,例如vue-lazyload、vue-scroller等一般可以上npm查看相关是使用方法即可。

      vue-cli单页面部署相关

      一、build路径问题

      一般项目都会部署到端口的某个文件夹下面,所以需要修改config index.js的assetsPublicPath路径

     index: path.resolve(__dirname, '../文件夹名/index.html'),
    
    assetsRoot: path.resolve(__dirname, '../文件夹名'),
    assetsSubDirectory: 'static',
    assetsPublicPath: './',  // ./为相对文件夹路径,否则/为根目录

      二、部署到Nginx上

      由于打包完后的是静态文件,所以我们可以直接部署到Nginx上面,接口通过Nginx代理即可。但是刷新会丢失404,所以需要做个重定向即可。

    location /{
                root   dist;
                index  index.html;
            try_files $uri $uri/ /dist/index.html;
    }

      三、部署到Tomcat上

      部署到Tomcat上的话,一样存在刷新丢失的情况,我看有人提出配置web.xml进行404重定向,这个我司也是有实践了下

    <!DOCTYPE web-app PUBLIC
     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     "http://java.sun.com/dtd/web-app_2_3.dtd" >
    
    <web-app>
      <display-name>xxx</display-name>
    
      <error-page>
        <error-code>404</error-code>
        <location>/index.html</location>
      </error-page>
    </web-app>

      但是,这样部署的话其实是第一次刷新ok的,但是再次刷新则还是404丢失。(ps:在移动设备上会,有知道的大佬可以留言喔~)

    总结:

      其中,有了解过vue-cli开发的话,其实用vue开发在业务逻辑上是没有太大的问题的,因为很多大佬已经开发出各种组件供我们调用了,我呢,就在部署上面卡了很久,因为最初的想法是部署到Tomcat上的,所以一直尝试都没有成功,最初的原因的就是使用了es6的promise,然后呢又了解到了需要配置重定向xml。最后以为大功告成,还是存在二次刷新丢失的问题。所以部署到了Nginx上,然后设置重新定这样子解决。

      另,其中还有很多可能没有总结到位,到时有补充的会补充在这里~

      再另,附福利

      winter大大,前手机淘宝前端负责人在极客时间上发了《重学前端》的课程,扫我的二维码报名的话可以找我分奖励喔,另外通过我二维码报名的加我wx:UEMtQWFyb24= (ps:base64转码)可得vue教程一套。嘻嘻

  • 相关阅读:
    ios10 获取idfa的坑
    iOS 获取手机sim卡的运营商(移动,电信,联通) 相关信息
    iOS获取手机IP地址
    UIScrollView 与 touchesBegan 冲突解决方法
    32位与64位基础
    MySQL数据库基础_表&简单查询
    MySQL数据库基础
    Java_File、递归
    Java_lambda表达式
    Java线程锁,等待唤醒和线程池
  • 原文地址:https://www.cnblogs.com/aaron-pan/p/10272907.html
Copyright © 2011-2022 走看看