1. 老生常谈微信授权
微信授权这个东西吧,全部让后端做,后端不高兴,全是前端做的话,但是微信上有文档说明有些数据要放在服务器上发起与存储。所以我和后台商量了一下就我们两个人结合,我前端发请求取请求微信的code。我拿code去请求用户的数据(code换取access_token,access_Token获取appId,appId获取用户数据)这些都放在后端去做
<1>用户什么时候去授权,该怎么去授权(路由钩子)
首先明确一点,新用户访问公众号的第三方网页肯定是要授权。这个授权我的做法是在需要访问的菜单上(路由)加了一个requireAuthor,然后使用路由的钩子函数beforeEach去判断哪个菜单要授权,同时呢还要看本地是否有这个用户的缓存数据,是不是有code。有这个用户但是没有code,说明这个用户授权过期了,需要重新授权,有code,但是没有用户信息,那说明这是一个新用户。
import rotuer from './index'
import store from '../store/store'
import {getWechatAuthore} from '../api'
rotuer.beforeEach((to, from, next) => {
let wxcode = getulrparam("code");
let users = store.getters.getStore;
let uri = encodeURIComponent("http://XXX.cn");
if (to.meta.requireAuth) {
if (wxcode == null && users == null) {
location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=3&redirect_uri=${uri}&response_type=code&scope=snsapi_userinfo&state=1&connect_redirect=1#wechat_redirect`;
} else {
if (wxcode !== null && users == null) {
getWechatAuthore(wxcode).then(res => {
store.commit("setStore", res)
});
next();
}
if (users !== null && wxcode == null) {
next();
}
next()
}
next();
} else {
next();
}
// next()
});
function getulrparam(name) {
let reg = new RegExp("(|&)" + name + "=([^&]*)(&|$)");
let r = window.location.search.substring(1).match(reg);
if (r != null) return unescape(r[2]);
return null
}
2 使用vant的File,但是这个东西没有校验如何解决(vee-validate)
第一次使用有赞的东西,觉得样式挺好的。写完以后我发现这个完善资料这个组件里面要校验的东西太多了,我不能自己一个一个去校验吧,不大现实。去网上找了一下,说是有vee-validate这个插件可以解决,我装上以后发现按照网上的说法来做根本行不通。所以我去官网上看了一下,人家现在是3.X的版本了,里面的api完全变了。可以说变得更简单了,新的版本采用了观察者模式,只不过一开始被网上的2.X的教程误导了。如果你觉得这个框架校验的不够全面,那就自己定义,这里我自己定义的校验手机号,身份证,体重身高的范围值的校验
// 手机号码验证
extend('mobile', {
message: () => `请输入正确的手机号码`,
validate: value => value.length === 11 && /^(((13[0-9]{1})|(14[57]{1})|(15[012356789]{1})|(17[03678]{1})|(18[0-9]{1})|(19[89]{1})|(16[6]{1}))+\d{8})$/.test(value)
});
extend('idCard',{
message:()=> `请输入正确的身份证号码`,
validate:value => value.length === 18 && /^[1-9][0-9]{5}([1][9][0-9]{2}|[2][0][0|1][0-9])([0][1-9]|[1][0|1|2])([0][1-9]|[1|2][0-9]|[3][0|1])[0-9]{3}([0-9]|[X])$/.test(value)
})
extend('number',{
message:()=> `请输入正确数字`,
validate:value => value*1 < 500 && /^\+?[1-9][0-9]*$/.test(value)
})
然后在mainjs中引用这个规则文件,然后再需要使用校验的地方要
<ValidationObserver ref="form">
<van-cell-group>
<!--用户名-->
<ValidationProvider rules="required" name="用户名" v-slot="{errors}">
<van-field
v-model="userInfoEdite.userName"
required
clearable
label="用户名"
right-icon="question-o"
placeholder="请输入用户名"
:error-message="errors[0]"
/>
</ValidationProvider>
<!--身份证号-->
<ValidationProvider name="身份证号" rules="required|idCard" v-slot="{errors}">
<van-field
v-model="userInfoEdite.identityCard"
label="身份证号"
placeholder="身份证号"
required
:error-message="errors[0]"
/>
</ValidationProvider>
</van-cell-group>
</ValidationObserver>
然后就是vue的语法,this.$refs.form.validate()这是一个promise,你可以写箭头函数来拿到校验以后的结果,返回boolean值。
3 解决输入框问题
在ios里面键盘是可以自动滑动,这样保证输入框始终在键盘上方,但是在Android就不行,把整个样式都搞乱。问我同学他们公司怎么搞得,然后因为他们使用的是jq,所以方式放在这里肯定是不行了,在网上看到有人加了一段代码,我把它封装成一个包,然后引入这个包就可以了
export default function inputUp() {
//安卓机型,自动上滑露出输入框
if(/Android/.test(navigator.appVersion)) {
window.addEventListener("resize", function() {
if(document.activeElement.tagName=="INPUT" || document.activeElement.tagName=="TEXTAREA") {
document.activeElement.scrollIntoView();
}
})
}
}
4 在ios版本中的微信中url总是显示第一次的值
一开始使用vue-router的hash 模式,觉得是不是hash模式微信浏览器获取不到#后面的值,所以修改成history模式,调试发现还是显示的是www.xxx.com,因为要监听路由的变化我去同步底部导航的状态,加上我的路由表设计的有点问题,导致我的tab不能正常切换。以为是vant的tab组件的问题,问了问别人,说确实回失效,换成原生就好了,所以我用原生写了,但还是切换失效,所以我去找路由表,觉得嵌套的有问题,所以这个看自己的路由表和路由挂载的地方,那有什么办法解决这个url不变呢,有一个很简单的办法就是刷新一次页面,但是不能使用this.$router.go(0);这样会一直刷新页面,无限刷新,然后我又强制刷新路由。这个bug一直没解决,所以没办法我只能去掉这个tab切换。
5 滚动问题
这个滚动问题,只会出现在safari与微信浏览器中,一个是首次加载页面会出现划不动的现象,网上有说加一个样式,说的是解决ios滑动会出现卡顿的现象,但是没有解决,我以为是vant的问题,我换成mui的loadeMore还是会出现这个问题,可这个在chrome和Android 里面完全是好使的哇,心态要崩溃了,没办法,只能去网上找了一个插件,但是这个插件上拉完成以后,会让元素跑到最上面隐藏一部分,但是通过ios自带的下拉反弹能够看到,这个问题去掉插件就是好的,和客户商量了一下,暂时先这样用。
2019/11/18(更新,滚动问题)
在查了几天的资料后,我觉得应该是这样的:我的页面结构
<div class="searchResult" :style="{height:hei + 'px'}">
<div class="van-list-wrap">
<mt-loadmore :bottom-method="onLoad" :bottom-all-loaded="allLoaded" :auto-fill="false" ref="loadmore"
@bottom-status-change="handleBottomChange">
<div class="item" v-for="(item,index) in dataList" :key="index">
<div class="name" @click.once="getRecordDetails(item.examinationRecordId)">
<div class="itemList">
<p><span>姓名:</span>{{item}}</p>
<p><span>日期:</span>{{item}}</p>
<p><span>项目:</span>{{item}}</p>
</div>
</div>
<p v-if="item.fileName">{{item}}
<van-button plain type="info" @click="pdfPreview(item.accessUrl)">查看附件
</van-button>
</p>
<div class="onePx"></div>
</div>
<div slot="bottom" class="mint-loadmore-bottom">
<span v-show="bottomStatus !== 'loading'" :class="{ 'rotate': bottomStatus === 'drop' }">↓</span>
<span v-show="bottomStatus === 'loading'">Loading...</span>
</div>
</mt-loadmore>
</div>
<van-loading type="spinner" color="#fff"/>
</div>
基本上的结构是子元素无限高度,父元素固定高度,并设置overflow:scroll,我的bug是首次加载会滚动,当路由跳转到其他页面,然后再回到这个路由页面滚动就失效了。我查了一下,路由复用的时候,不会重新加载页面,也就是说我的数据还没返回,他又不重新渲染,导致我子元素的高度为0。这也就是网上说的overflow:scroll在ios中失效的原因。解决的办法:第一个就是刷新一次页面,重新渲染,这个在我使用的场景上还可以,所以就使用这个。第二个就是给子元素设置一个min-height;style="height: calc(100%+.5rem)"
6 打生产包放在nginx里面会出现404以及使用history页面刷新一次会报404,开发环境刷新报404
我在开发的时候一共会出现这三种情况。第一种的出现的原因是因为assetsPublicPath我是用的绝对路径,这样肯定是不行的,所以改成“./”.第二种vue-router上也说了,使用history会出现重定向,在host路径是找不到资源的,所以才会报404,解决办法就是在nginx中加上一段配置
try_files $uri $uri/ /index.html;
这样就重定向到首页,让在首页这个位置去匹配路径。开发环境刷新报404,是因为springboot加filter把路径拦截掉了,所以我改了一个路径名,结果刷新就不再报404了。