前言

博主也是vuejs萌新,公司仅我一个前端,收到做h5的需求后,马上想到要用下vuejs,于是说服领导,开始慢慢钻研,现在记录一下踩到的坑。这些坑主要是在一些组件的使用上,其它的只要好好看官方文档就好了,vue,vue-router, vuex的文档相当重要。

欢迎体验提bug 墨瞳漫画 m.cm233.com

vue-router

router这里踩的坑主要是组件的重用。构建单页面大型应用的话,肯定要开启组件的缓存的,因为一般会要求后退的时候不要重新加载页面,而且要记住原始的滚动位置。
首先,引入router-view的地方要加上keep-alive

<router-view keep-alive></router-view>

然后开启html5 history模式,并开启位置纪录

const router = new Router({history: true, // use history=false when testingsaveScrollPosition: true
})

开启keep-alive以后,当要求一个组件的内容发生变化时,比如 漫画详情页面是一个路由带参数的组件,当参数变化时,router会重用这个组件,而不是重新请求数据,这显然是不符合要求的,所以正确的姿势是:
首先,用一个字段保存这个路由参数,
用router的钩子函数data获取路由变化参数,保存到字段里


route:{data: function(transition){this.bookId = transition.to.params.id;}
}

写一个watcher来拉取数据并填充模版,因为在data钩子函数中,我们已经修改了相应字段,所以当路由参数更改时会直接触发这个watcher

watch: {'bookId' : function(val){//do something}
}

如果是多个参数的,可以把这些参数放到一个对象里,watcher采用深监测

route:{data: function(transition){this.watcher.type = transition.to.params.type;this.watcher.id = transition.to.query.id;}
},
watch : {'watcher' : {handler: function(val){//do somethingwindow.scrollTo(0,0);// 不使用缓存时,不使用记录好的用户位置,滑倒顶部},deep: true}
}

一开始没有用这种方法出了很多的bug,改了以后,路由和缓存方面的逻辑瞬间就变得清晰了,组件的切换也更加流畅了。
第二个坑就是关于缓存页面浏览位置的纪录,router是通过html5 history的pushState来纪录当前滚动位置的,切换路由的时候,把当前位置push进去,用户后退时,会触发onpopstate事件,这个时候再把位置取出来并滚动到指定位置,但是!某些浏览器本身也设置了一些奇怪的位置滚动,vue-router的滚动就失效了,所以需要延迟执行一下

   window.addEventListener("popstate",function(e){setTimeout(()=>{window.scrollTo(0,e.state.pos.y);//通过打log,发现了位置纪录在这个变量里了},300)},false);

然而,浏览器只能记录一个位置,所以会有这样的情况: 从m.cm233.com 到 m.cm233.com/book,再返回到m.cm233.com,这时浏览器跳到了当时记录的位置,但是再前进到/book时,浏览器还是会停在首页的那个位置上,这个bug暂时还没有解决,好在用户场景不是很多。所以告诉我们,子页面路由参数变化的时候,要把滚动条人工弄到最上面,要不然就会滚动到入口页面的浏览位置。也就是watcher里还要加一句如上的滚动。

页面标题也是要手动更改的,所以每个页面要放一个专门的title变量存一下,然后在data钩子函数(用于组件缓存时) 和 路由参数的watcher(用于组件更新时) 里 都改变title

route:{data: function(transition){this.title = 'hiahia';document.title = this.title;}
},
watch : {'id' : function(val){this.title = 'hiahia';document.title = this.title;}
}

通常页面的标题不是固定的,用变量存储title,主要是为了记住上一次组件被用的时候的title,以便于重用的时候更换。

然而,ios微信不会监测document.title的变化,所以要写一个专门针对它的hack,通过创建iframe

//全局函数
window.isWeiXin = function(){var ua = window.navigator.userAgent.toLowerCase();if(ua.match(/MicroMessenger/i) == 'micromessenger'){return true;}else{return false;}
}window.weiXinChange = function(title){if(window.isWeiXin()){document.title = title;var iframe = document.createElement('iframe');iframe.src = './favicon.ico';iframe.style.display = 'none';iframe.onload = function(){setTimeout(function() {document.body.removeChild(iframe);}, 0);}document.body.appendChild(iframe);}
}//组件中route:{data: function(transition){this.title = '墨瞳漫画';document.title = this.title;window.weiXinChange(this.title);}
},
watch : {'id' : function(val){this.title = '墨瞳漫画';document.title = this.title;window.weiXinChange(this.title);}
}

vue-infinite-scroll (directive)

(为什么不自己写!)

组件地址 https://github.com/ElemeFE/vue-infinite-scroll 饿了么出品

使用方法
main.js

import Scroll from 'vue-infinite-scroll'
Vue.use(Scroll)

组件中

  <dl v-infinite-scroll="loadMore()" infinite-scroll-disabled="busy" infinite-scroll-distance="7"><template v-for="item in list"><dd class="page-item"></dd></template></dl>

其中busy这个变量比较重要,他控制着这个指令是否继续执行,当没有下一页数据的时候,应该把busy置为true来关闭滚动加载。正在读取下一页数据时,要先把busy置为true,数据返回时在置为false

loadmore(){this.busy = true;someApi.someFunction().then((data) => {this.busy = false;})
}

但是这个组件在路由切换的时候会出问题,routerView被移除时,组件会触发加载(大概是因为页面高度突然塌陷),而且会一直加载到我们自己设置的停止条件(busy=true)。所以离开页面的时候,需要在路由的deactivate钩子函数里把滚动关掉,再次进入页面的时候再开启(路由无变化在data钩子函数里开启,有变化的话在watcher里开启,如果不需要在路由改变时向子组件延时传递参数也可以都在data钩子函数里开启)

route:{deactivate: function(transition){this.busy = true;transition.next();},data: function(transition){if(){this.busy = false;}//这里输入组件路由参数没有变化的条件}
}

lazyload

(为什么不自己写!)
网上找了几个lazyload的组件,都不太好使,就自己改了一个,是改了一个,原组件叫vue-lazyload, 毛病还挺多的,写这个组件的人估计没有真正在大项目中用过就匆匆发布在npm了,es6版本也写的不伦不类的 - -,不过还是很厉害,自己写的话毛病肯定会更多。我改后的放在https://github.com/Ganother/blog/blob/master/lazyload.js了,是个较为稳定的版本。其中过渡动画写在img-loaded这个class里

/*简单的透明度渐入,图片加载完成后会删掉这个class,以防router切换缓存页面时再次引起动画*/
.img-loaded {animation: loaded .2s ease-in-out;}@keyframes loaded {0%{opacity: 0;}100%{opacity: 1;}}
let loadingJpg = require('assets/loading.jpg');//这里引入一张loading图,会被转成base64
Vue.use(VueLazyload, {preLoad: 1.3, //图片顶端距窗口顶端1.3个屏幕高度时开始加载loading: loadingJpg,error: loadingJpg
})

自适应的图片:如果服务端传过来的图片带了宽高信息,可以在img外层包一个class为img-bar的元素,图片过来的时候先设置一个min-height为响应高,组件在图片加载后会自动取掉这个min-height。这样可以防止loading图和图片大小不一样引起的页面跳动继而导致的加载图片时机错误。

vue-resource

跨域时,会先发送一个空的options请求来查看接口是不是支持跨域,再发送一次真实请求。还不是很了解这种方式的好处,当接口较多时,请求数量多了一倍也是有点尴尬的,所以要设置一下。而且如果接口每次都打印空参数的log的话。。。嗯。

Vue.http.options.emulateJSON = true;
Vue.http.options.headers={'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'
};

结构目录

vue-cli直接构建的,src里的目录如下

api 放一些ajax请求接口的函数
assets 放一些静态资源,图片,公共sass
directives 放一些指令js,比如改动后的lazyload
pages 页面入口组件,用在router中
components 小组件们
vuex vuex
app.vue
main.js

另外,可以修改下生成的静态文件,vue-cli默认声称的静态文件时间戳是加在文件名上的,如app.fefdfd7s8f78sd7.js,这样版本迭代很快后会使服务器上积压过多无用文件,我们希望这样加时间戳 app.js?t=32j32ih4u32h 所以改一下webpack.prod.conf.js就好了,如下

  output: {path: config.build.assetsRoot,filename: utils.assetsPath('js/[name].js?t=[chunkhash]'),chunkFilename: utils.assetsPath('js/[id].js')}new ExtractTextPlugin(utils.assetsPath('css/[name].css?t=[contenthash]')),

墨瞳漫画h5一期 vuejs总结相关推荐

  1. 墨瞳漫画 升级vue2 踩坑

    概述 升级的话呢,还是比较简单,就按官方文档来,改写一下某些api,本文主要讲文档中说的不清晰的一些坑 vue-router 官方文档中推荐使用watcher来监测$route的改变,当路由变化时就去 ...

  2. VUE常用问题hack修改

    vue-router router这里踩的坑主要是组件的重用.构建单页面大型应用的话,肯定要开启组件的缓存的,因为一般会要求后退的时候不要重新加载页面,而且要记住原始的滚动位置. 首先,引入route ...

  3. 用Paint Tool SAI绘制漫画

    漫画绘图软件 Paint Tool SAI是一个来自日本的小巧的漫画辅助绘图软件,只有11M大小. 这个没有任何现成的模板和组件,只能自己一笔一笔的话,画笔.图层等功能与Photoshop类似,但没有 ...

  4. 漫画 | 外行对程序员误会有多深!

    程序员如今已经发展成社会的主流职业,以至于街头的王大妈李大爷都能说出一二来,据说他们认为的程序员是这样子的: 1.程序员都是秃头,秃的越狠越是高级. 2.程序员各个都是死宅男,整天在家玩电脑. 3.甚 ...

  5. 关于中秋节的网页html5,中秋节H5案例合集:freestyle、快闪以及一镜到底

    原标题:中秋节H5案例合集:freestyle.快闪以及一镜到底 这次的中秋节营销怎么玩?天猫.腾讯和故宫食品已经给出了他们的答案,我们一起来看看有木有可以借鉴的. 一.天猫:外星人入侵地球竟是为了- ...

  6. H5简约大气企业官网

    编号:H5-005-minimaxing预览-简约高大上企业官网 今天给大家分享一个简约大气的企业官网 主色调:蓝,浅绿 H5-005-minimaxing预览-简约高大上企业官网 如果需要的朋友,可 ...

  7. 集合之Map家族的TreeMap + Sort +Properties及Collections工具类和总结

    集合之Map家族的TreeMap + Sort +Properties及Collections工具类和总结 一.TreeMap 1.TreeMap的使用 import java.util.Arrays ...

  8. 集合之比较接口器+Map家族的HashMap+LinkedHashMap+Hashtable+ConcurrentHashMap

    集合之比较接口器+Map家族的HashMap+LinkedHashMap+Hashtable+ConcurrentHashMap 一.比较器接口 1.内置比较器 – Comparable import ...

  9. php-resque消息队列

    参考:http://www.thinkphp.cn/extend/888.html tp3.2集成php-resque消息队列 推送,发送短信等第三方库,找到以下几种方案: 1)PHP+redis自己 ...

最新文章

  1. 插入排序算法(基于Java实现)
  2. 不是说一个源程序中只能有一个public类?怎么内部类可以用public?
  3. vs与qt版本对应关系
  4. Python中的遇到的错误(持续更新)
  5. 剑指offer(12)数值的整数次方
  6. Anaconda安装tensorflow遇到的wrapt、load error、Twisted问题
  7. 前锋php人工智能_人工智能除了学习php,还应该学什么?
  8. 微信宣布将推出自有输入法后,搜狗快马加鞭赶来泼冷水......
  9. 【es】ClassNotFoundException: org.elasticsearch.plugins.ExtendedPluginsClassLoader
  10. LTR学习排序 Learning to Rank 小结
  11. OpenCV:使用python-cv2实现Harr+Adaboost人脸识别
  12. echarts x轴文字个数太多_echartsX轴文本数据太长溢出问题
  13. 8051蜂鸣器程序c语言,蜂鸣器报警声C51程序
  14. java 中super_Java中的super
  15. 使用Windows系统的几个好的习惯
  16. mysql表删除后恢复
  17. C++实验5 游戏玩家类Player、两个道具类Helm和Armor
  18. 你好,C++(22) 排排坐,吃果果——4.3.3 for循环:某个范围内…每个都…
  19. App 用户新体验——Agora Native SDK 3.4.0
  20. MYSQL8.0修改密码(仅限于修改密码)

热门文章

  1. 如何借助“AI+边缘计算”助推能源产业智能化转型?这场直播给你答案 | 量子位·视点...
  2. NLP玩得溜,「兵器」得趁手:GLUE排行第一的那种,了解下?
  3. MIT新研究给量子计算机「泼冷水」:自然界辐射会干扰它,需要研究新对策 | Nature...
  4. 我一个普通程序员,光靠GitHub打赏就年入70万,要不你也试试
  5. 苹果2项最新专利曝光无人车路线:闭门造车、传感器先行,关注驾乘体验
  6. mormot支持websocket
  7. 2018-11-05直播
  8. Android程序员的技术要求和学习路线
  9. openssl 创建私有CA
  10. 是时候对XSLT说“Goodbye”了吗?