vue做混合式app_Vue+原生App混合开发手记#1

项目的大致需求就是做一个App,里面集成各种功能供用户使用,其中涉及到很多Vue的使用方法,单独总结太麻烦,所以通过这几篇笔记来梳理一下。原型图如下:

路由配置

主界面会用到一些原生App方法,比如验证用户身份等,故由原生App完成,进去的每个模块则全部都是HTML页面(有一种后端工作好轻松的感觉 ̄へ ̄)。由于传统的HTML页面开发起来效率太低,所以我选择了Vue来实现。每一个功能对应一个路由,比如电脑报修对应/repair,repair这个路由下的子页面都放进子路由里。

├─repair

│ apply.vue

│ index.vue

│ payment.vue

│ repairList.vue

└─teambuilding

apply.vue

index.vue

const router = newRouter({

mode:'history',

routes: [

path:'/repair',

component: repair,

children: [

{path:'apply', component: repairApply}, //电脑报修申请

{

path:':id',//报修单详情

component: repairDetail,

children: [

{name:'evaluate', path: 'evaluate', component: repairEvaluate}, //服务评价

{name: 'evaluatePay', path: 'pay', component: pay} //支付

]

}

]

]

})

为了减小打包时的体积,在加载组件的时候采用了以下形式:

const repair = resolve => import('views/repair/index').then(module =>resolve(module))

const repairApply= resolve => import('views/repair/apply').then(module =>resolve(module))

const repairDetail= resolve => import('views/repair/detail').then(module => resolve(module))

这是按照官方文档提供的路由懒加载技术写的,这样就能实现当路由被访问的时候才加载对应组件。以上是项目中关于路由的一些用法。

注册全局组件

接下来是全局组件的用法,比如头部,等待加载,弹出层之类的组件,几乎每个页面都有,全局注册能省去不少事。

import header from 'components/header/header'import loading from'components/loading/loading'Vue.component('v-header', header)

Vue.component('loading', loading)

之后在每个页面中敲入就能直接使用了,不用每次都去import。

处理返回键

还有一个比较常见的问题,由于Vue做出来的页面是一个SPA,在Android机中如果按下了物理返回键,整个应用都会退出,解决方法是重写物理返回键,这样就能按路由一级一级地返回了。因为主界面是由原生实现的,所以Vue只能返回到对应模块的首页,比如从 /repair/apply -> /repair -> null ,想要回到原生主界面,需要后端向前端注入一段脚本,在模块首页的后退按钮被点击时,执行一段方法告知Android调用自身的逻辑,然后Android关闭当前页面并回到主界面,例如:

//在main.js中加入该方法

window.AndroidMethod = function(msg) {if (window.android !== null && typeof(window.android) !== "undefined") {

window.android.callAndroid(msg);

}

}

在头部组件header.vue中,可以使用如下方式:

methods:{

goback() {

window.history.length> 1 ? this.$router.go(-1) : this.$router.push('/')

},

backToHomePage() {

AndroidMethod('backToHomePage')

}

}

这样可以将模块首页的返回和子路由的返回区分开来。

如果使用其他的打包工具,比如apiCloud或者HBuilder,它们都有各自的阻止物理返回按键的方法:

//apiCloud

api.addEventListener({

name:'keyback'},function(ret, err){

});

});//HBuilder

//https://blog.csdn.net/qq_25252769/article/details/76913083

document.addEventListener('plusready', function() {var webview =plus.webview.currentWebview();

plus.key.addEventListener('backbutton', function() {

webview.canBack(function(e) {if(e.canBack) {

webview.back();

}else{

webview.close();

}

})

});

});

同样的,把这些代码放在main.js中即可,打包后在真机里运行时会执行这些方法,普通环境是不存在这些变量的。

接收后端返回的数据

有时候,我们希望在Vue初始化时就能设置一些从服务器获取的常量,比如userID等,之后在各个组件中就能很方便地访问。设置全局变量很简单,直接挂载在Vue.prototype后面即可:

axios.get('http://localhost/index.php').then(res =>{

Vue.prototype.uid=res.data.uid

Vue.prototype.appid=res.data.appidnewVue({

el:'#app',

router,

store,

render: h=>h(App)

})

})

在组件中使用this.uid、this.appid就能访问到从服务器获取的常量了。如果是普通的js文件(比如api,utils等等),可以通过

import Vue from 'vue'Vue.prototype.uid

来访问。我们可能还希望这些数据在初始化时也能同时保存到Vuex中,先来看一下最初的Store/index.js文件:

import Vue from 'vue'import Vuex from'vuex'import* as actions from './actions'import* as getters from './getters'import state from'./state'import mutations from'./mutations'exportdefault newVuex.Store({

actions,

getters,

state,

mutations

})

但这样就没有往Vuex中存入数据的机会,这时就需要对Store文件夹中的index.js做一些小的封装,使其返回一个方法:

functionbuidler(data) {return newVuex.Store({

actions,

getters,

state: data,

mutations

})

}

exportdefault buidler

然后修改main.js中调用Vuex的方式,最初的代码如下:

import store from './store'

newVue({

el:'#app',

router,

store,

render: h=>h(App)

})

修改后的代码如下:

import store from './store'axios.get('http://localhost/index.php').then(res =>{

Vue.prototype.uid=res.data.uid

Vue.prototype.appid=res.data.appidnewVue({

el:'#app',

router,

store:store(res.data),

render: h=>h(App)

})

})

在组件的created方法中用MapGetters输出一下uid和appid,发现值可以被打印出来,说明这种实现方式是可以采用的。

更新:在后续的测试中,发现一些机型,特别是华为机(实测iOS没有此问题),对这种延后初始化Vue的方式兼容不好,表现在所有路由的切换动画全部失效,页面后退时会重新渲染页面(执行组件created方法中的内容),设置keep-alive也没有效果。不过水平有限,实在弄不懂为什么会这样。为了兼容,就不能采用上面的方式了。最后使用了在请求头中携带cookie的方式,具体为webview加载vue页面时,在requestURL中注入cookie,在cookie中设置需要传递的值,下面是用PHP模拟的一个小例子,PHP加载HTML页,并注入cookie,在HTML加载时取到cookie。

PHP:

HTML:

这样就能在main.js里同步拿到userID,Vue也不用延迟初始化了,Android机的表现效果和iOS一致。拿到userID后,可以保存到配置文件config中,在每个组件中访问config.uid就能拿到。

better-scroll

App中最常见的组件就是滚动数据列表,由此又很容易联想到better-scroll这个插件。better-scroll虽然好用,但如果使用不当还是会造成不小的麻烦,一些错误甚至无从排查。这里主要记录一下下拉刷新和上拉加载更多的实现。容器结构如下:

最外层的div限制滚动内容的位置,srcoll是官网提供的已经封装好的组件,里面正常置入ul>li形式的列表就行了,ul和li都不需要特殊的样式。由于官网提供的例子中整合了许多文件,查阅起来不是很方便,于是将其剥离出来,写了一个只有上拉加载和下拉刷新的Demo,方便以后使用。使用scroll时要慎用v-show指令,比如我希望使用下面的代码来控制没有数据时容器的显示与隐藏,由于数据是异步加载,刚开始时容器不显示直到数据加载好为止。

data() {return{

dataList: []

}

}

但这样会造成scroll组件内部高度计算错误(offsetHeight被计算成0,这是由于容器处于display:none状态),如果此时列表的数据没有达到滚动要求,上拉和下拉的提示文字会显示在列表下方,网速慢时也无法使用上拉下拉功能。解决方法是使用v-if指令,这样容器的min-height高度就能被正确计算了。

图片上传

另外一个功能是图片上传,这个功能并非由前端完成,而是和上面一样,通过后台返回的一段函数体拿到上传图片的路径并展示出来。

相册和拍摄都由后台调起,前端只需要进行简单的传值就行了:

AndroidMethod('photo')

AndroidMethod('video')

代码是和后端约定好的,所以不需要操心。真正需要关注的是从后台返回的图片上传路径,拿到这个路径后要在前台展示,并且保存时要带上一个或多个路径组成的字符串。

这个方法同样是和后台约定好的方法:

window.getUpload = function(path) {//这里要将path保存起来拿到组件里使用

}

这里就需要使用全局变量将path保存起来,假定这个全局变量叫做uploadImgUrl,初始化时是一个空数组,只有当用户从相册里选择图片上传后才将拿到的路径赋给这个全局变量。Vue组件中要监听这个全局变量的变化,就不能使用Vue.prototype.uploadImgUrl这种方式了,因为Vue要监听某个变量的变化,必须将这个变量放在data中,改进一下之前的代码:

import store from './store'axios.get('http://localhost/index.php').then(res =>{

Vue.prototype.uid=res.data.uid

Vue.prototype.appid=res.data.appid

let vm= newVue({

el:'#app',

router,

data() {return{

uploadImgUrl: []

}

},

store:store(res.data),

render: h=>h(App)

})

window.getUpload= function(path) {

vm.uploadImgUrl=path

}

})

上面将变量存放在根组件的data中,在其它组件内就可以通过以下形式访问到

this.$root.$data.uploadImgUrl

虽然拿到了路径,但问题还没有结束,因为这个值是动态变化的,需要使用计算属性来监测它的变化,下面是核心代码:

data() {return{

loadedImgs:[]//保存已上传的图片

}

},

methods: {

deleteImg(index) {for (let i = 0; i < this.loadedImgs.length; i++) {if (index ===i) {this.loadedImgs.splice(i, 1)break}

}

},

computed: {

imgsList() {this.loadedImgs = this.loadedImgs.concat(this.$root.$data.uploadImgUrl)this.$root.$data.uploadImgUrl =[]  //每次合并完重置一下return this.loadedImgs

}

},

created() {this.$root.$data.uploadImgUrl =[]  //组件创建时先重置一下之前的值

}

}

}

通过computed计算属性,无论是添加图片或者删除图片都能正确展示了。

真机调试

在真机上调试非常不方便,很多调试信息看不到,不过vconsole这个插件解决了这个问题,安装方法非常简单,在依赖里(开发环境或正式环境均可)安装vconsole,然后在main.js中

import Vconsole from 'vconsole'

new Vconsole()

打开页面就能看到右下角多出了一个vConsole的图标,项目中所有console.log的信息都会输出到这个vConsole面板里。

结束

知识点比较繁杂,所以文章有点乱,暂时先总结到这,后续还有很多坑待填。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/476111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android入门第八篇之GridView(九宫图)

GridView跟ListView都是比较常用的多控件布局&#xff0c;而GridView更是实现九宫图的首选!本文就是介绍如何使用GridView实现九宫图。GridView的用法很多&#xff0c;网上介绍最多的方法就是自己实现一个ImageAdapter继承BaseAdapter&#xff0c;再供GridView使用&#xff0c;…

(十九)【AAAI2021】Knowledge-Enhanced Hierarchical Graph Transformer Network for Multi-Behavior Recommend

题目&#xff1a; Knowledge-Enhanced Hierarchical Graph Transformer Network for Multi-Behavior Recommendation 论文链接&#xff1a; 代码链接&#xff1a;https://github.com/akaxlh/KHGT 论文 时间戳放入到关系中&#xff0c;可以参考这篇《Heterogeneous graph trans…

LeetCode 1295. 统计位数为偶数的数字

1. 题目 给你一个整数数组 nums&#xff0c;请你返回其中位数为 偶数 的数字的个数。 示例 1&#xff1a; 输入&#xff1a;nums [12,345,2,6,7896] 输出&#xff1a;2 解释&#xff1a; 12 是 2 位数字&#xff08;位数为偶数&#xff09; 345 是 3 位数字&#xff08;位数…

pymysql保存数组_pymysql 读取大数据内存卡死的解决方案

背景&#xff1a;目前表中只有5G(后期持续增长)&#xff0c;但是其中一个字段(以下称为detail字段)存了2M(不一定2M&#xff0c;部分为0&#xff0c;平均下来就是2M)&#xff0c;字段中存的是一个数组&#xff0c;数组中存N个json数据。这个字段如下&#xff1a;[{"A"…

WPF学习笔记-第二周【基本笔刷】

书接上回&#xff0c;这一次&#xff0c;讲的是WPF中的基本笔刷&#xff0c;由于是菜鸟&#xff0c;就不多说了&#xff0c;继续帖示例代码&#xff1a;&#xff09; 第一部份 代码 第二章 基本笔刷 第一个 示例 VaryTheBackgroud P38 1 #regionVaryTheBackgroud P382 3 ///<…

知识图谱论文阅读(二十)【WWW2020】Heterogeneous Graph Transformer

题目&#xff1a; Heterogeneous Graph Transformer 论文链接&#xff1a; https://arxiv.org/abs/2003.01332 代码链接&#xff1a;https://github.com/acbull/pyHGT 论文 异构图研究之一&#xff1a; 使用元路径来建模异构结构 heterogeneous graphs 《Mining Heterogeneous…

LeetCode 1287. 有序数组中出现次数超过25%的元素

1. 题目 给你一个非递减的 有序 整数数组&#xff0c;已知这个数组中恰好有一个整数&#xff0c;它的出现次数超过数组元素总数的 25%。 请你找到并返回这个整数 示例&#xff1a; 输入&#xff1a;arr [1,2,2,6,6,6,6,7,10] 输出&#xff1a;6提示&#xff1a; 1 < arr…

你真的知道一个HTML及资源是如何load的吗(了解各个部分是何时下载和执行的)

你真的知道一个HTML及资源是如何load的吗(了解各个部分是何时下载和执行的)2009-12-03 01:09 by Tower Joo, 3741 visits, 网摘, 收藏, 编辑 你真的知道一个HTML及资源是如何load的吗(了解各个部分是何时下载和执行的) 本博客所有内容采用 Creative Commons Licenses 许可使用.…

vue开发手机页面闪烁_Vue页面加载闪烁问题的解决方法_婳祎_前端开发者

v-if 和 v-show 的区别v-if只会在满足条件时才会编译&#xff0c;而v-show不管是否满足条件始终会编译&#xff0c;v-show的显示与隐藏只是简单的切换也就是说&#xff0c;在使用v-if时&#xff0c;若值为false&#xff0c;那么页面将不会有这个使用场景一般来说&#xff0c;v-…

知识图谱论文阅读(二十一)【SIGIR2019】NGCF: Neural Graph Collaborative Filtering

题目&#xff1a;Neural Graph Collaborative Filtering 代码&#xff1a; https://github.com/xiangwang1223/neural_graph_collaborative_filtering 本文参考了博文 想法 &#xff08;1&#xff09;其实是很有缺点&#xff0c;在消息传播中&#xff0c;只是使用了邻居与目…

[推荐]VMware Workstation 6.5虚拟机(汉化补丁+注册机+原版安装文件)

VMware虚拟机6.5 新版虚拟机过了近一年的开发&#xff0c;VMware Workstation 6.5终于正式发布了。 这个增强版的Vmware Workstation 6.5不仅将3D加速带到了虚拟机平台&#xff0c;而且新增的Unity模式更是改变了虚拟机应用的模式。 VMware Workstation 6.5新特性有&#xff1a…

bootstrap获取弹框数据_Bootstrap模态弹出框的实例教程

前面的话在 Bootstrap 框架中把模态弹出框统一称为 Modal。这种弹出框效果在大多数 Web 网站的交互中都可见。比如点击一个按钮弹出一个框&#xff0c;弹出的框可能是一段文件描述&#xff0c;也可能带有按钮操作&#xff0c;也有可能弹出的是一张图片。本文将详细介绍Bootstra…

知识图谱论文阅读(二十三)【SIGIR2020】Multi-behavior Recommendation with Graph Convolutional Networks

题目&#xff1a; Multi-behavior Recommendation with Graph Convolutional Networks 论文地址&#xff1a; 论文代码&#xff1a; 想法 将相同行为的交互方式进行了聚合来计算user Embedding和item Embedding 创新 模型要做的事情就是user-item传播层学习行为影响力度&am…

LeetCode 1200. 最小绝对差

1. 题目 给你个整数数组 arr&#xff0c;其中每个元素都 不相同。 请你找到所有具有最小绝对差的元素对&#xff0c;并且按升序的顺序返回。 示例 1&#xff1a; 输入&#xff1a;arr [4,2,1,3] 输出&#xff1a;[[1,2],[2,3],[3,4]]示例 2&#xff1a; 输入&#xff1a;ar…

在mojoportal项目中发邮件使用的是dotnetopenmail

[翻译]开源发送邮件组件dotnetopenmail使用介绍 在mojoportal项目中发邮件使用的是dotnetopenmail介绍发邮件是非常简单的,不管用System.web.mail [ASP.NET 1.1]或System.Net.mail [ASP.NET 2.0],但是还是有其他第三方组件可以被使用,比如DotNetOpenMail.他可以使你用最少的代码…

怎么看表_干货 | 剪力墙、柱、板配筋率到底怎么算?

干货 | 剪力墙、柱、板配筋率到底怎么算&#xff1f;正在努力的阿源 北京峰源结构设计 剪力墙&#xff08;纯剪力墙&#xff09;1.一般部位墙厚高规7.2.1条及抗规6.4.1条&#xff0c;对于一般部位&#xff0c;一、二级不应小于160mm且不宜小于层高或无支长度的1/20&#xff0c;…

(二十四)【2021 ACL】OntoED: Low-resource Event Detection with Ontology Embedding

题目&#xff1a; OntoED: Low-resource Event Detection with Ontology Embedding 论文链接&#xff1a; https://arxiv.org/abs/2105.10922 论文代码&#xff1a;https://github.com/231sm/Reasoning_In_EE 论文 什么原型&#xff1f; Prototypical networks for few-shot …

哈尔滨理工C语言程序设计精髓_【注意啦】哈尔滨工业大学2020考研计算机专业课调整,难度提升!...

前言&#xff1a;最近各高校在密集调整计算机相关专业的专业课&#xff0c;从热门985高校、211高校到普通本科&#xff0c;许多学校的专业课都进行了调整。各高校通常会发布专业课调整通知或者直接发布2020研究生招生专业目录&#xff0c;请各位同学多多关注相关信息。哈尔滨工…

数据恢复软件(绝对真实可用)

本软件已经本人测试&#xff0c;这个数据恢复软件是我用过的感觉最好用的一个了。声明&#xff1a;我是在我电脑没有重装系统的前提下进行测试的。小小的这么一个绿色软件&#xff0c;还真的可以找回大部分删除了N久的文件。感觉很爽。现给大家展示几张我测试时的截图&#xff…

LeetCode 1221. 分割平衡字符串

1. 题目 在一个「平衡字符串」中&#xff0c;‘L’ 和 ‘R’ 字符的数量是相同的。 给出一个平衡字符串 s&#xff0c;请你将它分割成尽可能多的平衡字符串。 返回可以通过分割得到的平衡字符串的最大数量。 示例 1&#xff1a; 输入&#xff1a;s "RLRRLLRLRL"…