zoukankan      html  css  js  c++  java
  • 一次与客户端合作的走坑之旅!

        项目经理给客户端提出了个需求,加急做用户反馈界面,很急,安卓客户端项目开发就一个人,表示干不了,短时间内完成不了,于是商量了一番,把前端的我搅和进去了,让新增的用户反馈界面用H5开发。甩锅于前端,经理说赶紧做,当天要!于是那天临近午饭时间,通知这个事情让我干,我心里是真的不是滋味,心里mmp。随即给我UI,告诉我说UI会裁好图给我。这图一直到下午4点,离下班还有两个小时的时候才给我的。这种做事效率让人心塞啊!但是也顾不得抱怨了,三下五除二,使用vue+vue-router+vant足以满足需求开发了。最终在下班之前还是打包交给服务器端了。

      服务器端部署项目之后,打开界面,白屏界面不出来,而且还不报错!这就尴尬了,没报错那是真的难找问题。他们服务器的人也倒腾了半天,没效果,我就不信邪,我说我以前打包的项目都是这样的,没出现过这样的问题。我就把这个项目部署在了自己的阿里云服务器上,试试看,却能看到界面效果!这就摸不着头脑了,问题还是要解决的。试了几次,终于找到了问题,router的history模式导致的问题。因为我自己的服务器的nginx配置时对这个mode进行了处理的,所有是没有问题,而这个项目的服务器端时没有对这个模式进行匹配处理的。那就先来说说vue-router的history模式了。

      HTML5 History模式

      vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

    const Router = require('vue-router')
    const router = new Router({
       mode:'history',
       routes: [...]  
    })

    当使用history模式时,url就像正常的url如https://i.cnblogs.com/EditPosts.aspx?opt=1。不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

    后台服务器nginx的配置需加上:

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

    完整的vue-router 的history模式可以点此学习:https://router.vuejs.org/zh/guide/essentials/history-mode.html

    由于当时服务器没有对这个history模式进行nginx配置,我只好把router处的mode:'history'去掉。后面那些路由不好看的啥子东西服务器那边配置的时候自行解决了。

      本以为都告一段落了,谁知这才刚刚开始。测试站测试人员提bug了。客户端测试人员用的安卓机,可不是正常的手机,是用那种低端机进行测试的,所以与我们在稍好一点的手机上看到的效果差别还是很明显的。测试人员说:进入H5页面会有闪屏出现,那个banner图片会闪一下再出来,体验很不好。

    我看了一下效果之后,我那是就有点底了,h5刚出来的时候,本应该是banner占据的位置,被下面的内容占据了,我心中一想可能是没有给图片的容器进行高度设置,才让这种闪屏出现。我觉得还应该对图片进行压缩处理,因为在移动端,对图片的压缩还是非常有必要的。虽然有时候有些损失图片的质量,但是其实在移动端,还是很难觉察到差别的。经过了对图片的高度设置和压缩之后,这种闪屏好了很多。

      解决了这个闪屏bug,满以为可以了。可是客户端的需求是不断改变的。客端户需要在无网络状态下,进入h5首页,然后连网之后,可以在页面上进行交互。

      我当时脑子是蒙的,我是拒绝的,我说这个应该是你们客户端解决的事情吧,客户端人员说需要三份代码,因为我们坐的这个用户反馈h5是有三种不同的语言的,中文、印尼语和英文,所以还是需要打包三份代码,用以针对三种不同语言的需求。以保存在客户端本地。打包好三份代码给客户端之后,客户端在无网络的情况下,打开用户反馈app,会自动调取本地存储的文件,这个时候问题就出来了,里面的icon图片位置有破图出现,而且点击进行交互没有反应,客户端显示的h5发起的请求地址居然是本地地址。这两个bug我是这样解决的:

    1、icon图片破图

      当图片不存在时,出触发onerror事件,这个时候我们就可以处理一下来让网页美观一些,有两个方法

    • 让这个图片元素隐藏 
      <img src="图片的url地址" alt="图片XX" onerror="this.style.display='none'"/>
    • 用默认的图片替换 
      <img src="图片的url地址" alt="图片XX" onerror="this.src='默认图片的url地址'"/>

    我使用的第二种方法,在vue中我们可以这样使用:

    data() {
        return {
             defaultImage: "this.src="+require('./assets/error.png')
         }
    }
    <img src="图片的url地址" alt="图片XX" onerror="defaultImage"/>

    2、无网络状态下调用客户端本地的文件,之后打开网络后,进行页面交互发起的请求地址不对

    使用vue+webpack打包上线的的文件,是需要部署在线上服务器的,能够以http等协议进行访问,在项目里面进行api请求,在线上都是以域名进行访问请求的,比如域名是:https://olqa.faceworld.top/,进行的api请求就是 https://olqa.faceworld.top/api/getCatogryList/lang=zh#/。当使用客户端本地的文件时,进行的请求访问地址就变成了 file://XXX/api/getCatogryList/lang=zh#/,这样的请求交互当然是不生效的。后来服务器开发人员给了我一个建议,让我写绝对地址,就是在交互请求的地址上把域名加上去。如下:

          axios({
                        url: 'https://olqa.faceworld.top/olqa/api/faq/getList.do',//把域名加上去
                        params: data,
                        method: 'POST',
                    }).then(res => {
                        if(res.status == 200 && res.data.data.length > 0) {
                            this.page ++;
                            this.searchList = this.searchList.concat(res.data.data);
                        }else if(res.status != 200){
                            this.loading = false
                        }else {
                            console.log('没有结果');
                            this.finished = true;
                        }
                        this.loading = false
                    }).catch(err => {
                        console.log('net timeout');
                        this.loading =false;
                    })

    之后进行打包交给客户端存储在本地。这也算是一种解决方法吧。

      任何项目完成上线都不是一帆风顺的。这不,测试人员说在低端机上,h5的首屏加载时间有点长,让我去研究研究改善用户体验。vue的SPA页面都是通过打包后的js文件进行解析后生成dom进行页面渲染的,如果对于js文件的解析比较慢,是会导致首屏加载时间较长。想着如果进行预渲染,可能会有出奇效果。找到了一款插件:prerender-spa-plugin,

    可以把页面单独打包出来,而且打包出来的index.html文件可以直接访问打开,如果放在客户端本地的话,效果应该不错。于是就试试:

    1、安装

     npm install prerender-spa-plugin --save-dev

     2、webpack.prod.conf.js增加部分代码

    const PrerenderSPAPlugin = require('prerender-spa-plugin')   //引用插件
    const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
    const webpackConfig = merge(baseWebpackConfig, {
        plugins: [
            // vue-cli生成的配置中就已有这个了,不要动
            new HtmlWebpackPlugin({
                filename: config.build.index,
                template: 'index.html',
                inject: true,
                minify: {
                    removeComments: true,
                    collapseWhitespace: true,
                    removeAttributeQuotes: true
                },
                chunksSortMode: 'dependency'
            }),
            // 配置PrerenderSPAPlugin
            new PrerenderSPAPlugin({
                // 生成文件的路径,也可以与webpakc打包的一致。
                staticDir: path.join(__dirname, '../dist'),
                
                // 对应自己的路由文件,比如index有参数,就需要写成 /index/param1。
                routes: ['/', '/detail','/search'],
               
                // 这个很重要,如果没有配置这段,也不会进行预编译
                renderer: new Renderer({
                    inject: {
                      foo: 'bar'
                    },
                    headless: false,
                    // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
                    renderAfterDocumentEvent: 'render-event'
                })
            })
        ]
    })

     3、在main.js中加入以下代码

    new Vue({
      el: '#app',
      router,
      render: h => h(App),
      mounted () {
        document.dispatchEvent(new Event('render-event'))
      }
    })

    4、使用npm run build打包,dist文件里面有每个路由对应的包 

     

     而且这里面直接打开index.html文件能够进行访问。

    把这种打包后的文件给了客户端,确实让首屏的加载速度上去了。只是这样打包的文件要比以前打包的文件体积稍大一点,不过综合比较,觉得这样的体验稍好一些,因为都是本地资源,加载速度还是比较快的。

    与客户端合作之旅暂告一段落!

     个人博客地址:https://www.zengfanping.com/

      

  • 相关阅读:
    实用的网站记录
    XML记一次带命名空间的xml读取
    WEB项目挂载到IIS session过期
    【EF】CodeFirst Fluent API使用记录
    【Unity】微软的一款依赖注入组件
    【AutoFac】依赖注入和控制反转的使用
    【JavaScript】封装实用方法【持续积累】
    【Config】类库读取自己的配置文件,配置文件的扩展
    【c#】队列(Queue)和MSMQ(消息队列)的基础使用
    0、Java配置----JDK开发环境搭建及环境变量配置
  • 原文地址:https://www.cnblogs.com/zengfp/p/10558470.html
Copyright © 2011-2022 走看看