用了vue2.0,vuex, vue-router等较新的技术,完成了城会玩这个项目,过程中发现自己许多不足,也得到很多人帮助,特别是有些困难的技术点。现在项目上线了,在此做一个整理和总结。
1.keep-alive的用法
<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和<transition>
相似,<keep-alive>
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。当组件在
<keep-alive>
内被切换,它的activated
和deactivated
这两个生命周期钩子函数将会被对应执行。主要用于保留组件状态或避免重新渲染
2.v-html的用法,v-html可以直接调用方法,可以实现和过滤器一样的效果,更灵活之处是可以传参。
<span class="time-left" v-html="buyLeftTime(el.buy_end_time, serverTime)"></span>
3.根据给定的某个时间点,计算距离此刻还剩多长时间的计算方法
Vue.filter('timeLeftFilter', function(time, serverTime) { var date = moment.unix(time); var difMin = date.diff(moment(serverTime), 'minutes'); if (difMin > 24*60) { return '报名:剩' + date.diff(moment(serverTime), 'days') + '天'; } else if (difMin > 60) { return '报名:剩' + date.diff(moment(serverTime), 'hours') + '小时'; } else if (difMin > 1) { return '报名:剩' + difMin + '分钟'; } else { return '报名已截止' } });
用moment.js这个库,serverTime为获取服务器的时间。
4.Vuex的用法,可以简单许多:(比如upCityName)
// 初始化状态管理模式 var store = new Vuex.Store({ state: { left_time: '' ,// 报名剩余时间 person_data: {} , // 个人主页数据 share_data: {}, // 分享数据 tag_index: '0', // 分类标签的选中状态 cate_id: '', //分类ID city_code: '', //当前选中城市 city_name: '', }, mutations: { upTagIndex: function(state, payload) { state.tag_index = payload; }, upLeftTime: function(state, payload) { state.left_time = payload; }, upPersonData: function(state, payload) { state.person_data = payload; }, upCateId: function(state, payload) { state.cate_id = payload; }, upCityCode: function(state, payload) { state.city_code = payload; }, upCityName: function(state, payload) { state.city_name = payload; } } })
5.定义变量时,注意,可以直接用data: {},接受接口返回来的数据,其它数据要处理时,用处理器处理,这样代码会比较好维护。
6.接口返回时,做相应的容错处理(包括接口很久不返回:断开网络的情况)这点是最基本的前端开发人员应该具备的,惭愧,自己没做好
7.虚拟键盘,fixed布局在移动端的问题
在android端
这个输入框会被遮住。
ios端表现得也不是很好,有时会悬空。
目前的处理办法是:最外层div用position: relative布局;里面的这个框用position: absolute布局。
<div class="say-something-wrap" @touchstart="start"> <div class="say-title">小伙伴说({{total_comment}})</div> <div class="say-item clear" v-for="el in comments"> <a class="say-user-pic"><img :src="el.avatar || 'image/avatar_default.png'"></a> <div class="say-user-info">{{el.nickname}}<span class="say-user-time">{{el.create_time|commentTimeFilter(serverTime)}}</span></div> <div class="say-content" v-html="el.content"></div> </div> <div v-show="comments.length == 0" class="empty-bus"> <p class="m-elephant box"> 暂无留言</p> </div> <div class="foot-tip" v-show="comments.length > 0"><span class="border-left"></span><span v-show="!nomore">下拉加载更多</span><span v-show="nomore">已经到底啦</span><span class="border-right"></span></div> </div> <div class="comment-create clear"> <input id="comment-create-input" type="text" contenteditable="value" v-model="comment_content" placeholder="我来说两句" maxlength="150" @focus="focus"/> <div class="m-square" @click="commentAdd()">发送</div> </div>
主要是@touchstart和@focus做了下处理
focus: function(e){ //iOS第三方软键盘顶不上去的问题 if($(e.target)[0] && $(e.target)[0].scrollIntoView){ $(e.target)[0].scrollIntoView(); setTimeout(function(){ $(e.target)[0].scrollIntoView(); },50) } }, start: function(){ $('#comment-create-input').blur(); },
8.广告轮播图问题
setTimeout(function(){ var elem = document.getElementById('bannerSwipe'); if(self.swipe){ self.swipe.kill(); } self.swipe = Swipe(elem, { startSlide: 0, auto: self.event.length <= 1? 0:5000, continuous: true, disableTouch: self.event.length <= 1, callback: function(index, elem) { // 因缓存循环广告时特殊处理 index = index % self.event.length; // 广告激活态 $('.m-swipe ul li').removeClass('m-swipe-active'); $('.m-swipe ul li:eq('+index+')').addClass('m-swipe-active'); } }); },0)
①最外层的setTimeout(function(){}, 0)是为了防止轮播图滚动时出现白屏现象,这代码看起来没什么用,不过加上这句就不会出现白屏现象,和swipe这个插件有关。
②disableTouch的设置是为了防止出现一张图的情况下,还能拖动的现象;配合这个参数的设置,需要
if(self.swipe){ self.swipe.kill(); }
因为disableTouch不会重置,加上上面的代码,就可以实现重置。
③ 轮播广告只有两张图的时候要做特殊处理 if(self.swipe && self.event.length==2)
// 初始化广告图片列表 ddb.get('party/get_party_ad', { activity_city: city_id }, function(d) { if (0 !== +d.ret) { alert(d.msg); return; } $(window).on('resize', function() { var ad = $(".m-swipe"); ad.height( ad.width() / 3); // 广告图片比例自适应 }).trigger('resize'); if(self.swipe && self.event.length==2){ $('.m-swipe-wrap div').eq(2).remove(); $('.m-swipe-wrap div').eq(2).remove(); } self.event = d.data.ad_list; self.mySwipe(); });
9.div 内容宽度过大,左右移动的实现
moveCate: function() { var mx = 0; var move_time = 0; // var move_distance = 1.44; var move_distance = 1.94; // var obj = document.getElementById("cate-tags"); // obj.addEventListener("touchstart",function(e) { // mx = e.touches[0].pageX; // }); // obj.addEventListener("touchend",function(e) { // var tag_length = $('.tag-name').length; // max_move_time = tag_length - 3; // var _x=e.changedTouches[0].pageX; // if($('.cate-log-wrap').width() >= 768) { // 屏幕宽度大于768,则没有左右移动操作 // return; // } // if(mx - _x > 10) { //右移动10个像素以上 // if(move_time + 1 > max_move_time) { // return; // } // move_time ++; // obj.style.marginLeft = -( move_distance * move_time) + 'rem'; // } else if(mx - _x < -10) { //左移动10个像素以上 // if(move_time - 1 < 0 ) { // return; // } // move_time --; // obj.style.marginLeft = -( move_distance * move_time) + 'rem'; // } else { // return; // } // }); },
不过后面没有用这个方法,直接让其宽度可以横向滚动就可以了^_^
---更新17-02-09---
广告图片自适应:
$(window).on('resize', function() { var ad = $(".m-swipe"); ad.height( ad.width() / 3); // 广告图片比例自适应 }).trigger('resize');