前言

最近项目迭代需要开发一个app,由于项目组其他系统前端技术栈都是Vue,所以自己在需求评估的时候就初步敲定了Cordova+Vue的前端架构,后来查阅了不少资料,也掉了不少坑,这里总结一下,也算是对自己这段时间摸索的回顾吧。

项目脚手架搭建

首先安装nodecordova,下面是我项目的版本号

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。 Cordova+Vue快速搭建Hybrid App 随笔 第1张 mac配置Android sdk,此处有 具体教程

vue-cli项目搭建

安装vue-cli

npm install -g @vue/cli
vue init webpack vue-app
cd vue-app npm i 复制代码

执行成功之后项目目录如下:

Cordova+Vue快速搭建Hybrid App 随笔 第2张 之后执行 npm run dev 看到浏览器如下页面,可以说明项目搭建成功了。 Cordova+Vue快速搭建Hybrid App 随笔 第3张

cordova项目搭建

在项目同级目录下创建cordova项目

执行cordova create cordova-app

项目整体目录如下:

Cordova+Vue快速搭建Hybrid App 随笔 第4张 www目录存放编译后的前端代码,包括Html,CSS,JS

项目整合

下面是将vue项目编译代码的目录指向cordova的www目录,这样就可以实现项目整合了,vue项目负责页面代码编写,cordova项目负责打包和原生接口调用。

Cordova+Vue快速搭建Hybrid App 随笔 第5张 Cordova+Vue快速搭建Hybrid App 随笔 第6张

修改之后执行npm run build 就可以看到vue-app项目的代码编译打包到cordova-app的www目录了。

引入sass-loader

因为vue-cli默认生成的项目是不支持sass语法的,所以需要引入sass-loader

npm install sass-loader node-sass webpack --save-dev

安装成功之后就可以在vue组件中愉快地编写样式了

<style lang="scss"> @import 'assets/style/reset.scss'; @import 'assets/style/variable.scss'; @import 'assets/style/common.scss'; </style> 复制代码

抽离公共组件

项目是基于平板的应用,所以需要用到一些通用UI组件,在src目录新建base文件夹,存放通用组件,此处以移动端常用的toast组件为例,加入了transition动画效果:

<template>
    <transition name="fade"> <div class="wrapper" v-if="show"> <div class="container"> <p class="title tc">{{title}}</p> <p class="content tc" v-for="msg in content" :key="msg">{{msg}}</p> <p class="action tc" @click="confirm" v-if="type == 'toast'">{{action}}</p> <p class="confirm tc" v-if="type == 'confirm'"> <span @click="cancel">{{cancelText}}</span> <span @click="ok">{{okText}}</span> </p> </div> </div> </transition> </template> <script> export default { // 弹窗组件 name: 'Toast', props: { type: { type: String, default: 'toast' }, show: { type: Boolean, default: false }, title: { type: String, default: '' }, content: { type: Array, default: null }, action: { type: String, default: '确定' }, cancelText: { type: String, default: '取消' }, okText: { type: String, default: '确定' } }, methods: { confirm() { this.$emit('confirm') }, cancel() { this.$emit('cancel') }, ok() { this.$emit('ok') } } } </script> <style scoped lang="scss"> @import '../assets/style/variable.scss'; .wrapper { z-index: 999; background-color: $black-color3; position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; .container { width: 400px; border-radius: 4px; background-color: #eee; .title { color: #333; font-size: 28px; line-height: 28px; margin: 40px 0 20px 0; } .content { color: #666; font-size: 24px; line-height: 31px; font-weight: 200; padding: 0 32px; } .action, .confirm { border-top: 2px solid #ddd; height: 80px; line-height: 80px; font-size: 28px; color: #007AFF; margin-top: 40px; } .confirm { display: flex; span { flex-grow: 1; &:first-child { border-right: 2px solid #ddd; color: #333; } } } } } </style> 复制代码
Cordova+Vue快速搭建Hybrid App 随笔 第7张

调用Cordova插件

之所以要开发成app,自然是需要调用设备原生api,cordova有相当多的插件供开发者使用,只需要安装添加到cordova-app项目即可调用。

类似扫码功能cordova plugin add phonegap-plugin-barcodescanner

vue-app当中调用时也很简单:

if (window.cordova && window.cordova.plugins.barcodeScanner) { window.cordova.plugins.barcodeScanner.scan((result) => { if (result && result.text) { alert(result.text) } }, (err) => { console.log(err) }, { prompt: '', // 提示文字 resultDisplayDuration: 0// 扫描成功文字停留时间 }) } 复制代码

不过,当你打包出来会发现window.cordovaundefined,其实你还漏了一步,cordova打包之后调用插件需要手动引入cordova.js,而我们的vue代码并没有这一步操作,所以我们需要在main.js里面加入:

// 增加cordova文件 if (window.location.protocol === 'file:') { let cordovaScript = document.createElement('script') cordovaScript.setAttribute('type', 'text/javascript') cordovaScript.setAttribute('src', 'cordova.js') document.body.appendChild(cordovaScript) } 复制代码

这样打包就大功告成了。

引入Vuex

单页应用在共享数据上存在一定的麻烦,所以此时Vuex就登场了。

在src增加以下目录文件:

Cordova+Vue快速搭建Hybrid App 随笔 第8张 此处我们实现一个wifi连接状态以及名称的管理。具体看以下代码:

getter.js

export const wifi = state => state.wifi 复制代码

index.js

import Vue from 'vue' import Vuex from 'vuex' import * as getters from './getters' import state from './state' import mutations from './mutations' import createLogger from 'vuex/dist/logger' Vue.use(Vuex) const debug = process.env.NODE_ENV !== 'production' export default new Vuex.Store({ getters, state, mutations, strict: debug, plugins: debug ? [createLogger()] : [] }) 复制代码

mutation-types.js

export const SET_WIFI_STATUS = 'SET_WIFI_STATUS' export const SET_WIFI_NAME = 'SET_WIFI_NAME' 复制代码

mutations.js

import * as types from './mutation-types' const matutaions = { [types.SET_WIFI_STATUS](state, status) { state.wifi.status = status }, [types.SET_WIFI_NAME](state, name) { state.wifi.name = name } } export default matutaions 复制代码

state.js

const state = {
    wifi: {
        status: false, name: '' } } export default state 复制代码

结语

代码创造世界,世界属于三体。后会有期。

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄