vue之微信公众号开发

最近使用vue开发了一个购物类的微信公众号项目,将遇到的问题及大致的流程都给记录一下。

使用的是vue+vuex+vue-router+axios,样式用的是YDUI。

项目是需要做一个扫码之后通过微信openid做用户标识,然后让用户能够购买商品的小型购物网站,开始是仿照的慕课上某老师的回龙观项目,后来就加入了许多东西。

正文之前写说句感慨,没有系统学习vue就直接做vue项目简直是一直折磨。还有就是基础知识学的不扎实导致遇到一些问题浪费大量时间也不一定能搞出来。

首先先来看vue-router文件:

import Vue from ‘vue‘
import Router from ‘vue-router‘

import goodsDetail from ‘@/components/goodsDetail‘
import goodsList from ‘@/components/goodsList‘
import Mine from ‘@/components/mine‘
import mainPage from ‘@/components/mainPage‘
import submitOrder from ‘@/components/submitOrder‘
import confirmbuy from ‘@/components/confirmbuy‘
import skip from ‘@/components/skip‘
import subuserinfo from ‘@/components/subuserinfo‘

Vue.use(Router)
const router = new Router({
  // mode: ‘history‘,
  routes: [
    {
      path: ‘/‘,
      component: mainPage,
      name: ‘mainPage‘,
      children: [
        {
          path: ‘/‘,
          component: goodsList,
          name: ‘goodsList‘
        },
        {
          path: ‘/Mine‘,
          component: Mine,
          name: ‘Mine‘
        }
      ]
    },
    {
      path: ‘/skip‘,
      component: skip,
      name: ‘skip‘
    },
    {
      path: ‘/goodsDetail‘,
      component: goodsDetail,
      name: ‘goodsDetail‘
    },
    {
      path: ‘/submitOrder‘,
      name: ‘submitOrder‘,
      component: submitOrder
    },
    {
      path: ‘/confirmbuy‘,
      name: ‘confirmbuy‘,
      component: confirmbuy
    },
    {
      path: ‘/subuserinfo‘,
      name: ‘subuserinfo‘,
      component: subuserinfo
    }
  ]
})
export default router

贴vuerouter代码的目的主要是为了展示一下目录结构,这里面是点击了购物车组件之后跳转到提交界面,因为我最开始做的时候,把订单提交组件放到了购物车组件的子组件中,导致了样式发生了很low的错误,需要通过z-index去设置组件的显示级别,后来就都弄成兄弟组件就好了。

mainjs中主要是一些公共方法,下面是一段封装了axios请求,并能够排序进行md5校验的代码,

import axios from ‘axios‘
import querystring from ‘querystring‘
import crypto from ‘crypto‘

Vue.use(YDUI)
// Vue.use(axios)
Vue.config.productionTip = false
Vue.prototype.$domain = ‘http://xianghuali.cn‘  //接口域名/ip
Vue.prototype.$http = function (options) {
  var defaultParam = {
    url: ‘‘,
    method: ‘post‘,
    baseURL: `http://sbf.zzcyi.cn`,
    transformRequest: [function (data) {
      var q = querystring.stringify(data)
      return q
    }],
    // headers: {‘Content-Type‘: ‘application/x-www-form-urlencoded‘},
    params: {},
    data: {},
    timeout: 10000,
    responseType: ‘json‘
  }
  var ajaxParam = {}
  for (var k in defaultParam) {
    ajaxParam[k] = options[k] ? options[k] : defaultParam[k]
  }
  console.log(ajaxParam)
  if (ajaxParam.url === ‘‘) {
    alert(‘请传入请求URL‘)
    return null
  }
  return axios(ajaxParam)
}
Vue.prototype.$md5 = function (str) {
  var md5 = crypto.createHash(‘md5‘)
  md5.update(str)
  return md5.digest(‘hex‘)
}

我使用vuex主要就是为了缓存一些全局参数,例如用户添加的商品数据等信息。其实使用vue做公众号并没有与做pc端有很大的区别,主要是有一些需要主要的地方。

首先是微信请求之后的回调路径,因为我没搞清楚本地调试ip+端口怎么通过微信验证,并且能够回跳回来,所以在开始做支付之后就写上了服务器地址,下面是微信获取用户openid的代码,

function GetOpenId (that, wxappid) {//wxappid是微信公众号后台的appid
  var code = getQueryString(‘code‘)
  var redirecturl = encodeURIComponent(`${that.$domain}/index.html`) //这里是回调地址,可以看到我在组件中调这个方法的时候,把vue的this对象传递了尽量,然后把vue原型链上挂载的地址显示出来
  var imei = window.location.href.split(‘?‘)[1].split(‘#‘)[0].replace(‘imei=‘, ‘‘)
  if (!code && !window.sessionStorage.getItem(‘openidobj‘)) {//如果没有code,并且sessionstorage中没有用户的openid,就跳转到微信授权页,然后回跳回来走else if
    window.location.href = ‘http://open.weixin.qq.com/connect/oauth2/authorize?appid=‘ + wxappid + ‘&redirect_uri=‘ + redirecturl + ‘&response_type=code&scope=snsapi_userinfo&state=‘ + imei + ‘#wechat_redirect‘
  } else if (code && !window.sessionStorage.getItem(‘openidobj‘)) {//请求接口获取openid
    that.$http({
      url: `${that.$domain}/WxPay/QryWebAccessToken?code=${code}`,
      method: ‘get‘
    }).then((res) => {
      if (res.data.openid) {
        window.sessionStorage.setItem(‘openidobj‘, res.data.openid)
        that.$http({
          method: ‘post‘,
          url: `${that.$domain}/WxPay/GetWxUserInfo`,
          data: {
            openid: res.data.openid
          }
        }).then((res) => {
          if (res.data.status === ‘ok‘) {
            window.sessionStorage.setItem(‘wxuserinfo‘, res.data.memo)
            that.$router.replace(‘/‘)
          } else {
            that.$dialog.toast({mes: res.data.memo})
          }
        })
      }
    })
  } else {
    that.$http({
      method: ‘post‘,
      url: `${that.$domain}/WxPay/GetWxUserInfo`,
      data: {
        openid: window.sessionStorage.getItem(‘openidobj‘)
      }
    }).then((res) => {
      if (res.data.status === ‘ok‘) {
        window.sessionStorage.setItem(‘wxuserinfo‘, res.data.memo)
        that.$router.replace(‘/‘)
      } else {
        that.$dialog.toast({mes: res.data.memo})
      }
    })
  }
}

这里牵扯到一个问题就是界面需要加载进来,然后跳转到微信,然后在跳回来,如果直接显示页面会让用户体验很不好,参考了网上的做法,做了一个等待页,专门用来显示给用户并获取用户信息的,获取信息之后在跳回来进行后面的操作。

其实我感觉vue与之前我们习惯的dom操作最大的区别就是,vue没有直接对父子兄弟元素进行操作的方法,而是通过传值,flag,通过函数改变变量来间接的操作目标元素。开始不习惯的时候感觉做起来很吃力,写多了之后也就习惯了,只要能记得变量要及时清除重新赋值即可。项目中使用的微信支付,主要是掉后台接口,没有什么要记录的。下面说一下socket以及百度地图,

首先是socket,因为需要通过socket与设备通讯,所以在界面一进来就要建立一个长连接,参考上面vue-router中的路由配置,这里就是在用户逗留时间最多的商品列表组件goodsList的父组件mainPage中创建的,mainPage.vue代码如下

<template>
  <div>
    <v-header></v-header>
    <div class="tab">
      <div class="tab-item">
        <router-link to="/" replace>商品</router-link>
      </div>
      <div class="tab-item">
        <router-link to="/Mine" replace>订单</router-link>
      </div>
    </div>
    <keep-alive>
      <router-view />
    </keep-alive>
  </div>
</template>

<script>
import header from ‘./header‘
import ‘../../static/boundleProto‘
// import ‘../../static/CySocket‘
import {GetOpenId} from ‘../../static/common‘

import {CySocket} from ‘../../static/CySocket‘
import {GetSignature} from ‘../../static/common‘
import Vue from ‘vue‘
export default {
  name: ‘mainPage‘,
  components: {
    ‘v-header‘: header
  },
  created () {
    // var imei=‘ZZCY5ccf7fdf754c‘;
    this.$http({
      url: `${this.$domain}/Home/QryConfig`,
      method: ‘get‘
    }).then((res) => {
      // GetOpenId(this,res.data.WxAppId)
      this.formatdate()
      var that=this;
      this.$store.state.refundTimeRange=res.data.refundTimeRange
      if(!window.sessionStorage.getItem(‘wxuserinfo‘)){
        var t=setInterval(function(){
          if(window.sessionStorage.getItem(‘wxuserinfo‘)){
            that.creatsocket(res.data.ServerIpEp);
            clearInterval(t)
          }
        },10)
      }else{
        that.creatsocket(res.data.ServerIpEp);
      }
    })
  },
  beforeRouteEnter (to, from, next){
    next(vm=> {
      if(!window.sessionStorage.getItem("wxuserinfo")){
        next("/skip");
      }
    })
  },
  methods: {
    //实例化socket
    creatsocket(serverIp){
      var wxuserinfo=JSON.parse(window.sessionStorage.getItem(‘wxuserinfo‘)).LoginNo
      if(!wxuserinfo){
          this.$dialog.toast({mes: ‘获取参数错误‘});
      };
      var that=this
      Vue.prototype.cySocket = new CySocket({
        server:`ws://${serverIp}`,
        autoReconnect: true,
        openSocket: function() { //连接socket后立即发送登录包
            var user = new window.proto.SocketCmd.CmdHeader();
            user.setCmdcode("0202"); //命令号
            user.setIdentity(wxuserinfo); //客户端标识
            user.setTimetoken(new Date().format("yyyy-MM-dd hh:mm:ss")); //命令时间
            this.sendMsg(user.serializeBinary());
            var imei=window.sessionStorage.getItem(‘imei‘);
            //查询设备状态
            if(!imei||!wxuserinfo){
              that.$dialog.toast({mes: ‘出现异常···请重新扫码‘});
            }else{
              var qrydevice = new window.proto.SocketCmd.CmdHeader();
              qrydevice.setCmdcode("0203");
              qrydevice.setIdentity(wxuserinfo);
              qrydevice.setOppositeid(imei);
              qrydevice.setTimetoken(new Date().format("yyyy-MM-dd hh:mm:ss.S")); //命令时间
              this.sendMsg(qrydevice.serializeBinary());
              var time_=0;
              var t=setInterval(function(){
                time_+=1;
                if(that.$store.state.socketbacksocket){
                  clearInterval(t)
                }else if(time_>=1000){
                  clearInterval(t)
                }
              },10)
            }
        },
        receiveMsg: function(data) {
            var commBk = window.proto.SocketCmd.ComCmdBkPb.deserializeBinary(data);
            var msg = "";
            switch (commBk.getCmdcode()) {
            case "0202": //客户端登录
                msg = "登录返回:" + commBk.toString();
                break;
            case "0103":
                msg = "状态查询返回:" + commBk.toString();
                if(commBk){
                  that.$store.state.socketbacksocket=true
                }
              break;
            case "0104": //控制返回消息
                var lockBk = window.proto.SocketCmd.OpenLockBkPb.deserializeBinary(data);
                msg = "控制开锁返回:" + lockBk.toString();
                that.$store.state.deviceState = true
                if(that.$store.state.opendoorfrom == ‘mineorder‘){
                  that.$http({
                    method: ‘post‘,
                    url: `${that.$domain}/WxPay/TxUpdateOrderState`,
                    data: {
                      orderId: that.$store.state.orderId,
                      state: ‘SUCCESSU‘
                    }
                  }).then((res) => {
                  })
                }
                that.$dialog.toast({mes: ‘开锁成功‘});
                break;
            case "0105":
                msg = "补货开大门返回:" + commBk.toString();
                break;
            }
        }
      });
      Vue.prototype.cySocket.init();
    },  //格式化时间
    formatdate(){
      Date.prototype.format = Date.prototype.format||function (fmt) {
        var o = {
            "M+": this.getMonth() + 1, //月份
            "d+": this.getDate(), //日
            "h+": this.getHours(), //小时
            "m+": this.getMinutes(), //分
            "s+": this.getSeconds(), //秒
            "q+": Math.floor((this.getMonth() + 3) / 3), //季度
            "S": this.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
      }
    }
  }
}
</script>
<style>
@import "../common/index.css";
.tab{
  display:flex;
  width:100%;
  height:40px;
  line-height:40px;
  border-bottom: 1px solid rgba(7,17,27,0.1);
}
.tab .tab-item{
  flex:1;
  text-align:center;
}
.tab .tab-item a{
  display:block;
  font-size:14px;
  color:rgb(77,85,93);
}
.tab .tab-item a:hover , .tab .tab-item a.router-link-exact-active{
  font-size:14px;
  color:#f01414;
}
</style>

其中socket这部分因为要传bype,而之前做的项目已经被bype传伤了,所以后台大佬用google巨佬们开源的protobuffer封装了前后台及硬件c的protobuf代码,不用拼bype可以直接传~~~~,因为使用了vue的keep-alive组件,所以组件可以缓存,socket在切换了之后也不会断,暂时没有研究不使用keep-alive组件,切换兄弟组件之后上个组件注销会不会导致socket断开。其他子组件发送socket只需要将数据塞到挂载在vue原型链上的cysocket对象就行了

  opendoor(){
      var imei=window.sessionStorage.getItem(‘imei‘);
      var wxuserinfo=JSON.parse(window.sessionStorage.getItem(‘wxuserinfo‘)).LoginNo
      var boxInfo = new window.proto.SocketCmd.OpenLockPb();
      boxInfo.setCmdcode("");//从这里开始
      boxInfo.setIdentity(wxuserinfo);
      boxInfo.setOppositeid(imei);
      boxInfo.setOrderid(this.orderId);
      boxInfo.setLockstatus(this.lockstate);
      boxInfo.setTimetoken(new Date().format("yyyy-MM-dd hh:mm:ss.S"));//命令时间  //到这里结束,都是自己定义的参数,因为是protobuffer封装过的,所以可以直接传了···
      this.cySocket.sendMsg(boxInfo.serializeBinary());
      this.$store.state.opendoorfrom=‘suborder‘
    },

其实这段socket代码并没有前端太多事,编译ptobuf我也不懂,以后有时间,学习了后端之后再去研究一下,js操作二进制数据可以参考我的另一篇博客

下面是微信jsapi获取用户坐标并在百度地图中显示出来,

首先是算签名的公共方法,并传进去callback获取用户坐标

function GetSignature (that, callback) {
  that.$http({
    url: `${that.$domain}/WxPay/QryWxSignature?url=${window.location.href.split(‘#‘)[0]}`,
    method: ‘get‘
  }).then((data) => {
    AppId = data.data.appId
    Timestamp = data.data.timestamp
    Signature = data.data.signature
    Noncestr = data.data.nonceStr
    wx.config({
      beta: true,
      debug: false,
      appId: AppId,
      timestamp: Timestamp,
      nonceStr: Noncestr,
      signature: Signature,
      jsApiList: [
        ‘checkJsApi‘,
        ‘onMenuShareTimeline‘,
        ‘onMenuShareAppMessage‘,
        ‘onMenuShareQQ‘,
        ‘onMenuShareWeibo‘,
        ‘hideMenuItems‘,
        ‘showMenuItems‘,
        ‘hideAllNonBaseMenuItem‘,
        ‘showAllNonBaseMenuItem‘,
        ‘translateVoice‘,
        ‘startRecord‘,
        ‘stopRecord‘,
        ‘onRecordEnd‘,
        ‘playVoice‘,
        ‘pauseVoice‘,
        ‘stopVoice‘,
        ‘uploadVoice‘,
        ‘downloadVoice‘,
        ‘chooseImage‘,
        ‘previewImage‘,
        ‘uploadImage‘,
        ‘downloadImage‘,
        ‘getNetworkType‘,
        ‘openLocation‘,
        ‘getLocation‘,
        ‘hideOptionMenu‘,
        ‘showOptionMenu‘,
        ‘closeWindow‘,
        ‘scanQRCode‘,
        ‘chooseWXPay‘,
        ‘openProductSpecificView‘,
        ‘addCard‘,
        ‘chooseCard‘,
        ‘openCard‘,
        ‘openWXDeviceLib‘,
        ‘closeWXDeviceLib‘,
        ‘configWXDeviceWiFi‘,
        ‘getWXDeviceInfos‘,
        ‘sendDataToWXDevice‘,
        ‘startScanWXDevice‘,
        ‘stopScanWXDevice‘,
        ‘connectWXDevice‘,
        ‘disconnectWXDevice‘,
        ‘getWXDeviceTicket‘,
        ‘WeixinJSBridgeReady‘,
        ‘onWXDeviceBindStateChange‘,
        ‘onWXDeviceStateChange‘,
        ‘onScanWXDeviceResult‘,
        ‘onReceiveDataFromWXDevice‘,
        ‘onWXDeviceBluetoothStateChange‘
      ]
    })
    wx.ready(function (res) {
      // alert(‘调用微信jsapi返回的状态1:‘ + JSON.stringify(res))
      if (callback) callback()
      wx.error(function (res) {
        // alert(‘调用微信jsapi返回的状态2:‘ + JSON.stringify(res))
      })
    })
  })
}

然后是在地图组件map中调用该方法,并在获取到坐标之后实例化地图

<template>
    <div id="mymap">

    </div>
</template>
<script>
import {GetSignature} from ‘../../static/common‘
import wx from ‘weixin-js-sdk‘
import Vue from ‘vue‘
export default{
    name:‘maps‘,
    data() {
        return{
            lng_:null,
            lat_:null
        }
    },
    created () {
        // GetSignature(this)
    },
    mounted() {
        this.$nextTick(function () {
            var that=this;        //校验签名并获取坐标
            GetSignature(this,function(){
                wx.getLocation({
                    type: ‘gcj02‘, // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入‘gcj02‘
                    success: function (res) {
                        var latitude = res.latitude // 纬度,浮点数,范围为90 ~ -90
                        var longitude = res.longitude // 经度,浮点数,范围为180 ~ -180。
                        var lng = longitude
                        var lat = latitude
                        var xpi = 3.14159265358979324 * 3000.0 / 180.0
                        var x = lng
                        var y = lat
                        var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * xpi)
                        var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * xpi)
                        lng = z * Math.cos(theta) + 0.0065
                        lat = z * Math.sin(theta) + 0.006
                        that.$store.state.lng = lng
                        that.$store.state.lat = lat
                        var map = new BMap.Map("mymap",{enableMapClick:true});
                        // 初始化地图,设置中心点坐标和地图级别
                        var point;
                        var marker;
                        point=new BMap.Point(that.$store.state.lng,that.$store.state.lat)
                        map.centerAndZoom(point, 16);
                        var movemarkerIcon = new BMap.Icon("/reserve/static/img/moveicon.png", new BMap.Size(36,36),{
                            imageSize: new BMap.Size(36,36)
                        });
                        var movemarker;
                        map.enableDragging();   //地图拖拽
                        getneardevice()
                    // 添加带有定位的导航控件
                        var navigationControl = new BMap.NavigationControl({
                            // 靠左上角位置
                            anchor: BMAP_ANCHOR_TOP_LEFT,
                            // LARGE类型
                            type: BMAP_NAVIGATION_CONTROL_LARGE,
                            // 启用显示定位
                            enableGeolocation: true
                        });
                        map.addControl(navigationControl);
                        //地图拖动事件
                        // map.addEventListener("dragend",getneardevice);
                        // 添加定位控件
                        var geolocationControl = new BMap.GeolocationControl();
                        geolocationControl.addEventListener("locationSuccess", function(e){
                            // 定位成功事件
                            that.$store.state.lng = e.point.lng;
                            that.$store.state.lat = e.point.lat;
                            that.lng_ = e.point.lng
                            that.lat_ = e.point.lat
                            point=new BMap.Point(e.point.lng,e.point.lat)
                            map.centerAndZoom(point, 16);
                            getneardevice()
                        });
                        geolocationControl.addEventListener("locationError",function(e){
                            // 定位失败事件
                            that.$dialog.toast({mes: e.message,timeout:500});
                        });
                        map.addControl(geolocationControl);
                        // map.enableScrollWheelZoom(true);
                        function attribute(){
                            var p = movemarker.getPosition();  //获取marker的位置
                            getneardevice(p.lng,p.lat);
                        }
                        //获取设备
                        function getneardevice(lng,lat){
                            map.clearOverlays();
                            that.$dialog.loading.open(‘正在加载点位数据‘);
                            point=new BMap.Point(that.$store.state.lng,that.$store.state.lat)
                            marker = new BMap.Marker(point);// 创建标注
                            if(lng&&lat){
                                that.lng_ = lng
                                that.lat_ = lat
                                movemarker = new BMap.Marker(new BMap.Point(lng,lat),{icon:movemarkerIcon});// 创建标注
                            }else{
                                that.lng_ = that.$store.state.lng
                                that.lat_ = that.$store.state.lat
                                movemarker = new BMap.Marker(point,{icon:movemarkerIcon});// 创建标注
                            }
                            map.addOverlay(marker);             // 将标注添加到地图中
                            map.addOverlay(movemarker);             // 将可移动点
                            movemarker.enableDragging()
                            movemarker.addEventListener("dragend",attribute);
                            that.$http({
                                method: ‘get‘,
                                url: `${that.$domain}/ProductModule/QryNearbyImeiInfo?lng=${that.lng_}&lat=${that.lat_}`
                            }).then((res) => {
                                that.$dialog.loading.close();
                                if(res.data){
                                    var myIcon = new BMap.Icon("/reserve/static/img/mapicon.png", new BMap.Size(36,36),{
                                        imageSize: new BMap.Size(36,36)
                                    });
                                    for(var i=0;i<res.data.length;i++){
                                        var point_=new BMap.Point(res.data[i].ImeiLongitude,res.data[i].ImeiLatitude)
                                        var marker_ = new BMap.Marker(point_,{icon:myIcon});// 创建标注
                                        marker_.imei=res.data[i].ImeiMac
                                        map.addOverlay(marker_);
                                        //点击坐标点事件
                                        marker_.addEventListener("click",function(e){
                                            that.$store.state.imei=e.target.imei;
                                            window.sessionStorage.setItem(‘imei‘,e.target.imei)
                                            that.$http({
                                                method: ‘get‘,
                                                url: `${that.$domain}/ApiDevice/QryImeiInfo?imeiMac=${e.target.imei}`
                                            }).then((res) => {
                                                if(res.data.data[0].ImeiStatusNo==‘On‘){
                                                    if(res.data.data[0].ImeiIsPreOrder==‘Y‘){
                                                        if(JSON.parse(window.sessionStorage.getItem(‘wxuserinfo‘)).UserInfo.IsApprove){
                                                            that.$router.push(‘/goodsList‘)
                                                        }else{
                                                            that.$router.push(‘/statement‘)
                                                        }
                                                    }else{
                                                        that.$dialog.toast({mes: ‘该设备未开启预订功能‘,timeout:500});
                                                    }
                                                }else{
                                                    that.$dialog.toast({mes: ‘该设备已离线‘,timeout:500});
                                                }
                                            })
                                        })
                                    }
                                }
                            })
                        }
                    }
                })
            })
        })
    },
    methods: {
        getlng(){
            return this.$store.state.lng
        },
        getlat(){
            return this.$store.state.lat
        },    //坐标转换
        getTrasSite(longitude,latitude){
            var lng = longitude
            var lat = latitude
            var xpi = 3.14159265358979324 * 3000.0 / 180.0
            var x = lng
            var y = lat
            var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * xpi)
            var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * xpi)
            lng = z * Math.cos(theta) + 0.0065
            lat = z * Math.sin(theta) + 0.006
            // var x = lng - 0.0065, y = lat - 0.006;
            // var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * xpi);
            // var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * xpi);
            // lng = z * Math.cos(theta);
            // lat = z * Math.sin(theta);
            return{
                lng:lng,
                lat:lat
            }
        }
    }
}
</script>
<style lang="scss" scoped>
#mymap{
    width: 100vw;
    height: 100vh;
}
</style>

其中获取设备是类似摩拜的那种需求。

在手机端需要面对的一个问题就是,用户点击home键而不去点你设置好的按钮,那么路由就会非常乱,现在有几种处理方法,但是都不是很完美,

首先是vue-router的replace方法,这个方法与push方法的不同就在于push是向浏览器地址栈中一直添加,[a,b,c,d],这样子,也可能是[a,b,c,d,a,a,a,a]这样,而replace是将当前的路径替换,但是并不是消除,例如[a,b,c],下一个路由你用this.$router.replace(‘/d‘),路由就变成了[a,b,d],暂时没找到方法清除路径记录的,可能js中有这个方法,下去有时间再研究一下。

然后是vuerouter的导航守卫。分别使用beforeRouteEnter和beforeRouteLeave来监听,其中需要注意的就是beforeRouteEnter中没有this对象,因为这时候组件还没有开始创建,可以在回调方法中访问:

beforeRouteEnter (to, from, next) {//两个方法都可以在这里进行判断,如果离开要去的路由或者路由来源不是自己想要的,就进行中断或者跳转
    if(from.path == ‘‘||to.path == ‘‘) {
      next(vm=>{
        //这里的vm就是this,在这里可以进行一些操作
      })
    }
    next()
  },

具体内容参考官方文档   https://router.vuejs.org/zh-cn/advanced/navigation-guards.html。

--END

整篇文章并没有太多高技术含量的内容,但是因为当初并没有系统学习vue,只是看了看官网文档,看了点视频就开始做项目了,导致很多东西都不懂,做项目很吃力。以后学习如果有时间还是要系统的学习。

再此做记录备忘,以及给和我一样遇到同样问题的人一些帮助

原文地址:https://www.cnblogs.com/xianghuali/p/8953822.html

时间: 2024-07-31 17:49:14

vue之微信公众号开发的相关文章

《初识Java微信公众号开发》 学习中遇到的困难

前一段时间无聊的时候,在慕课网上自学了一点点微信公众号开发(受学姐威胁). 慕课网教程的地址:http://www.imooc.com/learn/368 毕竟是免费的课程,不可能讲的那么详细.所以我吧我遇到的问题跟大家分享一下. 这是我照着课程敲的代码(IDE是Eclipse): https://github.com/Zuosy/WeiXin 发到github上面了. 为了这个,我还专门到廖大的网站上学了一遍Git. 廖大的Git教程传送们:https://www.liaoxuefeng.co

微信公众号开发总结

最近公司用到了微信公众平台,所以研究了一下微信公众号的开发技术,总体来说比较简单,结合现有的平台核技术,实现起来非常方便. 首先先来了解一下微信公众平台. "微信,是一个生活方式" ,这是微信的自我评价,是不是觉得如果那天不在朋友圈里分享一下自己的最新状态, 并且收到几个赞和评价的话,会觉得空虚寂寞呢?它实实在在的改变了我们的生活方式. " 微信,也是一个生意方式 ",在微信成为我们日常必备之app的同时,它同样具备巨大的的商业 或许不应该称为潜力,因为有很多人已经

微信公众号开发80端口映射之搭建ngrok服务器

说明 了解本文之前,最好先看前篇:<<微信公众号开发80端口映射解决方案>>.最近公司要搞微信公众号开发,需要解决80端口映射的问题,为了稳定可靠,只好自己搭建ngrok服务端.ngrok 是一个使用go语言编写的反向代理软件,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道,实现内网穿透.ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放. 环境和条件 服务器Centos6.8_x64+windows10_x64 一台有公网ip的服务器 域名解析到服务

C#微信公众号开发 -- (五)自定义菜单创建

公众号中,底部都是有自己定义的功能按钮,通过点击某个按钮来实现指定的业务逻辑操作. 下面就来说说这些按钮是怎样放到微信公众平台的,还是先来看看微信的官方解释: 请注意: 1.自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单. 2.一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替. 3.创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单, 如果菜单有更新,就会刷

.NET C#微信公众号开发远程断点调试(本地远程调试生产环境)

最近在做微信公众号开发,由于之前没有接触过,突然发现调试不方便,不方便进行断点跟踪调试.因为微信那边绑定的服务器地址必须是公网地址,但是还是想进行断点调试(毕竟这样太方便了) 因此上网搜了一下,发现好多是使用软件之类的进行请求转发从生产环境转发请求到开发环境上,发现有的太麻烦了. 突然想到Vs有一个附加到进程的远程调试.于是玩了一把.我们直接开始(服务器上就不要使用发布版本代码了,代码和本地开发一样,不然是不能调试的) 本篇是以开发环境的Visual Studio2013旗舰版以及生产环境里阿里

利用OpenShift托管Node.js Web服务进行微信公众号开发

最近写了一个微信的翻译机器人.用户只要关注该微信号,发送英文的消息,就能收到中文翻译的回复.后台是用Node.js写的,托管在OpenShift的Paas平台上.翻译过程实际上是调用微软的Bing translation API做的,代码中用到了alexu84的bing-translate和JacksonTian的wechat这两个npm模块.下面把做的过程详细说一下. 1. 微信公众号开发 首先是要到https://mp.weixin.qq.com 申请一个公众号,并申请成为开发者.目前个人只

nodejs + BAE 搭建微信公众号开发平台

闲来无事创建了一个微信公众账号,名曰“深圳生活小助手”, 关注的人不多,平时发一些深圳新闻,趣事啥的,为了丰富公众号的内容,准备添加一些便民查询功能,例如天气预报.快递查询等等. 于是就有了本文的内容. 深圳的读者扫描关注支持下啊... 闲话不多说,本文主要介绍的就是如何基于nodejs和百度云搭建微信公众号开发平台,下一节介绍如何基于该平台实现了一个简单的天气预报查询功能的小例子. 1. 使用Express搭建本地站点 Express 是一个简洁.灵活的 node.js Web 应用开发框架,

微信公众号开发及时获取当前用户Openid及注意事项

目录 (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 (四)微信公众号开发之网页授权获取用户基本信息 (五)微信公众号开发之网页中及时获取当前用户Openid及注意事项 前言 这篇主要是承接上篇的网页授权获取用户基本信息的后文,也是对第一种静默授权之后,用户点击公众号内链接时,如何再次取得当前用户的OpenId的大致讲解和一些注意事项. 看过上一篇的小伙伴都知道,我们在用户关注的时候就已经将该用户的基本信息存入数据库中,那么如果

微信公众号开发模式开启总结

一直没想过要开个微信公众号,想到经营公众号估计跟经营微博一样,像我这种素质的,肯定没有这种基因. 师兄推荐了一个学经济的妹纸过来请教我微信公众号开发者模式如何开启,妹纸请教,那必须上刀山下火海哇. 稍作研究了一下,其实并不复杂,妹纸被卡到的地方是输入URL和Token的地方,其实这个URL和Token想明白了还是很容易理解的.微信的开发者模式的意义在于,当订阅者通过菜单栏或者发送消息等方式向公众号发送请求的时候,请求会首先到达微信服务器,然后微信服务器需要把这个请求再转发给开发者自己的网站服务器