Vue項(xiàng)目用于Ios和Android端開發(fā)

起因

前公司商城App項(xiàng)目使用的是H5開發(fā),有微信公眾號(hào)、Ios和Android三個(gè)版本,H5版本是自己寫的一套框架,已經(jīng)用了有些年頭了,承載不下不斷涌現(xiàn)出的新需求。而Ios和Android端通過webview加載h5文件顯示,App的原生功能和H5交互的代碼寫得有些凌亂,在我接手項(xiàng)目后老板完全沒給重構(gòu)的時(shí)間,所以只能在做新功能的時(shí)候順手一點(diǎn)點(diǎn)的重構(gòu)。后來要做一個(gè)與原先的商城相對(duì)獨(dú)立的新商城,而且新商城的入口放在老商城中。因?yàn)闀r(shí)間緊任務(wù)重,使用React Native或者weex的話需要將原項(xiàng)目重構(gòu)后再引入,考慮到可能存在的各種各樣的坑,不太可能使用這些解決方案。使用vue或者react構(gòu)建一個(gè)web項(xiàng)目再嵌入原有的app項(xiàng)目中是最穩(wěn)妥的。最終因?yàn)関ue的名字在字符數(shù)和音節(jié)數(shù)量上占了絕對(duì)的優(yōu)勢(shì)而入選。

vue項(xiàng)目構(gòu)建

預(yù)備

vue中文文檔: https://cn.vuejs.org/v2/guide/instance.html

構(gòu)建工具環(huán)境
nodejs: http://nodejs.cn

構(gòu)建工具vue-cli:
https://github.com/vuejs/vue-cli

如果是第一次接觸vue或者在已有項(xiàng)目中引入vue時(shí)可以選擇用CDN版本或者下載js文件

vue的生產(chǎn)版本js:
https://vuejs.org/js/vue.min.js

引入CDN版本:
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

構(gòu)建項(xiàng)目

如果是作為一個(gè)新項(xiàng)目,還是建議使用vue-cli構(gòu)建項(xiàng)目,省時(shí)省心

安裝完nodejs環(huán)境后在終端里輸入:
npm install --global vue-cli

進(jìn)入要存放項(xiàng)目的目錄后創(chuàng)建一個(gè)基于webpack模板的新項(xiàng)目
vue init webpack my-project

其他模板還有pwa、browserify、webpack-simple、simple、browserify-simple等,可以自行到Github上了解:https://github.com/vuejs-templates

在構(gòu)建時(shí)有這么幾個(gè)選項(xiàng)需要注意:
Vue build:
選擇Runtime + Compiler: recommended for most users
官方的解釋https://cn.vuejs.org/v2/guide/installation.html#運(yùn)行時(shí)-編譯器-vs-只包含運(yùn)行時(shí)

vue-router:
建議選上,文檔地址 https://router.vuejs.org/zh-cn/

ESLint:
建議選上,模板使用Standard ,官網(wǎng)地址 https://eslint.org

編譯與運(yùn)行

進(jìn)入項(xiàng)目根目錄打開package.json文件可以看到項(xiàng)目的各項(xiàng)配置,其中scripts下存放的是各種命令,在命令行中通過npm run ***來執(zhí)行

npm run dev 或者 npm start

相當(dāng)于執(zhí)行webpack-dev-server --config build/webpack.dev.conf.js啟動(dòng)開發(fā)環(huán)境

在開發(fā)中經(jīng)常會(huì)使用process.env.***的值來區(qū)分不同的環(huán)境。環(huán)境變量的值在/config/*.env.js文件中配置,webpack.dev.conf.js文件中引入的配置文件是dev.env.js,我們可以在開發(fā)是判斷process.env.NODE_ENV的值是否為development來確定當(dāng)前環(huán)境是否為開發(fā)環(huán)境

在不改任何配置的情況下啟動(dòng)后,在瀏覽器中輸入http://localhost:8080就可以看到效果了

image

npm run build

執(zhí)行此命令后會(huì)對(duì)當(dāng)前項(xiàng)目進(jìn)行編譯打包,編譯完成后我們就可以在/dist目錄下看到我們需要的項(xiàng)目文件了。

編譯完成后可以在終端上看到這樣一段溫馨提示,“不允許通過直接打開index.html文件進(jìn)行訪問哦”


image

這也就意味著將打包后的項(xiàng)目直接放到Ios或Android項(xiàng)目中使用webview加載也是不允許的。這可如何是好呢?
我們偷偷的點(diǎn)開/dist/index.html文件看看會(huì)發(fā)生什么吧?


image

一片空白并且報(bào)了ERR_FILE_NOT_FOUND的錯(cuò)誤,沒有找到css和js文件。用編輯器打開文件后可以看到,這幾個(gè)文件的路徑確實(shí)有些問題,于是在路徑前加上一個(gè).號(hào)后發(fā)現(xiàn)打開頁面不再是一片空白了。

image

但是,我們不可能每次編譯都重新手動(dòng)修改一次文件吧?很明顯這個(gè)是可以在編譯的配置里面設(shè)置的.
打開/config/index.js文件,找到build {}的配置下有一個(gè)assetsPublicPath: '/'的參數(shù)配置,修改成assetsPublicPath: './'就好啦,執(zhí)行npm run build后資源文件的路徑就修改成./了。

image

現(xiàn)在無論是用http://還是file://訪問都沒問題了。放到Ios或者Android項(xiàng)目中應(yīng)該也沒有問題了

關(guān)于source map

使用webpack編譯后會(huì)發(fā)現(xiàn)每個(gè)資源文件都有一個(gè)對(duì)應(yīng)的.map文件,而且這個(gè)文件所占的體積還不小,在沒加任何代碼的情況下將項(xiàng)目文件壓縮成zip包后大小為227k,如果刪除.map文件后只有50k,可以想象.map文件對(duì)項(xiàng)目體積的影響。
在編譯完項(xiàng)目后我們自己寫的所有js代碼會(huì)被壓縮到一個(gè)app.***.js文件中,這時(shí)候如果在線上某個(gè)函數(shù)報(bào)錯(cuò)了,.map文件可以幫我們定位到報(bào)錯(cuò)的函數(shù)具體是在哪個(gè)文件里的。然而大多數(shù)情況下.map文件是沒有必要打包放到線上的.
打開/config/index.js文件,找到build {}的配置下的productionSourceMap改成false就不會(huì)生成.map文件啦

image

壓縮打包

在一般項(xiàng)目中在開發(fā)完成后我們通常會(huì)將文件打包成一個(gè)zip文件,這樣不但方便保存和傳輸,還有一種儀式感。那么要怎樣在編譯完成之后自動(dòng)打包成zip文件呢。
首先我們需要安裝一個(gè)webpack-zip-plugin工具
npm i webpack-zip-plugin --save-dev

然后打開/build/webpack.prod.conf.js文件,在文件中引入相關(guān)的包

const WebpackZipPlugin =require('webpack-zip-plugin')

plugin: []中加入WebpackZipPlugin的配置:

    new WebpackZipPlugin({
      initialFile: './dist/release/',  //需要打包的文件夾(一般為dist)
      endPath: './dist/release/',  //打包到對(duì)應(yīng)目錄(一般為當(dāng)前目錄'./')
      zipName: 'release.zip' //打包生成的文件名
    })

可以在dist目錄下看到release.zip文件啦。

關(guān)于跨域

在本地開發(fā)的時(shí)候如果要調(diào)用服務(wù)端的接口,肯定會(huì)遇到跨域問題,這時(shí)候我們只需要在/config/index.js文件中的dev: {}里面加上proxyTable就行了.

    proxyTable:{
      '/server': {
        target: 'http://192.168.11.5:3001'
      }
    }

這樣我們就可以將http://localhost:8080/server路徑的所有請(qǐng)求都轉(zhuǎn)發(fā)到http://192.168.11.5:3001/server下了

Android項(xiàng)目

關(guān)于WebView

無論是Android的WebView還是Ios的UIWebView和WKWebView都只是提供一套接口方便開發(fā)者調(diào)用,而實(shí)際工作都是交給WebKit完成的。后來Google在WebKit的基礎(chǔ)上按照自己的風(fēng)格與優(yōu)化出了Blink,用于自己的瀏覽器產(chǎn)品。由Blink我們可以看出Google在Android的WebView優(yōu)化上做出了不少的努力。但是還是會(huì)難以抑制的擔(dān)心系統(tǒng)WebView的性能,尤其是當(dāng)看到騰訊X5內(nèi)核標(biāo)注的技術(shù)特性。不管怎樣,騰訊爸爸的話還是要信的,所以在demo中使用了X5內(nèi)核。


image

http://x5.tencent.com/tbs/guide/procIntro.html

加載vue項(xiàng)目

將Vue項(xiàng)目生成的文件放到Android項(xiàng)目的Assets目錄下,使用WebView的loadUrl方法加載就行了

mWebView.loadUrl("file:///android_asset/vue/index.html"); 

關(guān)于跨域

如果vue項(xiàng)目中有請(qǐng)求服務(wù)端數(shù)據(jù)的功能,就有可能產(chǎn)生跨域的問題,日志中會(huì)發(fā)現(xiàn)如下錯(cuò)誤

No 'Access-Control-Allow-Origin' header is present on the requested resource.

Android的WebView處理跨域問題很簡(jiǎn)單,只要將AllowUniversalAccessFromFileURLs設(shè)置為True就行了

WebSettings webSetting = mWebView.getSettings();
webSetting.setAllowUniversalAccessFromFileURLs(true);

Ios項(xiàng)目

加載vue項(xiàng)目

Ios可以使用UIWebView或者WKWebView直接加載

<!--    UIWebView   -->
let mWebView = UIWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
let path = Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "vue")

let url = URL(fileURLWithPath: path!)
self.view.addSubview(mWebView)
mWebView.loadRequest(URLRequest(url: url))

<!--    WKWebView   -->
let mWebView = WKWebView.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
    
let path = Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "vue")
    
let url = URL(fileURLWithPath: path!)
self.view.addSubview(mWebView)
mWebView.load(URLRequest(url: url))

demo

github: https://github.com/ljnjiannan/vue-demo

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容