前端須要注意的要點

聊聊公司團隊前端交互須要注意的一些要點。html

  1. 通常上 Tab 切換的頁面都應該經過路由定義,切換選項卡即切換路由,並且要用 replace 而不是 push 切換。
  2. 頁面分頁、側欄分類切換分類等會從新加載列表的操做都要經過路由進行切換。
  3. 連接必須使用 a 標籤+設置 href 屬性聲明跳轉,容許用戶右鍵新選項卡打開,不要經過 click 事件進行跳轉。
  4. 引入外部插件、添加 DOM 事件到 document/body 時,必定要銷燬,不作很容易致使內存泄漏。
  5. 能用框架提供的接口/方法解決就用框架,不要本身另外實現一份。
  6. 頁面/組件的每個狀態都要處理。

組件狀態處理

重點說一下這個,以頁面路由組件爲例子。前端

例如打開一個頁面,狀態大體能夠分爲數據加載中/加載完成/沒有數據三種。框架

在寫每個頁面的時候,都須要針對這 3 種狀態進行顯示 Loading/骨架圖、渲染、空數據提示的處理。異步

另外說一個例子,一個頁面包含多個相互獨立的業務組件(每個業務組件就能夠看成子系統)。async

須要考慮到每個業務組件可能出現的狀態:this

有一些組件比較簡單,直接渲染 UI 就行了;插件

有一些組件較爲複雜,有 Ajax 請求,那麼要考慮到請求中、請求成功、失敗、沒有數據等等狀態;code

有一些組件可能引入了很大的第三方庫(如Echarts),這些第三方庫必須異步加載,這時就須要考慮異步加載第三方庫時的狀態,好比顯示 Loading 之類;htm

其餘諸如屏幕適配也能夠看成狀態的一種,不過屏幕適配通常是在<App />中作,平時不須要太注意。接口

平時開發組件的時候必定要想好到底有多少種狀態,哪些狀態要處理,哪些狀態沒必要處理。

另外說下組件狀態的理解

對比下下面幾種寫法的優劣勢:

<template>
  <div>
    <skeleton v-if="aData.loading && bData.loading && cData.loading"></skeleton>
    <div v-else-if="aData.error || bData.error || cData.error">頁面發生錯誤</div>
    <template v-else>
      <part-a :data="aData.list"></part-a>
      <part-b :data="bData.list"></part-b>
      <part-c :data="cData.list"></part-c>
    </template>
  </div>
</template>
<script>
export default {
  data() {
    return {
      aData: {
        loading: true,
        error: false,
        list: []
      },
      bData: {
        loading: true,
        error: false,
        list: []
      },
      cData: {
        loading: true,
        error: false,
        list: []
      }
    }
  },
  async created() {
    this.loadA();
    this.loadB();
    this.loadC();
  }
};
</script>
<template>
  <div>
    <skeleton v-if="loading"></skeleton>
    <div v-else-if="hasError">頁面發生錯誤</div>
    <template v-else>
      <part-a :data="aData"></part-a>
      <part-b :data="bData"></part-b>
      <part-c :data="cData"></part-c>
    </template>
  </div>
</template>
<script>
export default {
  data() {
    return {
      loading: true,
      hasError: false,
      aData: [],
      bData: [],
      cData: []
    }
  },
  async created() {
    try {
      await Promise.all([this.loadA(), this.loadB(), this.loadC()]);
    }
    catch(err) {
      this.hasError = true;
    }
    finally {
      this.loading = true;
    }
  }
};
</script>
<template>
  <div>
    <skeleton v-if="loading"></skeleton>
    <div v-else-if="hasError">頁面發生錯誤</div>
    <template v-else>
      <part-a :data="aData"></part-a>
      <part-b :data="bData"></part-b>
      <part-c :data="cData"></part-c>
    </template>
  </div>
</template>
<script>
export default {
  data() {
    return {
      aData: {
        loading: true,
        error: false,
        list: []
      },
      bData: {
        loading: true,
        error: false,
        list: []
      },
      cData: {
        loading: true,
        error: false,
        list: []
      }
    }
  },
  computed: {
    loading() {
      return aData.loading && bData.loading && cData.loading;
    },
    hasError() {
      return aData.error || bData.error || cData.error;
    }
  },
  async created() {
    this.loadA();
    this.loadB();
    this.loadC();
  }
};
</script>

其實一個組件能夠看成一個有限狀態機。

而後就能夠把頁面複雜的邏輯問題簡化爲幾個狀態機自身的狀態轉移問題,能夠有效簡化問題又不失靈活,以應對多變的需求。

相關文章
相關標籤/搜索