Vue寫了一個H5項目,來看下我踩坑記錄吧。


轉載  https://blog.csdn.net/kingbox000/article/details/103993233  

沒錯,我用Vue寫了一個H5項目,來看下我踩坑記錄吧。


1、按需引入

在開發過程中,會遇到很多五花八門的庫。其實這些庫中有很多功能/模塊是用不到的,所以,這里推薦按需引入:

import { Slider } from 'element-ui'; Vue.use(Slider); 
  • 1
  • 2
  • 3

像這樣,如果只用到滑條,只需引入Slider,並掛載到Vue實例。

2、全局樣式抽離

Css樣式在前端開發中是繞不開的話題,以Vue開發為例,每個.vue文件都有自己的局部樣式scoped,但是全局性的樣式可以抽離到一個統一的文件(main.css),大概有以下四種情況:

  • 項目中的特有顏色(其他類比),它會在不同的地方出現
  • 全局的組件樣式,比如對滾動條顏色的控制
  • 對一些引用的公共組件的定制化樣式
  • 單個維度的樣式,比如.fl{ float: left }

然后樣式文件在項目入口引入:

import 'assets/css/main.css'; 
  • 1

3、統一的頁面入口

用Vue開發的話,如果配置好路由,其實頁面之間大可以獨立運行。但是項目越來越復雜,交互越多,就更需要一個統一的入口,這樣可以統一控制事件監聽、處理公共組件(比如Toast)等等。所以,咱們需要一個App.vue,代碼如下:

<template> <div class="page"> <router-view class="page-content"></router-view> </div> </template> <script> export default { name: 'app', data(){ return { // TODO }; }, }; </script> <style lang="scss" scoped> </style> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

然后,在Vue實例化的時候把它作為選項傳入:

import App from 'modules/App.vue'; new Vue({ router, ...App }).$mount(`#app-wrapper`); 
  • 1
  • 2
  • 3
  • 4
  • 5

最后,頁面的跳轉都會在App.vue內,一切盡在掌握。

4、緩存

聽到業務需求說要做持久化我是懵逼的,不過后來理解他們的意思就是做個緩存,那就簡單了,哈哈。Vue有提供keep-alive組件:

<template> <div class="page"> <keep-alive> <router-view class="page-content"></router-view> </keep-alive> </div> </template> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在上一節的基礎上,加上這個組件包裹它就行了。原理就是它會緩存不活動的組件,而不是銷毀它。詳情可以參見 keep-alive api,官方有詳細的解釋。

5、監聽移動設備的橫屏事件

如果是用RN開發,可以調用接口來監聽橫屏事件,H5的話,Js有沒有接口可以給你調用,但是可以監聽事件,通過監聽orientationchange事件,可以監聽橫屏動作,然后通過Orientation來獲取當前角度:

window.addEventListener( "orientationchange", () => { let angle = window.orientation; if(angle % 180 != 0){ // TODO } else { // TODO } // TODO }, false); 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

根據上一節說的App.vue,這個監聽事件就可以放在其中,然后向其他組件廣播。

6、不同組件間通信

那么,如何向其他組件廣播?如果是父子,子父這種的,都好說。但是,如果是多層級的組件間通信就不好處理了,這里推薦一種網上廣為流傳的方法,借用Vue實例,把它作為中間方,在各組件中注冊或者監聽事件。直接看代碼:

// inner.js import Vue from 'vue'; const bus = new Vue(); export {bus}; 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在inner.js中,new 一個Vue實例,然后,可以這樣監聽事件:

import {bus} from 'common/utils/inner'; bus.$on('my_event', (bool) => { // TODO }); 
  • 1
  • 2
  • 3
  • 4
  • 5

廣播事件:

import {bus} from 'common/utils/inner'; bus.$emit('my_event', {}); 
  • 1
  • 2
  • 3

這樣一來,就不用管什么層級關系了,都是廣播的對象。

7、簡單實現Dom拖動

如果不想引用其他庫的話,可以自己實現一個移動的Dom,原理就是監聽touchmove事件,然后改變它的top/left值:

document.getElementById("toolbar").addEventListener('touchmove', (e) => { e.stopPropagation(); e.preventDefault(); let y = e.touches[0].clientY; let height = window.screen.height; if(y > height) { y = height; } else if (y < 0) { y = 0; } document.getElementById("toolbar").style.top = y + "px"; }); 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

不依賴任何插件,達到手指拖動toolbar的效果(這里只是讓toolbar在Y軸上拖動,所以只改了它的top值)。注意要把冒泡和默認事件禁止掉,不然會影響其他模塊。

8、禁止頁面被拖動

H5開發會有很多問題,有些時候客戶想拖動的只是某個區域,但是整個頁面都會隨之拖動,那就把它禁了吧,很簡單:

document.getElementById("page").addEventListener('touchmove', function(e) { e.preventDefault(); }, {passive: false}); 
  • 1
  • 2
  • 3

對於Vue頁面來說,把它的頂部Dom禁掉就可以了,這樣頁面就不會有拖動的效果。

9、Ios設備下的特定樣式

通常,H5開發都會遇到適配問題,特別是Iphone下,同一套樣式Iphone和安卓下效果的就是會有區別。所以,我們需要判斷Iphone,並給它配置特定樣式,代碼如下:

const isIos = () => { var ua = navigator.userAgent.toLowerCase(); if (/iphone|ipad|ipod/g.test(ua)) { return true; } else { return false; } }; 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其實原理就是通過UserAgent去判斷這個設備是否是Ios設備,如果是,就把相應的樣式引用進來,如下:

if(isIos()) { //是ios系統 require('assets/css/ios.scss'); } 
  • 1
  • 2
  • 3

這樣就能達到根據設備配置指定樣式。

10、調用引用組件的內部方法

在Vue項目已經組件化之后,經常會面臨一個很常見的問題,調用組件的內部方法。其實很簡單,通過Ref就可以實現:

<my-comp ref="myRef"> </my-comp> 
  • 1

在給引用的組件加上ref之后,在代碼中去調用就行了。

this.$refs.myRef.fun(); 
  • 1

這樣就不用去傳Props觸發了。

11、下載文件

這個功能其實涉及到前后端的配合,如果你想下載一個文件,首先需要這個文件存在,或者是先生成,然后再獲取路徑下載。這是比較常規的方式了。以Excel文件為例,后台要根據業務生成Excel文件:

static async createDownloadFile(data) { try { let xls = json2xls(data); let fileName = `file.xlsx`; await fs.writeFileSync(`./dist/${fileName}`, xls, 'binary'); return fileName; } catch (err) { logger.error(`createDownloadFile error is : ${err && err.message || ''}`); return; } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

nodejs實現一個Excel文件下載就是這樣,把文件放到服務器指定目錄,將文件名稱返回到前端,前端去下載。

    <a :href="downloadUri" download >保存到本地</a> 
  • 1

downloadUri就是拼接好的文件路徑,然后別忘記加上download屬性,這個屬性在移動端大部分瀏覽器內核是支持的,但是,IE瀏覽器不支持(Safari瀏覽器也不支持,但是實測是可以下載的),沒關系,它是移動端,哈哈。

12、動畫效果

有些時候,整個項目交互沒有點動畫過渡會顯的很沉重,所以,還是加點動畫吧。手寫嗎?我知道要定義keyframes,然后設置animation之類的,但是這個東西我還是推薦使用一個庫: animation. 非常輕量,就是一個css文件。使用的時候也很簡單:

    <div class="animated fadeOutDown" > </div> 
  • 1

像這樣寫樣式就可以了。

13、表格

什么,要加表格?還是可以固定列,自定義的那種?我反手就是Element-ui表格,哈哈,完成。


巨坑啊,


Element-ui並不適合在移動端用,前期適配完之后,發現非常卡頓,最后發現是它的數據結構的問題,可折疊表格的數據結構就是子母嵌套的,數據量一上來,渲染過程就會頁面卡死。不推薦。


這里推薦一個小眾的組件: vue-easytable,功能都有主要是不卡,然后,把數據結構換成平級的,層級用樣式實現。大概就是這個意思:

 [ { id: -1, children: [ { id: -1.1, } ] }, { id: 2, } ] 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

換成這樣:

[ { id: -1, }, { id: -1.1, }, { id: 2, } ] 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

通過自定義屬性來設置樣式,達到不同層級縮進效果。

最后

今天我看到魷魚須在VueConf的演講了,Vue3.0用的是Typescript寫的,想想微軟還是強大,這種類Java的語言也能被他搞的這么火,嚇得我趕緊去看下Typescript。前端變化真快~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM