记 vue 移动端开发 中的经验
栏目: JavaScript · 发布时间: 5年前
内容简介:手上的 vue移动端 项目已经开发了大几个月了,遇到了一些很有意思的坑,也让自己学习了很多;写此文主要目的是记下一些我遇到的坑,以及自己的解决方案,分享的同时也方便以后复习。项目的底层是上司通过 Cordova 等常用的 hybird app工具打包出来的。然后通过 webview 打开我的vue项目。所以严格意义上说,我还是在做单页面应用。 hybird app 的底层会提供一些api 给我调用,方便我关闭打开webview,或者跳转到不同子页面。hybird app会集成不同的业务。这些业务有hybir
项目背景
手上的 vue移动端 项目已经开发了大几个月了,遇到了一些很有意思的坑,也让自己学习了很多;写此文主要目的是记下一些我遇到的坑,以及自己的解决方案,分享的同时也方便以后复习。
项目的底层是上司通过 Cordova 等常用的 hybird app工具打包出来的。然后通过 webview 打开我的vue项目。所以严格意义上说,我还是在做单页面应用。 hybird app 的底层会提供一些api 给我调用,方便我关闭打开webview,或者跳转到不同子页面。hybird app会集成不同的业务。这些业务有hybird app本事的服务,也有像我这种,完全来自其服务的页面。这些就是项目大概的背景。
上中下三部分的定位问题。
这个问题我在文章 中已经详细说过。
rem 的使用;
我直接在 app.vue 中添加以下方法,运行后,你会在html 标签中看到 fontsize 设置为了50px; 表示 1rem = 50px;
created() { this.resize(document, window); }, methods:{ /*设置rem参照单位。width:1rem = 50px 所以设计稿宽 375px == 375/50 = 7.5rem * 由于页面中有些元素用了绝对定位。特别是top,bottom。由于设备不同,计算出的rem不同, * 导致定位覆盖。所以,建议涉及高度的 统一用 px 做单位,包括padding-top,bottom等。 * 因为高度存在滚动条,不存在适配问题。主要针对宽度做适配。 * * */ resize(doc, win) { var docE1 = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', recalc = function () { var clientWidth = docE1.clientWidth; if (!clientWidth) return; //docE1.style.fontSize = clientWidth / 375 + 'px'; 这里希望设置 1rem = 1px,实验证明,这样做 会导致 html 的 fontsize小于 12px docE1.style.fontSize = (clientWidth / (375*2)) * 100 + 'px'; //乘以100的意义是,1为了不受fontsize小于12的影响,2为了计算方便; }; if (!doc.addEventListener) return; win.addEventListener(resizeEvt, recalc, false); doc.addEventListener('DOMContentLoaded', recalc, false); }, }
使用建议:
1,少量大小的定义尽量使用px,因为对自适应效果影响不大。例如某个div的padding,设置为5px 10px,影响是不大的。
2,宽度上的定义尽量使用rem 作为单位,因为移动设备对宽度敏感,可谓寸金寸土。设置了以上代码后,可以通过设计稿尺寸/50 得到rem单位的数值。 例如 padding:10px; 可以写成 padding: 10px 0.2rem; 或者 padding:0.2rem;
3,高度上的定义,尽量使用px;因为本项目可以滚动内容页,所以高度是不敏感的。设置为px 的原因是,后面定位 loadermore 组件会有帮助。当然,如果你对计算很有把握,或者页面内容不允许滚动,也可以使用 rem;
刷新某个子页面
遇到一个填写表单点保存形成草稿模式的需求。要求在url中加入参数 id;刷新本页面,重新通过id获取数据回填。 vue 是单页面应用,肯定不能全局刷新。
同事的解决方案
调用保存接口,获取到id后, 通过
this.router.push(this.$route.path + "&id=" + id);//加参数本页并不会刷新
改变url ,然后重新申请 调用接口,拿到最新的数据,回填回去。
这样做,理论上是行得通的。当时很危险,因为用户操作页面,会改变很多变量。如果回填数据后,由于没有经历完整的created等生命周期,这些变量还是原来状态,容易出bug;
其次,如果像本项目那样,需要支持 hybird app 通过url+id 的方式直接去到草稿的话,代码不好维护。所以,最理想的做法,就是真实的重新
load 一次这个子页面。
正确做法
利用vue 的provide / inject api
* app.vue 中定义 <router-view v-if="isRouterAlive"/> data() { return { isRouterAlive: true, } }, provide() { return { reload: this.reload, } }, methods: { reload() { this.isRouterAlive = false this.$nextTick(() => (this.isRouterAlive = true)) }, } * 需要刷新的子页面 inject: ['reload'], //需要调用的地方 let path = this.$route.path+"?id="+id this.$router.replace(path); this.reload();
keep-alive 页面怎么刷新
这个需求很常见,有个列表页面,点击某一条去到详情页面,点击返回,列表页面保持状态不变,滚动条保持原来位置。如果,详情对数据做了改变,点击返回,列表页面才刷新。
* app.vue 中 <div id="app"> <keep-alive> <router-view v-if="isRouterAlive&&$route.meta.keepAlive"/> </keep-alive> <router-view v-if="isRouterAlive&&!$route.meta.keepAlive"/> </div> * route.js 中 { path: 'a',//我的草稿 name: 'myDraft', meta:{ keepAlive:true, }, component: resolve => require(['page/myDraft'],resolve) },
这样,定义了meta keepAlive 为true 的页面就会被 缓存。数据不变的情况下,点击返回, 只要把滚动条位置设置到原来离开哪里就好了。
但是问题来了,1,从首页进入 keepAlive 页面,每次都要刷新,二,详情页如果改变了数据,返回后也要刷新 页面。
这里我主要通过 eventBus 来解决了组件通知 页面 刷新的问题。
细节可以看我的笔记,最好的实践应该是最后提到大神的链接文章。
不同页面跳转到同一个页面,topBar 点击返回,回到各个出发位置。
* topBar.vue 组件的封装并不难,就是预留自定cancel函数,不然就调用 app.vue 中的 backHome 函数 对返回做统一处理 inject:['backHome'], cancel(){ if(this.popup){ this.$emit('cancel') }else{ this.backHome(); } }, * app.vue provide() { return { backHome:this.backHome } }, backHome(){ //返回或退出webview let isOutsidePage = this.$route.params.inside; let from = this.$route.params.from; if(isOutsidePage=='in'){ //内页跳转 if(from=="CC"){ //回到a中心 this.$router.replace('/controlCenter') }else if(from=="SF"){ //回到b中心 this.$router.replace('/controlCenter2') }else { //回到原来的子页面(从a页到b页前,必须要先保存lastFullPath) this.$router.replace(this.$store.getters.lastFullPath) this.$store.commit('setLastFullPath',"")//置空旧路径 } }else{//关闭webView closeWebView(); } } * router.js { path: '/myDraft/:from/:inside', name: 'myDraft', component: resolve => require(['page/myDraft'],resolve) }, { path: '/myDraft', redirect: 'myDraft/ll/out', },
通过上面的定义 //hybrid app 只需要调用 ip:xxxx/myDraft 就能打开这个页面,并且返回键自动关闭webview;
通过 CC CF 等标志字符 可以判断来自哪个 中心的。
最后来到重点的 子页跳子页返回 操作,主要就是需要借助vuex 保存旧 路径
a.vue 子页 //跳转前先把当前路径保存到全局vuex变量lastFullPath this.$store.commit('setLastFullPath',route.fullPath)//保存路由用于返回本页 this.$router.replace('/ ');//清空路由,不重置会导致url 混乱。 this.$router.replace(`b/`+route.name+`/in?id=`+id);
以上所述就是小编给大家介绍的《记 vue 移动端开发 中的经验》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- SaaS管理系统开发经验------Dva(Redux)实战经验分享
- 20年程序员分享经验:20条编程经验,一定要看完
- 购房经验谈(下)
- 几个elasticsearch使用经验
- 写书稿的经验
- FairyGUI使用经验分享
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。