Vue後臺系統中如何優雅的書寫狀態標籤

前言

在後臺系統開發中,對於列表,經常有一些狀態字段的展現,好比審覈狀態、退貨申請狀態等等,而且每每伴隨有狀態篩選的列表查詢條件,同時狀態顯示對應不一樣顏色,在寫代碼時有些人每每是這麼作的:javascript

<template>
  <el-form :model="query">
    <el-form-item label="審批狀態" prop="status">
      <el-select v-model="query.status" clearable>
        <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
    </el-form-item>
    <el-form-item>
      <el-button type="primary">查詢</el-button>
      <el-button type="danger">重置</el-button>
    </el-form-item>
  </el-form>
  <el-table :data="list">
    <el-table-column label="審批狀態">
      <template #default="{ row }">
        <el-tag v-if="row.status === 0" type="primary">審覈中</el-tag>
        <el-tag v-if="row.status === 1" type="success">審覈成功</el-tag>
        <el-tag v-if="row.status === 2" type="danger">審覈失敗</el-tag>
      </template>
    </el-table-column>
  </el-table>
</template>
複製代碼
export default {
  data() {
    return {
      query: {
          status: null
      },
      statusOptions: [
          { label: '審覈中', value: 0 },
          { label: '審覈成功', value: 1 },
          { label: '審覈失敗', value: 2 }
      ],
      list: []
    }
  }
}
複製代碼

以上代碼雖然是實現了需求,但卻顯得不夠優雅,代碼維護成本較高:html

  • 標籤裏充斥着較多的 v-if 且與 data 裏的數據重複,形成冗餘。
  • 當有新增或修改時,須要改動多個地方,例如要改動文案時下拉框和表格裏的都要改。
  • 若是是多個頁面都有該狀態須要顯示,複製粘貼,最後當需求變更時勢必會增長改動成本。

優化

針對上面的問題,我們經過如下措施來進行搶救。vue

抽離變量

創建常量文件存放 statusOptions,增長 el-tag 組件的 type 字段來區分顯示不一樣的顏色,最後將其導出。java

// const/index.js
// 審覈狀態
const statusOptions = [
  { label: '審覈中', value: 0, type: 'primary' },
  { label: '審覈成功', value: 1, type: 'success' },
  { label: '審覈失敗', value: 2, type: 'danger' }
]

export {
  statusOptions
}
複製代碼

二次封裝 el-tag 組件

// components/stats-tag.vue
<template>
  <el-tag :type="getValue('type')">
    {{ getValue('label') }}
  </el-tag>
</template>
複製代碼
export default {
  name: 'StatusTag',
  
  props: {
    options: {
      type: Array,
      required: true,
      default: () => []
    },
    status: {
      type: [String, Number],
      required: true
    }
  },
  
  computed: {
    getValue({ options, status }) {
      return (key) => {
        const item = options.find(e => e.value === status)
        return (item && item[key]) || ''
      }
    }
  }
}
複製代碼

使用

<template>
  <el-form :model="query">
    <el-form-item label="審批狀態" prop="status">
      <el-select v-model="query.status" clearable>
        <el-option v-for="item in statusOptions" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
    </el-form-item>
    <el-form-item>
      <el-button type="primary">查詢</el-button>
      <el-button type="danger">重置</el-button>
    </el-form-item>
  </el-form>
  <el-table :data="list">
    <el-table-column label="審批狀態">
      <template #default="{ row }">
        <!-- 使用 -->
        <status-tag :options="statusOptions" :status="row.status" />
      </template>
    </el-table-column>
  </el-table>
</template>
複製代碼
import StatusTag from '@/components/status-tag'
// 導入
import { statusOptions } from '@/const'

export default {
  components: {
    StatusTag
  },
  
  data() {
    return {
      statusOptions
    }
  }
}
複製代碼

通過優化後,若是有修改變更,只須要改動 const/index.js 文件便可,無需處處修。markdown

// const/index.js
// 審覈狀態
const statusOptions = [
  { label: '審覈中', value: 0, type: 'primary' },
  { label: '審覈成功', value: 1, type: 'success' },
  { label: '審覈失敗', value: 2, type: 'danger' },
  // 增長取消狀態
  { label: '審覈取消', value: 3, type: 'warning' }
]

export {
  statusOptions
}
複製代碼

感謝

本次分享到這裏就結束了,感謝你的閱讀,若是本文對你有什麼幫助,別忘了動動手指點個贊❤️。app

本文若是有什麼錯誤或不足,歡迎評論區指正、交流。post

近期文章優化

【原生組件】一文帶你入門 Web Componentsui

在 Vue 裏如何優雅的清除一個定時器?url

尤大大新活 petite-vue 嚐鮮

一份 ElementUI 問題清單

相關文章
相關標籤/搜索