圍觀,聽說你用Vue寫H5項目了?

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


1、按需引入

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

import { Slider } from 'element-ui';

Vue.use(Slider);

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

2、全局樣式抽離

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

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

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

import 'assets/css/main.css';

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>

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

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

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

4、緩存

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

<template>
    <div class="page">
         <keep-alive>
            <router-view class="page-content"></router-view>
        </keep-alive>
    </div>
</template>

在上一節的基礎上,加上這個組件包裹它就行了。原理就是它會緩存不活動的組件,而不是銷燬它。詳情可以參見 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);

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

6、不同組件間通信

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

// inner.js
import Vue from 'vue';

const bus = new Vue();

export {bus};

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

import {bus} from 'common/utils/inner';

bus.$on('my_event', (bool) => {
    // TODO
});

廣播事件:

import {bus} from 'common/utils/inner';

 bus.$emit('my_event', {}); 

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

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";
});

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

8、禁止頁面被拖動

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

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

對於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;
    }
};

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

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

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

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

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

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

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

this.$refs.myRef.fun(); 

這樣就不用去傳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;
    }
}

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

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

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

12、動畫效果

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

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

像這樣寫樣式就可以了。

13、表格

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


巨坑啊,


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


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

 [
  {
    id: -1,
    children: [
        {
            id: -1.1,
        }
    ]
  },
  {
    id: 2,
  }
 ]

換成這樣:

[
 {
   id: -1,
 },
 {
   id: -1.1,
 }{
   id: 2,
 }
]

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

最後

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

發佈了41 篇原創文章 · 獲贊 16 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章