3天一个小型活动到上线的逻辑和源码,使用到vue-cli3、vue、vue-router、vant-ui、微信sdk

本文档详细介绍了使用Vue.js、vant-ui、微信SDK等技术栈开发活动应用的过程,包括全局分享功能、首页倒计时、申请页表单验证和审核页逻辑判断等功能的实现。代码示例涵盖了从路由配置到各页面组件的编写,以及百度统计的集成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近半个月都好忙,连着4、5个活动,都没啥自己的时间了,今天整理下其中一个比较小的活动代码吧

包含的功能点:

(进入正题,下面这个花了大概3天的时间包括项目切分支新建、ui样式还原、接口对接、测试、测试bug修改、上线)
技术栈:vue、vue-router、vant-ui、微信sdk,还引入了flexible.js和pxtorem字体大小自适应<这块代码没列出来>
一全局:分享功能、百度统计
二首页:距离截止日期倒计时、若是已经申请的话从首页自动跳审核页、点申请跳申请页
三申请页:表单必填项验证提示、获取验证码接口、提交接口、样式处理、提交成功的审核时间的缓存
四审核页:有审核中样式、审核成功样式、根据缓存时间显示审核或成功的逻辑判断、老师接口、老师id对应的二维码缓存

一全局:分享功能

一:全局分享功能的实现

main.js添加下面二行代码
import state from "../libs/state"
Vue.use(state);


libs新建state.js文件,且state.js的代码如下
import Vue from 'vue';
export default {
    install() {
        const state = new Vue({
            data: {
            },
            created() {
                this.share();
            },
            methods: {
                share() {
                    iceflower.wxShare({ // iceflower是已经封装了的分享的功能的
                        appId: '***8',
                        url:  location.href.split('#/')[0],
                        apiTicket: '***',
                        title: `全国人才助学计划`,
                        desc: '你有1000元学历补贴待领取',
                        imgUrl: '*',
                        success: function () {
                            console.log('分享成功');
                        }
                    });
               }
            }
        })
        Vue.prototype.$state = state;
    }
}

二首页:距离截止日期倒计时、若是已经申请的话从首页自动跳审核页、点申请跳申请页 

二首页:距离截止日期倒计时、若是已经申请的话从首页自动跳审核页、点申请跳申请页

新建index.vue页面,代码如下
<template>
  <section class="container">
    <img class="img_box" src="****" alt="">
    <div class="time_box">
      <p class="tipTitle">距离名额申请截止还剩:</p>
      <p class="tipTime">
        <van-count-down style="display: inline-block" :time="endTime">
          <template v-slot="timeData">
            <span class="item">{{
              timeData.days * 24 + timeData.hours > 9 
              ? timeData.days * 24 +  timeData.hours 
              : "0" + (timeData.days * 24 + timeData.hours)
              }}</span>
              时
            <span class="item">{{timeData.minutes > 9 ? timeData.minutes : "0" + timeData.minutes}}</span>分
            <span class="item">{{timeData.seconds > 9 ? timeData.seconds : "0" + timeData.seconds}}</span>秒
          </template>
        </van-count-down>
      </p>
    </div>
    <div class="btn_box" @click="goPath('/userForm')">
      <img src="***" alt="">
    </div>
  </section>
</template>
<script>
export default {
  components: {},
  data() {
    return {
      endTime: new Date("2021/03/31 23:59").getTime() - new Date().getTime(),
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init() {
      if(localStorage.getItem('submitTime')) { // 如果有缓存了的话 就直接跳第等待成功页
        this.goPath('/waiting')
      }
    },
    goPath(path) {
      this.$router.push({
        path: path
      });
    }
  }
}
</script>

三申请页:表单必填项验证提示、获取验证码接口、提交接口、样式处理、提交成功的审核时间的缓存 


三申请页:表单必填项验证提示、获取验证码接口、提交接口、样式处理、提交成功的审核时间的缓存
这块代码写的不好 原先是用van-field自带的必填检验的,后来说不要又改了一波校验

新建form.vue页面,代码如下
<template>
  <div class="form-container">
    <div class="img_box">
      <img class="banner" src="../../assets/img/loginbg.png" alt="">
      <p class="title">2021年个人学历补贴申请表</p>
    </div>
    <div class="head_box"></div>
    <div class="form_box">
      <van-form   class="van-form">
          <van-field
            readonly
            required
            clickable
            name="area"
            v-model="area"
            label="省份"
            placeholder="请选择"
            @click="showArea = true"
          />
          <van-popup v-model="showArea" position="bottom">
            <van-area
              :area-list="areaList"
              @confirm="chooseArea"
              @cancel="showArea = false"
              :columns-num="1"
            />
          </van-popup>
          <van-field
            required
            class="mt20"
            v-model="studentName"
            name="studentName"
            label="姓名"
            placeholder="请填写真实姓名"
          />
          <van-field
            required
            class="mt20"
            type="tel"
            v-model="phone"
            name="phone"
            label="电话"
            placeholder="请输入电话"
          />
          <van-field
            v-model="sms"
            name="sms"
            required
            class="mt20"
            center
            maxlength="6"
            type="number"
            clearable
            label="验证码"
            placeholder="请输入验证码"
          >
            <template #button>
              <van-button v-if="!smsCodeLoading" size="small" type="info" @click="smsHandled" style="background-color:#1F69C3;">获取验证码</van-button>
              <van-button v-else size="small" type="info">{{time}}s</van-button>
            </template>
          </van-field>
          <van-field
            required
            class="mt20"
            v-model="cause"
            name="cause"
            :rows="3"
            label="申请原因"
            type="textarea"
            placeholder="请输入申请原因"
          />

          <div class="btn_box">
            <van-button round block type="info" native-type="submit" class="btn_tijiao" @click="onSubmit">
            提 交
            </van-button>
          </div>
      </van-form>
    </div>
    <div class="tips_box">
      <div class="tips_title">注意说明:</div>
      <div>1、本次补贴面向所有需要提升学历的人员,请符合条件的学员进行申请。</div>
      <div>2、上传信息将作为补贴申领凭证,请确保信息无误后提交。</div>
      <div>3、请妥善保管个人信息,勿随意向他人透露申领资料,谨防上当受骗。</div>
    </div>
  </div>

</template>
<script>
import md5 from 'js-md5';
import { Toast } from 'vant';
import areaList from "../../../libs/area.js"
import axios from "axios"
import qs from 'qs'
import common from "../../../libs/common"
export default {
  data() {
    return {
      studentName: '',
      phone: '',
      sms: '',
      major: '',
      area: '',
      cause: '',
      areaDetail: '',
      showPicker: false,
      showArea: false,
      areaList: areaList, // 数据格式见 Area 组件文档
      smsCodeLoading: false,
      time: 60
    };
  },
  mounted() {
  },
  methods: {

    onConfirm(value) {
        this.major = value;
        this.showPicker = false;
    },
    chooseArea(values) {
      this.area = values.map(item => item.name).join('/');
      this.showArea = false;
    },
    // 点击获取验证码按钮
    smsHandled: function() {
        if(common.checkMobile(this.phone)) {
            this.sendPhoneApi()
        } else {
            Toast.fail({ message: '请输入正确手机号'});
            return;
        }
    },
    onSubmit() {
        let values = {
          studentName: this.studentName,
          phone: this.phone,
          sms: this.sms,
          area: this.area,
          cause: this.cause,
        }
        for(let params in values) {
            if(values[params] === '') {
                Toast.fail({ message: '请填完整所有必填项'});
                return;
            }
            if(params === 'phone' && !common.checkMobile(values.phone)) {
                Toast.fail({ message: '手机格式错误'});
                return;
            }
        }
        if(this.sms.length !== 6) {
          Toast.fail({ message: '请输入正确的验证码'});
          return ;
        }
        values.activityId = common.getQueryString('activityId');
        values.id = common.getQueryString('id');
        values = Object.assign(values, { // 拼接这些固定的参数
          labelInfo: '**',
          productId: 1,
          subjectId: 1,
          courseId: ''
        })
        let params = common.paramsFilters(values)
        this.verifySmsCode(params); 
    },
    verifySmsCode(params) {
        axios.post('***/insertCrmOpportunityPool',qs.stringify(params)).then(res => {
            if(res.data.code === 'Success') {
                localStorage.setItem('submitTime',new Date().getTime() + 300000)
                this.$router.push("/waiting")
            }else  {
                Toast(res.data.msg);
            }
        })
    },
    sendPhoneApi() {
        var that = this;
        that.smsCodeLoading = true;
        that.time = 60;
        let countDownClock = setInterval(function() {
            that.time--;
            if (that.time <= 0) {
                clearInterval(countDownClock);
                that.smsCodeLoading = false;
            }
        }, 1000);
        let params = common.paramsFilters({phone: this.phone});
        axios.post('***/sendPhone',qs.stringify(params)).then(res => {
            if(res.data.code === 'Success') {
                Toast.success("发送成功")
            }else  {
                that.smsCodeLoading = false;
                clearInterval(countDownClock);
                Toast(res.data.msg);
            }
        })
    }
  },
};

</script>

 四审核页:有审核中样式、审核成功样式、根据缓存时间显示审核或成功的逻辑判断、老师接口、老师id对应的二维码缓存

四审核页:有审核中样式、审核成功样式、根据缓存时间显示审核或成功的逻辑判断、老师接口、老师id对应的二维码缓存

新建result.vue页面,代码如下
<template>
  <section v-if="this.status == 1" class="w-container">
    <img class="img_box" src="**/xueli_zx_zhong.png" alt="">
    <div class="content_box">
      <div class="content_top">您已成功提交,资格审核中……</div>
    </div>
    <div class="tips_box">
      <div>您的信息将由专业机构人工审核,</div>
      <div>预计耗时5分钟,请耐心等待。</div>
    </div>
    <div class="qrcode_box">
      <img class="qrcode_title" src="*/xueli_zx_er1.png" alt="">
      <img class="qrcode_teacher" :src="teacherQrcode" alt="">
    </div>
  </section>
  <section v-else class="w-container">
    <img class="img_box" src="**/xueli_zx_cheng.png" alt="">
    <div class="content_box2">
      <div class="content_top">已通过审核</div>
      <div class="content_bottom">获得 <span>1000</span> 元 学历补贴</div>
    </div>
    <div class="tips_box">
      <div>您已通过2021年全国人才助学计划</div>
      <div>资格名额审核,</div>
      <div>可享有成人高考学历补贴,</div>
      <div>请联系学历顾问激活个人名额。</div>
    </div>
    <div class="qrcode_box">
      <img class="qrcode_title" src="*/xueli_zx_er2.png" alt="">
      <img class="qrcode_teacher" :src="teacherQrcode" alt="">
    </div>
  </section>
</template>


<script>
import axios from "axios"
import qs from 'qs'
import common from "../../../libs/common"
import { Toast } from 'vant';
export default {
  components: {},
  data() {
    return {
      status: 1,
      submitTime: '',
      teacherQrcode: ''
    }
  },
  mounted() {
    this.init();
    this.getTeacherQrCode();
  },
  methods: {
    init() {
      if(!localStorage.getItem('submitTime')) {
        setTimeout(() => {
          this.status = 2
        }, 5 * 60000)
      } else if(localStorage.getItem('submitTime') > new Date().getTime()) {
        let newTime = localStorage.getItem('submitTime')  - new Date().getTime()
        setTimeout(() => {
          this.status = 2
        }, newTime)
      } else {
        this.status = 2
      }
    },
    getTeacherQrCode() {
      if(localStorage.getItem(`TeacherQrCode_${common.getQueryString('id')}`)) {
        this.teacherQrcode = localStorage.getItem(`TeacherQrCode_${common.getQueryString('id')}`);
        return ;
      }
      let params = common.paramsFilters({activityId:common.getQueryString('activityId'),id: common.getQueryString('id') })
      axios.post('*/getTeacherQrCode',qs.stringify(params)).then(res => {
            if(res.data.code === 'Success') {
                this.teacherQrcode = res.data.dataJson.qrCode;
                localStorage.setItem(`TeacherQrCode_${common.getQueryString('id')}`, res.data.dataJson.qrCode)
            }else  {
            }
        })
    },
  }
}
</script>

五:路由的配置 

五:路由的配置
在main.js中添加如下几行代码
import router from "../libs/router"
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')


然后新建libs/router.js页,具体代码如下

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
    scrollBehavior (to, from, savedPosition) { // 可以解决页面切换后自动滚动的顶部的问题提
        return { x: 0, y: 0 }
    } ,
    routes: [
        {
            path: '/',
            name: 'xueliZxPlan',
            component: () => import('@/pages/xueliZxPlan/index'),
            meta: {
                title: '全国人才助学计划'
            }
        },
        {
            path: '/form',
            name: 'form',
            component: () => import('@/pages/xueliZxPlan/form'),
            meta: {
                title: '全国人才助学计划'
            }
        },
        {
            path: '/result',
            name: 'result',
            component: () => import('@/pages/xueliZxPlan/result'),
            meta: {
                title: '全国人才助学计划'
            }
        },
    ]
})

拓展:如果需要百度统计的话,添加在public/index.html中

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0 maximum-scale=1.0, user-scalable=no">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title></title>
    <script src="<%= BASE_URL %>flexible.js" ></script>
    <script src="<%= BASE_URL %>iceflower.js" ></script>
  <body>
    <div id="app"></div>
    <script>
    //  百度统计代码
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://***";
      var s = document.getElementsByTagName("script")[0]; 
      s.parentNode.insertBefore(hm, s);
    })();
    </script>
  </body>
</html>

然后就是npm run build打包,我使用部署到线上的软件是FileZilla,拖拽打包后的文件dist,就可以访问链接了✌️

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值