vue spa 微信公众项目开发与填坑之旅
Base
vue-cli3.0
注入插件
1. vuex=>支持状态管理器
2.vuex-persistedstate=>支持数据状态持久化
3.vue-router=>支持路由跳转管理
4.vue-meta =>支持SPA下单独设置页面title以及元信息
5.axios => 支持ajax数据请求和数据劫持
6.js-base64 => js转base64
7.vue-cookies => js存cookie
8.vConsole =>手机端调式
9.weixin-js-sdk => 微信公众号sdk
10.qs => 将对象 序列化成URL的形式
UI库
Cube-ui
移动端项目css 单位使用
rem转换方法:
html {
font-size: 50px
}
body {
font-size: 24px
}
@media
screen and (min-width:320px) {
html {
font-size: 21.33px
}
body {
font-size: 12px
}
}
@media
screen and (min-width:360px) {
html {
font-size: 24px
}
body {
font-size: 12px
}
}
@media
screen and (min-width:375px) {
html {
font-size: 25px
}
body {
font-size: 12px
}
}
@media
screen and (min-width:384px) {
html {
font-size: 25.6px
}
body {
font-size: 14px
}
}
@media
screen and (min-width:400px) {
html {
font-size: 26.67px
}
body {
font-size: 14px
}
}
@media
screen and (min-width:414px) {
html {
font-size: 27.6px
}
body {
font-size: 14px
}
}
@media
screen and (min-width:424px) {
html {
font-size: 28.27px
}
body {
font-size: 14px
}
}
@media
screen and (min-width:480px) {
html {
font-size: 32px
}
body {
font-size: 15.36px
}
}
@media
screen and (min-width:540px) {
html {
font-size: 36px
}
body {
font-size: 17.28px
}
}
@media
screen and (min-width:720px) {
html {
font-size: 48px
}
body {
font-size: 23.04px
}
}
@media
screen and (min-width:750px) {
html {
font-size: 50px
}
body {
font-size: 24px
}
}
body {
min-width: 320px;
font-family:
Arial,Helvetica,STHeiTi,sans-serif;
background: #ffffff;
}
#app {
font-family:
'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align:
center;
color:
#2c3e50;
margin-top:
60px;
width: 15rem;
margin: 0
auto;
line-height:1.1;
}
换率是:50 项目的设计稿的尺寸为750
750 (px) /50 = 15rem 1px= 0.02rem
Vue Spa 页面的登录
Main.js
router.beforeEach((to, from, next) => {
//不需要登录的页面
if (to.path == store.state.no_login.index ||
to.path== store.state.no_login.shouye ||
to.path== store.state.no_login.selectadress ||
to.path ==store.state.no_login.shopdetails ||
to.path== store.state.no_login.successpm ||
to.path== store.state.no_login.dynamic
) {
next();
returnfalse
}
//防止用户授权之后点击返回
if(to.path=== '/author' && store.state.userInfo.nickname){
next('/');
returnfalse;
}
//没登录,没用户信息都需要跳转中间件页面
if(!store.state.userInfo.nickname && to.path != '/author'){
store.state.toUrl = to.fullPath;
next('/author');
//return false;
}
if(store.state.userInfo.nickname) {
next();
returnfalse
}
next();
});
Vue spa 微信公众号的
分享
Main.js
import wx from 'weixin-js-sdk';
router.afterEach((to, from) => {
let _url =window.location.origin+"/shop"+ to.fullPath;
//非ios设备,切换路由时候进行重新签名
if(window.__wxjs_is_wkwebview !== true) {
axios.post('/wechat_config',qs.stringify({uri:_url})).then(function (res) {
//注入配置
wx.config({
debug:false,
appId:res.data.data.item.appId,
timestamp: res.data.data.item.timestamp,
nonceStr: res.data.data.item.nonceStr,
signature: res.data.data.item.signature,
jsApiList:["updateAppMessageShareData",'updateTimelineShareData','getLocation',"onMenuShareAppMessage","onMenuShareTimeline","onMenuShareWeibo"]
})
})
}
// ios设备进入页面则进行js-sdk签名
if(window.__wxjs_is_wkwebview === true) {
axios.post(' /wechat_config',qs.stringify({uri:_url})).then(function(res) {
wx.config({
debug:false,
appId:res.data.data.item.appId,
timestamp: res.data.data.item.timestamp,
nonceStr: res.data.data.item.nonceStr,
signature: res.data.data.item.signature,
jsApiList:['updateAppMessageShareData','updateTimelineShareData','getLocation',"onMenuShareAppMessage","onMenuShareTimeline","onMenuShareWeibo"]
})
})
}
let totitle ="";
let todesc ="";
// to.meta. share 是自定义路由的分享信息
//还可以在router meta自定义更多参数
if(typeof(to.meta.share) === "undefined"){
totitle ="我是没有分享自定义的标题";
todesc ="我是没有分享的分享详情";
}else{
totitle =to.meta. share.title;
todesc =to.meta. share.desc;
}
let share = {
title:totitle, //分享标题
desc:todesc, //分享描述
link:_url, //分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: '',//分享图标正式
success:function () {
//设置成功
}
}
//微信分享配置
wx.ready(function () {
wx.updateAppMessageShareData(share);
wx.updateTimelineShareData(share);
wx.onMenuShareAppMessage(share);
wx.onMenuShareTimeline(share);
wx.onMenuShareWeibo(share);
})
})
值得注意的是微信1.4版本分享给朋友的最新接口就算在客户端6.7.2版本也是会出现没有图片的问题所以还是将老的版本也写进去兼容一下
Vue 转换时间戳
Util.js
export function formatDate (date, fmt) {
if(/(y+)/.test(fmt)) {
fmt =fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}
let o = {
'M+':date.getMonth() + 1,
'd+':date.getDate(),
'h+':date.getHours(),
'm+':date.getMinutes(),
's+':date.getSeconds()
};
for (let kin o) {
if (newRegExp(`(${k})`).test(fmt)) {
letstr = o[k] + '';
fmt= fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
}
}
return fmt;
};
function padLeftZero (str) {
return ('00'+ str).substr(str.length);
};
需要转换的页面引用
import {formatDate} from '@/util.js';
filters: {
formatDate(time) {
vardate = new Date(time);
return formatDate(date, 'yyyy-MM-dd hh:mm');
}
}
使用:
{{ _time*1000 | formatDate}}
vue防止用户疯狂点击和加载
Util.js
/**
*函数防抖 (只执行最后一次点击)
* @param fn
* @param delay
* @returns{Function}
* @constructor
*/
export const Debounce = (fn, t) => {
let delay =t || 500;
let timer;
returnfunction () {
let args= arguments;
if(timer){
clearTimeout(timer);
}
timer =setTimeout(() => {
timer = null;
fn.apply(this, args);
},delay);
}
};
/**
*函数节流
* @param fn
* @paraminterval
* @returns{Function}
* @constructor
*/
export const Throttle = (fn, t) => {
let last;
let timer;
let interval= t || 500;
returnfunction () {
let args= arguments;
let now= +new Date();
if (last&& now - last < interval) {
clearTimeout(timer);
timer = setTimeout(() => {
last = now;
fn.apply(this, args);
},interval);
} else {
last= now;
fn.apply(this, args);
}
}
};
vue 朋友圈的天数计算
util.js
caculate_time(created_at){
letnow_time = new Date().getTime();
letold_time = parseInt(created_at) * 1000;
lettime = now_time - old_time;
let day = parseInt(time / (24 * 60 * 60));//计算整数天数
//计算出相差天数
day=Math.floor(time/(24*3600*1000))
//计算出小时数
letleave1=time%(24*3600*1000) //计算天数后剩余的毫秒数
lethours=Math.floor(leave1/(3600*1000))
//计算相差分钟数
letleave2=leave1%(3600*1000) //计算小时数后剩余的毫秒数
letminutes=Math.floor(leave2/(60*1000))
//计算相差秒数
letleave3=leave2%(60*1000) //计算分钟数后剩余的毫秒数
letseconds=Math.round(leave3/1000)
return[day,hours,minutes,seconds];
}
使用:
let ts_time = that.caculate_time(val.created_at);
let msg = '';
if(ts_time[0] != 0){
msg =ts_time[0]+'天前';
}else if(ts_time[1]!= 0){
msg =ts_time[1]+'小时前';
}else if(ts_time[2]!= 0){
msg =ts_time[2]+'分钟前';
}else if(ts_time[3]!= 0){
msg = '刚刚';
}
Vue spa 用Cube-ui库遇到的问题1
Cube-ui里面的左右滑动Scroll组件出现滑不懂的情况一定要看.cube-scroll-content是否重定义了display,而且必须是在<style
lang="stylus" rel="stylesheet/stylus">下面不然会不生效
.cube-scroll-content
display: inline-block
Vue spa 用Cube-ui库遇到的问题2
Scroll上拉加载和下拉刷新都必须要设置高度
//获取减去底部导航栏的高度
let getWindowHeight = (document.documentElement.clientHeight ||document.body.clientHeight) - this.$refs.bottom_h.offsetHeight;
this.getWindowHeight = getWindowHeight;
<!-- 获取foot的高度-->
Vue exclude设置不缓存页面没用的问题
exclude设置对应组件的name,是组件的name,是组件的name,大部分人都认为是路由里面的name
该文章是我在做vue spa项目的时候遇到的一些问题,特地在此记录一下。也希望能帮助到大家
作者:古城老巷_li
链接:https://www.jianshu.com/p/d012b8ef4179
來源:简书
简书著作权归作者所有,转自:https://www.jianshu.com/p/d012b8ef4179。