投票H5的Vue实现

投票H5的Vue实现

最近一段时间明显感觉到业务在投票这一类的H5上聚集,每次都是业务部门提需求,设计出设计稿,然后到技术这边实现页面效果及投票逻辑。每次都在做这类机械的重复性工作,所以就想能不能进行一些抽象,用技术的手段将这些形成流水线(其实就是想把自己从中解放出来O(∩_∩)O哈哈~)。说干就干,跟后端的同学讨论了下,他也觉得有必要将这个独立开来,交到他们业务部门去。
在这里我只说前端H5用vue实现展示页面,因为后端管理系统这个很常规。

剥离页面配置属性

首先将一些可以公用的配置抽取出来,统一请求。这样在其他页面就可以不必浪费这个资源了。基本确定的要抽取出来的内容如下:

config: {
	header: '', //头图
	footer: '',	//底部logo
	share: '', //微信分享图片
	bg_color: '', //背景色
	title_color: '', //页面标题底色
	button_color: '', //按钮颜色
	progress_color: '' //进度条颜色
},

初步商定的公共资源也就这么多,准备是将这些配置统一请求用vuex状态管理。但是存在一个问题,当用户将子页面分享出去,其他人从分享页进入就造成拿不到配置。所以我将请求放在最外层的App.vue页面,如下:

<template>
  <div :style="{backgroundColor: $store.state.config.bg_color}">
    <router-view/>
  </div>
</template>

<script>
import { ajax } from 'jquery'

export default {
  name: 'App',
  created() {
  	let that = this;

		//路由配置
		that.$store.dispatch('checkHost', process.env.NODE_ENV);

  	//请求配置数据
		ajax({
			type: 'get',
			url: that.$store.state.Host+'/v/votes/'+that.$route.query.tt+'/config',
			success: function(res) {
				let config = {
					header: res.header,
					footer: res.footer,
					share: res.share,
					bg_color: res.bg_color,
					title_color: res.title_color,
					button_color: res.button_color,
					progress_color: res.progress_color
				};

				that.$store.dispatch('catchConfig', config);
			}
		});

  }
}
</script>

组件抽离

这里也没有多少能够通用的组件,一个是页面加载;另一个是分享引导。如图,
页面加载,

分享引导,

在这里遇到一个坑,加载的时候都还没什么问题。当在分享引导的时候在把引导页调出来后还有一个交互,一般是点击再隐藏。我把click事件放在组件上面,发现没有任何作用,然后在组件外包一层div,把click事件放在div上一切就ok了

//没有作用
<v-mock v-show="share" :style="{height: mock_height}" @click="shareCancel"></v-mock>

//改进后
<div @click="shareCancel">
  <v-mock v-show="share" :style="{height: mock_height}"></v-mock>
  <div class="clearfix"></div>
</div>

微信分享

关于微信分享,在微信公众号开发的官网也没有发现可以通过import引入的方式。每个页面都是独立的,也不能引入进去。不过还是感谢度娘,找到了一个说是微信官方出的weixin-js-sdk。对分享进行了一次封装,便于每个页面的不同分享配置。代码如下,

import {ajax} from 'jquery';
import wx from 'weixin-js-sdk';

var shareInfo = (function(mod) {

  function identify(URL) {
    var requestUrl = 'url';
  
    ajax({
      type:'post',
      url:requestUrl,
      data:{share_url:URL},
      success:function(res) {
        wx.config({
          debug: false,
          appId: res.data.appid,
          timestamp: res.data.timestamp,
          nonceStr: res.data.noncestr,
          signature: res.data.signature,
          jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareQZone']
        });
      }
    });
  }
  /**
   * [init description]
   * @author mao
   * @version 1
   * @date    2017-06-06
   * @param   {object}   options 穿入参数
   * img, title, desc, shareURL
   */
  mod.init = function(options) {
    //认证
    identify(options.shareURL);

    wx.ready(function(){
      var imageurl = options.img,
          title = options.title,
          desc = options.desc,
          link = options.shareURL;

      wx.onMenuShareTimeline({
        title: title,
        desc: desc,
        link: link,
        imgUrl: imageurl,
        success: function () {},
        cancel: function () {}
      });

      wx.onMenuShareAppMessage({
        title: title,
        desc: desc,
        link: link,
        imgUrl: imageurl,
        success: function () {},
        cancel: function () {}
      });

      wx.onMenuShareQQ({
        title: title,
        desc: desc,
        link: link,
        imgUrl: imageurl,
        success: function () {},
        cancel: function () {}
      });

      wx.onMenuShareQZone({
        title: title,
        desc: desc,
        link: link,
        imgUrl: imageurl,
        success: function () {},
        cancel: function () {}
      });
    });

    wx.error(function(res){
      console.log(res);
    });
  }

  return mod;
})(shareInfo || {});

export default shareInfo;

在这里我为什么用jQuery呢,其实还是有原因的。最初我也是用非常流行的axios,其他的地方请求都没有问题。但是就是在分享认证这里请求过来就报错,然后我又换了一个superagent发现返回报错一样。最后就换成了jQuery的ajax,这里可能后端同学对这个请求有限制吧。我知道是又一次是这样搞过的,不过因为后端同学也在忙没有跟他深究这个事情。留待后续讨论~

微信分享

其实这里还有一个比较大的bug,就是分享子页面出去如何从分享页进入到指定页面的问题。基本有以下两种思路,

  1. 使用动态路由,然后nginx配置相应的路由
  2. 使用带参数的动态路由
    本着自己动手丰衣足食的优良品质,能不麻烦别人就不麻烦别人。明智的选择了第二种方式,但是在这里也存在一个隐患。在分享出去之后无论是在iOS端还是Android端微信都会给分享页面加上一些参数,比如,
    iOS系统:'from=singlemessage&isappinstalled=0'
    Android系统: 'from=singlemessage'
    本来是一个单页应用,所以页面改变后会带着一些参数,最后再分享出去之后会把上述参数追加到后面。但是测试后发现用vue-router其实不必担心这个,因为通过key值找到固定的参数。后面query不会改变页面渲染。

前端存储

由于移动端有些网络状态不是很好,所以在交互上设计的策略是投票后就自动在前段把票数加上去,然后同时发post请求存储。这样就可以给用户有一个很好的交互。

{
	奖项id: {
		选项id: 票数,
		选项id: 票数,
		选项id: 票数,
		上限: 票数
	},
	奖项id: {
		选项id: 票数,
		选项id: 票数,
		选项id: 票数,
		上限: 票数
	}
}

在开发过程中老是不对,查了好久逻辑也没有任何问题。最后重头到尾有细细看了一下发现把变量名给搞错了。导致第一次进入的时候没问题,重复进入之后逻辑就不对了。所以敲代码还是要细心啊!

最后的效果如下图,




posted @ 2018-02-07 14:47  marvine  阅读(1502)  评论(2编辑  收藏  举报