摘要:使用值來(lái)作路由。原生應(yīng)用本身就是多頁(yè)的場(chǎng)景,頁(yè)面間狀態(tài)的隔離比共享更重要一些。使用開發(fā)的是原生應(yīng)用,頁(yè)面棧的管理使用的也是原生的特性,沒有但是有模塊可以實(shí)現(xiàn)頁(yè)面的前進(jìn)和后退等操作。
系列文章的目錄在 ? 這里
(由于 我比較懶 最近一段時(shí)間在忙其他事,系列文章拖了好久終于又更新了。。。)
vue-router 官方文檔
vue-router 是針對(duì) Vue.js 開發(fā)的前端路由工具,可以很方便的開發(fā)單頁(yè)應(yīng)用。
單頁(yè)應(yīng)用單頁(yè)應(yīng)用的概念其實(shí)很早就出現(xiàn)了,它是指在同一個(gè)頁(yè)面內(nèi)包含了應(yīng)用的所有功能,一個(gè)頁(yè)面就是一個(gè)應(yīng)用,整個(gè)應(yīng)用只有一個(gè)頁(yè)面,是在 Web 場(chǎng)景下提出的一種開發(fā)方式。單頁(yè)應(yīng)用的特性在文末討論,這里先說(shuō)用法。
怎么在 Weex 里引入 vue-routervue-router 是以 Vue.js 插件的形式存在的,使用前必須要引入 Vue.js。因?yàn)?WeexSDK (>= 0.9.5)中已經(jīng)包含了 Vue.js Runtime,所以不需要再引入一遍 Vue.js ,只需引入 vue-router 并注冊(cè)即可:
// import Vue from "vue" import VueRouter from "vue-router" Vue.use(VueRouter)使用 vue-router 的例子 定義根視圖
通過在模板中添加
在模板中也可以包含其他標(biāo)簽,
在向應(yīng)用中注冊(cè) router 之前,需要先創(chuàng)建路由實(shí)例,并且配置路由規(guī)則。
// router.js import VueRouter from "vue-router" import HomeView from "path/to/HomeView.vue" import AboutView from "path/to/AboutView.vue" Vue.use(VueRouter) export default new VueRouter({ routes: [ { path: "/home", component: HomeView }, { path: "/about", component: AboutView } ] })
上述代碼中創(chuàng)建了 VueRouter 的實(shí)例,并且傳入了 routes 配置,當(dāng)路徑是 home 時(shí),頁(yè)面就會(huì)跳轉(zhuǎn)到 HomeView 組件,HomeView.vue 就會(huì)渲染到 App.vue 中
想要在應(yīng)用中注入路由功能,還有給入口組件添加 router 屬性,使應(yīng)用和路由建立聯(lián)系。
import App from "path/to/App.vue" import router from "path/to/router.js" App.el = "#root" App.router = router new Vue(App)注意事項(xiàng)
前邊提到過,單頁(yè)應(yīng)用是在 Web 場(chǎng)景下提出的一種開發(fā)方式,它的具體實(shí)現(xiàn)依賴了 Web 平臺(tái)的功能,如 Histroy API 和 URL Hash 等特性。然而 Weex 的運(yùn)行環(huán)境不只是瀏覽器,通常是以移動(dòng)端原生環(huán)境為主,這些特性在 Weex 中并不完全適用,參考《Weex 和 Web 平臺(tái)的差異》。
針對(duì)這些平臺(tái)差異,有以下兩點(diǎn)需要注意:
路由模式在 vue-router 的配置項(xiàng)中,有一個(gè) mode 參數(shù)可以用來(lái)指定 vue-router 的運(yùn)行模式。
hash: 使用 URL hash 值來(lái)作路由。默認(rèn)模式。
history: 依賴 HTML5 History API 和服務(wù)器配置。查看 HTML5 History 模式。
abstract: 支持所有 JavaScript 運(yùn)行環(huán)境,如 Node.js 服務(wù)器端。
根據(jù)平臺(tái)差異可以看出,在 Weex 環(huán)境中只支持使用 abstract 模式。 不過,vue-router 自身會(huì)對(duì)環(huán)境做校驗(yàn),如果發(fā)現(xiàn)沒有瀏覽器的 API,vue-router 會(huì)自動(dòng)強(qiáng)制進(jìn)入 abstract 模式,所以 在使用 vue-router 時(shí)只要不寫 mode 配置即可,默認(rèn)會(huì)在瀏覽器環(huán)境中使用 hash 模式,在移動(dòng)端原生環(huán)境中使用 abstract 模式。 (當(dāng)然,你也可以明確指定在所有情況下都使用 abstract 模式)
編程式導(dǎo)航vue-router 支持使用
除了上述最基本的特性以外,vue-router 還有很多很強(qiáng)大的功能,具體使用方法建議參考其官方文檔,這里不再贅述。
動(dòng)態(tài)路由匹配
嵌套路由
編程式導(dǎo)航
重定向和別名
導(dǎo)航鉤子
過渡動(dòng)效
實(shí)際項(xiàng)目中的 vue-router在 weex-hackernews 項(xiàng)目中使用了 vue-router 做路由管理。
路由配置其中表頭的五個(gè)一級(jí)菜單(Top 、New 、Show 、Ask 、Job),就對(duì)應(yīng)了五個(gè)不同的路由路徑,也對(duì)應(yīng)了五個(gè)列表組件。除此之外,還有列表頁(yè)、評(píng)論頁(yè)、用戶信息頁(yè)也都對(duì)應(yīng)了多帶帶的路由路徑。具體配置在 src/router.js 中,如下所示:
export default new Router({ routes: [ { path: "/top", component: createStoriesView("top") }, { path: "/new", component: createStoriesView("new") }, { path: "/show", component: createStoriesView("show") }, { path: "/ask", component: createStoriesView("ask") }, { path: "/job", component: createStoriesView("job") }, { path: "/article/:url(.*)?", component: ArticleView }, { path: "/item/:id(d+)", component: CommentView }, { path: "/user/:id", component: UserView }, { path: "/", redirect: "/top" } ] })
其中 article 、item 和 user 三個(gè)配置項(xiàng)中用到了動(dòng)態(tài)路由匹配,把所有同類路由都映射到了同一個(gè)組件上,組件結(jié)構(gòu)相同,但是參數(shù)是不同的(url 不同或者 id 不同)。
在最后還配置了路由重定向,將默認(rèn)根路由 / 重定向到了 /top,默認(rèn)加載“最熱”文章列表。
在應(yīng)用中注冊(cè)路由若要應(yīng)用組件和路由之間建立聯(lián)系,需要給入口組件注入 router 屬性。代碼在 src/entry.js 中。
new Vue(Vue.util.extend({ router }, App)) router.push("/")
代碼在創(chuàng)建 Vue 實(shí)例前在 App 上添加了 router 屬性,使得應(yīng)用組件中都能通過 this.$router 獲取到路由數(shù)據(jù)。在創(chuàng)建實(shí)例后,手動(dòng)調(diào)用 router.push("/") 跳轉(zhuǎn)到根視圖。
同步 Vuex 和 vue-router 的狀態(tài)使用 vuex-router-sync 可以很方便地同步 Vuex 和 vue-router 的狀態(tài),這個(gè)步驟并不是必須的,但是可以簡(jiǎn)化代碼的使用。實(shí)際代碼在 src/entry.js 中,如下所示:
sync(store, router)
代碼的效果就是注冊(cè)了 store.state.route 這個(gè)變量,使得在 Vuex 的 Store 中可以獲取到 route 對(duì)象,這在一些比較復(fù)雜的大型應(yīng)用中可能會(huì)用到。
Weex 適合寫單頁(yè)應(yīng)用嗎 ?由于在根組件中已經(jīng)注入了 router 屬性,在所有組件中也都可以通過 this.$router 獲取到當(dāng)前的路由狀態(tài)。
以下是我個(gè)人的觀點(diǎn),不代表任何人,也不代表 Weex。
不考慮技術(shù)細(xì)節(jié),從實(shí)際應(yīng)用的角度聊一下我對(duì)“單頁(yè)應(yīng)用”的看法。
單頁(yè)應(yīng)用也有不少的優(yōu)勢(shì)和缺陷:
優(yōu)勢(shì):頁(yè)面無(wú)需刷新;可以實(shí)現(xiàn)更好的過渡效果;組件復(fù)用;狀態(tài)共享。
缺陷:初次加載白屏?xí)r間長(zhǎng);不利于 SEO;有大量全局狀態(tài);技術(shù)方法相對(duì)復(fù)雜,有學(xué)習(xí)成本。
大部分特性都已經(jīng)有共識(shí),我也不再展開對(duì)比,這里著重討論一下在 移動(dòng)端 和 Weex 平臺(tái) 中使用單頁(yè)應(yīng)用的情況。
頁(yè)面間狀態(tài)的共享與隔離單頁(yè)應(yīng)用運(yùn)行在同一個(gè) javascript runtime 里,也就是說(shuō)頁(yè)面的狀態(tài)都是共享的,環(huán)境變量也是相同的,這一點(diǎn)其實(shí)是有很多隱患。在移動(dòng)應(yīng)用中,單頁(yè)應(yīng)用不僅耗費(fèi)內(nèi)存,也很容易發(fā)生內(nèi)存泄露。
所有的 Weex 頁(yè)面,無(wú)論是基于 Vue 還是 Rax,都共用一個(gè) Weex Runtime,其中的 js 引擎也只初始化一次,除非重新初始化 Weex SDK(應(yīng)用重啟),所有頁(yè)面對(duì)環(huán)境的操作痕跡都將保留。在這種情景下,頁(yè)面間狀態(tài)的隔離就尤為重要,共享的全局狀態(tài)很可能會(huì)成為內(nèi)存泄露的元兇。
換句話說(shuō),如果某個(gè)頁(yè)面創(chuàng)建了一個(gè)臨時(shí)的全局變量,但是在頁(yè)面退出后沒有清除,這個(gè)變量將一直保留在內(nèi)存中;如果某個(gè)頁(yè)面在全局狀態(tài)上掛載了某個(gè)屬性,但是頁(yè)面退出后沒有斷開連接,這個(gè)屬性也會(huì)一直保留在全局狀態(tài)中。
原生應(yīng)用本身就是多頁(yè)的場(chǎng)景,頁(yè)面間狀態(tài)的隔離比共享更重要一些。
資源加載和緩存單頁(yè)應(yīng)用要把所有頁(yè)面用到資源(至少是腳本)提前打包在一起,一次性全部發(fā)到客戶端,首次打開的網(wǎng)絡(luò)耗時(shí)會(huì)比較久,容易導(dǎo)致長(zhǎng)時(shí)間白屏,很難遞進(jìn)的加載資源,無(wú)法做到“先加載有用的”。如果有多個(gè)單頁(yè)應(yīng)用都需要用到某些頁(yè)面或者某個(gè)組件,是很難復(fù)用的,也很難加緩存,難不成整個(gè)移動(dòng)應(yīng)用都寫成一個(gè)大“單頁(yè)”的嗎? Web 上或許可以考慮,但是原生應(yīng)用里十分不建議這樣做。應(yīng)用都規(guī)模越大,這些缺陷就越明顯。
更何況現(xiàn)在 HTTP/2 逐漸普及,有了多路復(fù)用,把資源粒度劃分的細(xì)一些更有利于瀏覽器的加載。還有 prefetch 和 preload 這種特性可以提升資源加載的效率,Weex 也在考慮支持。瀏覽器也逐漸開始支持 ES6 module,可以直接通過 的方式引入 ES6 模塊,代碼的管理和加載可能會(huì)以 模塊 為單元,而不是頁(yè)面。
從一系列技術(shù)趨勢(shì)來(lái)看,現(xiàn)在有很多技術(shù)方案都講究將資源細(xì)分,恨不得使用 code split 把代碼細(xì)分到組件級(jí)別(“打包”是一個(gè)暫時(shí)性的讓人又愛又恨的工作)。
Histroy API 和 hash單頁(yè)應(yīng)用在技術(shù)上基本上都是基于 Histroy API 或 hash 鏈接實(shí)現(xiàn),即使不直接依賴,也會(huì)模擬這方面的行為(polyfill)。前邊也提到過 Weex 和 Web 平臺(tái)有差異, Histroy API 和 hash 這些都是瀏覽器中的概念,和 Weex 里不完全對(duì)應(yīng)。
使用 Weex 開發(fā)的是原生應(yīng)用,頁(yè)面棧的管理使用的也是原生的特性,沒有 Histroy API 但是有 navigator 模塊 可以實(shí)現(xiàn)頁(yè)面的“前進(jìn)”和“后退”等操作。其實(shí)我覺得原生開發(fā)中 Navigator 的概念比 web 上 History API 設(shè)計(jì)的更完善一些(由于多端行為有差異,Weex 只暴露了部分通用功能),可操作性也更強(qiáng)。至于 hash,移動(dòng)端不會(huì)輕易暴露頁(yè)面 url,更不用說(shuō) hash 了。
一句話總結(jié): Weex 是跨平臺(tái)的,Histroy API 是針對(duì) Web 平臺(tái)設(shè)計(jì)的,未必適合原生開發(fā)。
小結(jié)技術(shù)本身是客觀的,有各自的適用場(chǎng)景。weex-hackernews 項(xiàng)目本身的頁(yè)面也不多,多個(gè)頁(yè)面之間的確會(huì)共用一些數(shù)據(jù);而且本來(lái)這就是一個(gè)范例項(xiàng)目,為了展示能力和用法的,所以我用了 vue-router。在你的應(yīng)用中是否應(yīng)該引入 vue-router,需要結(jié)合應(yīng)用自身的特性和需求具體分析。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/82539.html
摘要:全球首個(gè)使用和開發(fā)的原生應(yīng)用那就是官方出了一個(gè),是一個(gè)完整的使用的例子,并且用到了和服務(wù)端渲染。項(xiàng)目介紹和文章目錄配置開發(fā)環(huán)境編寫?yīng)毩㈨?yè)面使用框架的特性使用平臺(tái)的功能使用使用完整項(xiàng)目目錄詳解 背景介紹 Weex 和 Vue 已經(jīng)互相支持,這也不是新聞了(如果你覺得是新聞,自行在網(wǎng)上搜相關(guān)信息……),Vue.js 也因此具備了開發(fā)原生應(yīng)用的能力。 Vue 官方倉(cāng)庫(kù)中包含了適配 Weex ...
目錄 Weex系列(序) —— 總要知道原生的一點(diǎn)東東(iOS) Weex系列(序) —— 總要知道原生的一點(diǎn)東東(Android) Weex系列(1) —— Hello World項(xiàng)目 Weex系列(2) —— 頁(yè)面跳轉(zhuǎn)和通信 Weex系列(3) —— 單頁(yè)面還是多頁(yè)面 [Weex系列(4) —— 老生常談的三端統(tǒng)一] [Weex系列(5) —— 封裝原生組件和模塊] [Weex系列(6) —...
閱讀 1386·2021-09-30 09:55
閱讀 1910·2021-08-27 13:10
閱讀 2259·2019-08-29 17:22
閱讀 1309·2019-08-29 16:30
閱讀 3474·2019-08-26 18:37
閱讀 2361·2019-08-26 11:47
閱讀 1173·2019-08-23 14:44
閱讀 1748·2019-08-23 13:46