摘要:去年年底自己搭了一個在移動端的開發(fā)框架,感覺體驗不是很好。路由懶加載首頁終于寫完了,以上這些就是我在移動端體驗優(yōu)化的實戰(zhàn)。
去年年底自己搭了一個vue在移動端的開發(fā)框架,感覺體驗不是很好。上個星期又要做移動端的項目了。所以我花了兩天時間對之前的那個開發(fā)框架做了以下優(yōu)化
自定義vuex-plugins-loading
路由切換動畫 + keep alive 動態(tài)管理緩存組件
better-scroll與vue的最佳實踐(better-scroll的vue化)
自定義指令(vue-finger:包括點擊,長按,雙擊,拖拽移動,多點觸控,滑動,旋轉(zhuǎn),縮放手勢)
移動端適配方案
如何分情況處理頁面置頂
路由懶加載
自定義 vuex-plugins-loading
如果每個頁面在數(shù)據(jù)加載完成前,展示loading。你首先想到的是每個頁面設(shè)置狀態(tài),show和hide狀態(tài)。但是這樣冗余代碼太多了,而且自己寫的都煩。我之前的react的項目中用到了dva,其中有dva-loading庫,之前就有研究過,所以我就用他的思想,自己寫一個vuex-loading。
實現(xiàn)思路:vuex中注冊一個管理loading的module,通過綁定異步的action,將每個action的loading存在vuex中,這樣我在每個頁面只需要在vuex的store中拿相對應(yīng)的action loading就能達(dá)到此目的
## 核心代碼 store.subscribeAction({ before: action => { if (shouldEffect(action, includes, excludes)) { store.commit({ type: namespace + "/SHOW", payload: action.type }) } }, after: action => { if (shouldEffect(action, includes, excludes)) { store.commit({ type: namespace + "/HIDE", payload: action.type }) } } }) } }
使用之前大家可以先了解一下subscribeAction
想安裝此插件,請點擊這里,記得給個star喲
注意: 使用上述代碼,vuex必需為3.1.0版本。因為subscribeAction在3.1.0才新增的
我覺得還是寫一下為什么推薦大家使用vuex-plugins-loading這種處理數(shù)據(jù)流的思路。
我也是從前年接觸dva.js的時候,感覺到這種處理數(shù)據(jù)流的思路會讓你的整個項目更清晰,更易迭代。別人接手你的整個框架理解起來比較輕松。
現(xiàn)在我就講一下我這邊是怎么根據(jù)dva.js的思想封裝vuex的。其實很簡單
## store 文件目錄下的 index.js import Vue from "vue" import Vuex from "vuex" import home from "./modules/home" import createLoadingPlugin from "vuex-plugins-loading" Vue.use(Vuex) export default new Vuex.Store({ modules: { home, }, plugins: [createLoadingPlugin()] })
# home.js import { loadDataApi } from "../../service/api" const state = { listData: [], } const mutations = { getData (state, payload) { state.listData = state.listData.concat(payload.res.data.data) state.page = payload.res.data.page state.pageNumber = Math.ceil(payload.res.data.total / payload.res.data.pageSize) }, refreshData (state, payload) { state.listData = payload.res.data.data }, } const getters = { } const actions = { loadMore ({ commit, state }, data) { return new Promise((resolve, reject) => { setTimeout(() => { const { page, type } = data loadDataApi({ page }).then(res => { if (res.code === 200) { if (type === "loadMore") { commit({ type: "getData", res: res }) } else { commit({ type: "refreshData", res: res }) } resolve() } else { reject(res.error) Toast(res.error) } }) }, 1000) }) } }
## Home.vue computed: { // Getting Vuex State from store/modules/home ...mapState({ listData: state => state.home.listData, loading: state => state["@@loading"].effects["home/loadMore"] }), }, methods: { ...mapActions("home", ["initData", "plusPage", "initPage"]), // onLoad 加載數(shù)據(jù) onLoad () { this.requestData("loadMore") }, requestData (type) { setTimeout(() => { this.$store.dispatch("home/loadMore", { }).then(() => { }) }, 1000) }, onRefresh () { this.initPage().then(() => { this.requestData("refresh") }) },
1.先說vuex-plugins-loading內(nèi)層是怎么實現(xiàn)的?
1.plugins: [createLoadingPlugin()],
2.loading: state => state["@@loading"].effects["home/loadMore"]
使用1此插件的時候會綁定你使用過的每個action,在我使用2的時候會將綁定action的loading拿到。
這里面是有兩個過程的。store.subscribeAction 中的before和after。在我調(diào)用action之后我的loading一直是true,這就是在before里面的操作。當(dāng)我的action里面包裹的是promise,則走完resolve()或者reject()后整個action才算完成。之后就會走after。
before
after
我知道大家會問為什么把大量邏輯放在vuex里面處理。其實我反而覺得這樣會讓你的整個項目清晰化,可維護(hù)性高。易于迭代。
.vue文件只是將vuex里面的數(shù)據(jù)進(jìn)行頁面渲染。
store里面將數(shù)據(jù)存取,進(jìn)行過濾。
serve層用來封裝你的api
這樣一目了然
路由切換動畫 + keep alive 動態(tài)管理緩存組件
之前采用的是全局設(shè)置路由切換動畫,但是體驗效果不是很好,特別是返回列表頁,頁面會引起回彈,頁面切換時會有暫時的空白。
未改造前的,也是參考別人的做法
## app.vuecomputed: { // 數(shù)據(jù)存放在vuex里面 ...mapState({ data: state => { return state.global.data } }) }, methods: { // 設(shè)置Keep_alive路由 setKeep_alive (to) { if (to.meta.keepAlive) { this.$store.dispatch({ type: "global/setData", payload: to.name }) } } }, watch: { "$route" (to, from) { // 此時從from頁面跳轉(zhuǎn)到to頁面 this.setKeep_alive(to) const routeDeep = ["/", "/list", "/detail", "/reservation", "/addCars"] const toDepth = routeDeep.indexOf(to.path) const fromDepth = routeDeep.indexOf(from.path) if (!from.name) { this.transitionName = "fold" return } this.transitionName = toDepth > fromDepth "); ## router.js scrollBehavior (to, from, savedPosition) { // keep-alive 返回緩存頁面后記錄瀏覽位置 if (savedPosition && to.meta.keepAlive) { return savedPosition } // 異步滾動操作 return new Promise((resolve) => { setTimeout(() => { resolve({ x: 0, y: 1 }) }, 0) }) },兩個問題
列表頁滑動到一定位置后跳轉(zhuǎn)到詳情頁,返回列表頁頁面回彈
原因:原生滾動條的位置是不變的,使用scrollBehavior,根據(jù)上述代碼可知滾動條會有一個閃爍的過程先置頂,然后滾動到上次保留的位置。頁面切換時會有暫時的空白,過渡不正常。
改造后
## app.vuecomputed: { // 數(shù)據(jù)存放在vuex里面 ...mapState({ data: state => { return state.global.data } }) }, methods: { // 設(shè)置Keep_alive路由 setKeep_alive (to) { if (to.meta.keepAlive) { this.$store.dispatch({ type: "global/setData", payload: to.name }) } } }, watch: { "$route" (to, from) { // 此時從from頁面跳轉(zhuǎn)到to頁面 this.setKeep_alive(to) } }, list.vue1.采用better-scroll后,第一個問題可以直接解決。而且不用設(shè)置scrollBehavior,不懂可以去看better-scroll
2.給頁面CSS添加設(shè)置“position:absolute;”,此時頁面脫離文檔流,不占空間,這樣就不會把下一頁擠下去,完成平滑過渡。使用better-scroll給頁面CSS添加設(shè)置“position:fixed;”。
如果頁面布局里面有用到flex布局,一定要給flex組件加一個position為absolute或者fixed的div。
上述代碼中已有keep alive 動態(tài)管理緩存路由的思路。
better-scroll與vue的最佳實踐
之前在一篇文章上看到BetterScroll可能是目前最好用的移動端滾動插件,所以這次就想試試,滴滴開源的cube-ui組件庫里面大多數(shù)用到的滑動組件都是基于better-scroll,體驗了一下感覺還挺好。為什么沒有用cube了?因為個人感覺主題顏色有點丑。所以自己就打算基于better-scroll封裝一個vue版本的scroll組件。不說那么多了,立馬上圖:
想用better-scroll還有另外一個原因,我想自定義上下拉的動畫。
想看demo及源碼請點擊這里。記得給個star喲
自定義指令 vue-finger
包括點擊,長按,雙擊,拖拽移動,多點觸控,滑動,旋轉(zhuǎn),縮放手勢
這一塊我這邊是基于別人的demo改造的,在這些指令里面你可以做很多在移動端手勢方面想做的事情。后續(xù)我會繼續(xù)迭代這些指令,制定出體驗接近原生的組件,大家要關(guān)注我的github喲
移動端適配方案
## rem.js const baseSize = 32 // 設(shè)置 rem 函數(shù) function setRem () { // 當(dāng)前頁面寬度相對于 750 寬的縮放比例,可根據(jù)自己需要修改。 const scale = document.documentElement.clientWidth / 750 // 設(shè)置頁面根節(jié)點字體大小 document.documentElement.style.fontSize = (baseSize * Math.min(scale, 2)) + "px" } // 初始化 setRem() // 改變窗口大小時重新設(shè)置 rem window.onresize = function () { setRem() } ## main.js import "./rem"還有最后還有一步。對于經(jīng)常寫樣式的同學(xué),px轉(zhuǎn)rem是不是感覺很煩。 我這邊處理的方式是,在項目根目錄新建一個postcss.config.js文件。這樣你只需按照設(shè)計稿的樣式,正常寫px就好。運行項目時會自動幫你轉(zhuǎn)成rem。
module.exports = { plugins: { "autoprefixer": { browsers: ["Android >= 4.0", "iOS >= 7"] }, "postcss-pxtorem": { rootValue: 16, propList: ["*"] } } }如何分情況處理頁面置頂
上文有講到vue-router里面scrollBehavior這個方法。
## router.js scrollBehavior (to, from, savedPosition) { // keep-alive 返回緩存頁面后記錄瀏覽位置 if (savedPosition && to.meta.keepAlive) { return savedPosition } // 異步滾動操作 return new Promise((resolve) => { setTimeout(() => { resolve({ x: 0, y: 1 }) }, 0) }) },但是感覺添加頁面轉(zhuǎn)場動畫后。頁面會有回彈。所以我就放棄它了。不添加動畫的可以考慮。
我這邊用到了better-scroll后就不用擔(dān)心這個問題。看完better-scroll文檔介紹,你就會發(fā)現(xiàn)better-scroll就是為移動端運用而生的。路由懶加載
當(dāng)打包構(gòu)建應(yīng)用時,JavaScript 包會變得非常大,影響頁面加載。如果我們能把不同路由對應(yīng)的組件分割成不同的代碼塊,然后當(dāng)路由被訪問的時候才加載對應(yīng)組件,這樣就更加高效了。 這是路由懶加載就很重要了。看過官方文檔大家應(yīng)該都會用了,這里我就不介紹了。
// 路由懶加載 const _import_ = file => () => import("./views/" + file + ".vue") routes: [ { path: "/", name: "home", component: _import_("Home/Home"), meta: { title: "首頁", keepAlive: true } }, ]終于寫完了,以上這些就是我在移動端體驗優(yōu)化的實戰(zhàn)。希望能幫到大家。如果往后有什么好的優(yōu)化方案我會繼續(xù)更新。謝謝大家的觀看。覺得好的點個贊喲
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/6712.html
摘要:基于等開發(fā)一款移動端音樂,界面參考了安卓版的網(wǎng)易云音樂布局適配常見移動端。圖標(biāo)使用阿里巴巴圖標(biāo)庫,中間的唱片旋轉(zhuǎn)動畫使用了實現(xiàn)。搜索功能實現(xiàn)功能搜索歌手歌單歌曲熱門搜索數(shù)據(jù)節(jié)流上拉刷新保存搜索記錄。 基于 Vue(2.5) + vuex + vue-router + vue-axios +better-scroll + Scss + ES6 等開發(fā)一款移動端音樂 WebApp,UI ...
摘要:如何讓我們所開發(fā)的手機頁面能有更好的交互體驗,就是這篇文章的主旨移動開發(fā)問題和優(yōu)化小結(jié)。關(guān)于和鼠標(biāo)事件的延遲說明,我引用葉小釵大神博客里面的一張圖片,如下在手機上,的延遲將近。 1.前言 到目前為止,互聯(lián)網(wǎng)行業(yè)里,手機越來越智能化,移動端占有的比例越來越高,尤其實在電商,新聞,廣告,游戲領(lǐng)域。用戶要求越來越高,網(wǎng)站功能越來越好,效果越來越炫酷,這就要求我們產(chǎn)品質(zhì)量越來越高,web前端開...
摘要:如何讓我們所開發(fā)的手機頁面能有更好的交互體驗,就是這篇文章的主旨移動開發(fā)問題和優(yōu)化小結(jié)。關(guān)于和鼠標(biāo)事件的延遲說明,我引用葉小釵大神博客里面的一張圖片,如下在手機上,的延遲將近。 1.前言 到目前為止,互聯(lián)網(wǎng)行業(yè)里,手機越來越智能化,移動端占有的比例越來越高,尤其實在電商,新聞,廣告,游戲領(lǐng)域。用戶要求越來越高,網(wǎng)站功能越來越好,效果越來越炫酷,這就要求我們產(chǎn)品質(zhì)量越來越高,web前端開...
摘要:另外,單頁應(yīng)用因為數(shù)據(jù)前置到了前端,不利于搜索引擎的抓取。所以我們需要對自己的單頁應(yīng)用進(jìn)行一些優(yōu)化。 前言 最近秋招之余空出時間來按自己的興趣動手做了一個項目,一個基于vue-cli3.0, vue,typescript的移動端pwa,現(xiàn)在趁熱打鐵,將這個項目從開發(fā)到部署整個過程記錄下來,并將從這個項目中學(xué)習(xí)到的東西分享出來,如果大家有什么意見或補充也可以在評論區(qū)提出。先介紹一下這個項...
閱讀 1155·2023-04-25 17:28
閱讀 3531·2021-10-14 09:43
閱讀 3954·2021-10-09 10:02
閱讀 1941·2019-08-30 14:04
閱讀 3127·2019-08-30 13:09
閱讀 3268·2019-08-30 12:53
閱讀 2895·2019-08-29 17:11
閱讀 1821·2019-08-29 16:58