04-前端基礎平臺搭建宣導材料
阿新 • • 發佈:2022-04-03
1.為什麼要封裝前端頁面及元件?
元件封裝平臺 VS 未封裝業務頁面 == 用一個印表機完成各種花式的列印 VS 每種花樣一臺印表機
單業務頁面開發優缺點分析:
- 優點:
1.根據具體頁面具體設計 ;
2.新的頁面能快速開發; - 缺點:
1.頁面通用性差
2.同一個基礎元件重複使用時,頁面冗餘,程式碼冗餘
3.當某一個元件需要調整時,所有使用過的地方都要進行替換調整
4.新人接手專案,無從下手,程式碼和功能可擴充套件性差
5.通用業務,基礎業務處理不好
元件封裝及基礎平臺搭建 優缺點分析:
-
優點:
1.一處封裝處處使用
2.不針對具體業務,只針對特定頁面模組元件
3.使用靈活,程式碼量少
4.通用頁面開發快速,開發門檻較低
5.可擴充套件性強,後續維護方便,結構嚴謹
6.可配置化,也意味著後續視覺化設計頁面
7.開發需要由原先的業務頁面開發轉變成,模組元件的設計者角色 -
缺點:
1.複雜元件封裝邏輯複雜,需要有良好的業務剝離能力
2.對新手閱讀程式碼能力有要求
程式碼比對
封裝元件後的頁面程式碼
- 頁面部分(部分封裝,還未封裝完畢)
<hs-list-page :pageInfo="pageInfo"/> <!-- 查詢區域 -->
<printer-list-modal ref="modalForm" @ok="modalFormOk">
</printer-list-modal>
展開檢視
this.pageInfo = { search: { defaultBtns: [{ type: 'reset' }, { type: 'reload' }], searchArea: { conditions: [{ name: '狀態', //展示標題名稱 prop:'purchaseTypeList', display:'row',//展示行列樣式 component:'hs-radio-div',//元件名稱 datas: that.statusObj },{ name:'印表機品牌',//展示標題名稱 prop:'brandName', span:3, //佔用的span數 component:'hs-input',//元件名稱 },{name:'印表機型號',//展示標題名稱 prop:'brandType', component:'hs-input',//元件名稱 },{ name:'機器編號', component:'hs-input', prop:'machineNumber', },{name:'主機板ID', prop:'mainboardId', component:'hs-input' },{name:'噴頭型別', prop:'printheadType', component:'hs-input' },{ name:"入庫時間",// span:6, component:'hs-date-picker', startProp:'createTimeStart', //起始日期屬性 endProp:'createTimeEnd',//結束日期屬性 format:'YYYY-MM-DD HH:mm:ss',//格式化規則 },{name:"出貨時間",// span:6, component:'hs-date-picker', startProp:'shippingTimeStart', //起始日期屬性 endProp:'shippingTimeEnd',//結束日期屬性 format:'YYYY-MM-DD HH:mm:ss',//格式化規則 } ], } , queryParam:{ purchaseTypeList:[1,2,3] } }, btns:[], table:{ tableInfo:{ columns: [{ title: '#', dataIndex: '', key: 'rowIndex', width: 60, align: "center", customRender: function(t, r, index) { return parseInt(index) + 1; } }, { title: '購機客戶', align: "center", dataIndex: 'custName' }, { title: '印表機品牌', align: "center", dataIndex: 'brandName' }, { title: '印表機型號', align: "center", dataIndex: 'brandType' }, { title: '機器編號', align: "center", dataIndex: 'machineNumber' }, { title: '主機板ID', align: "center", dataIndex: 'mainboardId' }, { title: '噴車板晶片ID', align: "center", dataIndex: 'sprayPlateChipId' }, { title: '噴頭型別', align: "center", dataIndex: 'printheadType' }, { title: '噴頭ID', align: "center", dataIndex: 'nozzleId', scopedSlots: { customRender: 'nozzleId' } }, { title: '狀態', align: "center", dataIndex: 'purchaseType', }, { title: '入庫時間', align: "center", dataIndex: 'createTime', }, { title: '出貨時間', align: "center", dataIndex: 'shippingTime', }, { title: '操作', dataIndex: 'action', align: "center", fixed: "right", width: 147, scopedSlots: { customRender: 'action' } }], colProperty: [{ prop: "purchaseType", // 對應列的dataIndex component:'hs-text-select', //table的文字多選元件名稱 options:[ //選擇框的選項 { name:"未出售", value:1 }, { name:"代售中", value:2, style:{ color:"#18bc9c" } }, { name:"已出售", value:3, style:{ color:"#e74c3c" } } ] }, {prop:"action", component:'hs-table-button', btns:[ { name:"檢視", has:"M070402", click: record => that.handleDetail(record) } ] } ] }, initDatas:{ url:'outOrder/outbound', resData:'outBoundList' } } }
原始具體頁面程式碼
- 頁面部分
<a-card :bordered="false" style="min-height:814px"> <!-- <hs-list-page :pageInfo="pageInfo"/> --> <!-- 查詢區域 --> <div class="table-page-search-wrapper"> <a-form layout="inline" class="searchBox"> <a-row :gutter="48"> <a-col :md="24" :sm="24"> <a-form-item label="狀態"> <div class="statusBtn" @click="changeStatus(item.value)" :class=" {active:currentSeleted==item.value}" v-for="(item,index) in statusObj" :key="index"> {{item.name}} </div> </a-form-item> </a-col> </a-row> <a-row :gutter="48"> <a-col :md="8" :sm="24"> <a-form-item label="印表機品牌"> <a-input v-model.trim="queryParam.brandName" placeholder="印表機品 牌" /> </a-form-item> </a-col> <a-col :md="8" :sm="24"> <a-form-item label="印表機型號"> <a-input v-model.trim="queryParam.brandType" placeholder="印表機型 號" /> </a-form-item> </a-col> <template v-if="advanced"> <a-col :md="8" :sm="24"> <a-form-item label="機器編號"> <a-input v-model.trim="queryParam.machineNumber" placeholder="機 器編號" style="width: 100%" /> </a-form-item> </a-col> <a-col :md="8" :sm="24"> <a-form-item label="主機板ID"> <a-input v-model.trim="queryParam.mainboardId" placeholder="主機板 ID" style="width: 100%" /> </a-form-item> </a-col> <a-col :md="8" :sm="24"> <a-form-item label="噴頭型別"> <a-input v-model.trim="queryParam.printheadType" placeholder="噴 頭型別" style="width: 100%" /> </a-form-item> </a-col> <a-col :md="8" :sm="24"> <a-form-item label="入庫時間"> <div> <a-date-picker v-model="startValue" :disabled-date="disabledStartDate" format="YYYY-MM-DD" placeholder="請選擇開始時間" @openchange="handleStartOpenChange" class="timeBox" :class="{nonePadding:startValue}" /> <a-date-picker v-model="endValue" :disabled-date="disabledEndDate" format="YYYY-MM-DD" placeholder="請選擇結束時間" :open="endOpen" @openchange="handleEndOpenChange" class="timeBox end" :class="{nonePadding:endValue}" /> </div> </a-form-item> </a-col> <a-col :md="8" :sm="24"> <a-form-item label="出貨時間"> <!-- <a-form-item > --> <!-- <label slot="label">出 貨 時 間</label> --> <div> <a-date-picker v-model="startValue1" :disabled-date="disabledStartDate1" format="YYYY-MM-DD" placeholder="請選擇開始時間" @openchange="handleStartOpenChange1" class="timeBox" :class="{nonePadding:startValue1}" /> <a-date-picker v-model="endValue1" :disabled-date="disabledEndDate1" format="YYYY-MM-DD" placeholder="請選擇結束時間" :open="endOpen1" @openchange="handleEndOpenChange1" class="timeBox end" :class="{nonePadding:endValue1}" /> </div> </a-form-item> </a-col> </template> <a-col :md="!advanced && 8 || 24" :sm="24" class="hasRight"> <span class="table-page-search-submitButtons" :style="advanced && { float: 'right', overflow: 'hidden' } || {} "> <a-button type="primary" @click="onSubmit"> 查詢 </a-button> <a-button style="margin-left: 8px" @click="resetSearchForm"> 重置 </a-button> <a @click="toggleAdvanced" style="margin-left: 8px"> {{ advanced ? '收起' : '展開' }} <a-icon :type="advanced ? 'up' : 'down'" /> </a> </span> </a-col> </a-row> </a-form> </div> <!-- 查詢區域-END --> <!-- 操作按鈕區域 --> <div class="table-operator"> <!-- <a-button @click="handleAdd" type="primary" icon="plus" v- has="'M030201'">印表機入庫</a-button> --> </div> <!-- table區域-begin --> <div class="tb1"> <a-table ref="table" size="middle" :scroll="{x:true}" bordered="" :rowkey="(record,index)=>{return index}" :columns="columns" :datasource="dataSource" :pagination="ipagination" :loading="loading" class="j-table-force-nowrap" @change="handleTableChange"> <div slot="nozzleId" slot-scope="text"> <a-popover title="噴頭ID" v-if="text.length>9"> <template slot="content"> <p>{{text}}</p> </template> <div> {{text.substr(0,8)+'...'}} </div> </a-popover> <span v-else="">{{text}}</span> </div> <template slot="htmlSlot" slot-scope="text"> <div v-html="text"></div> </template> <template slot="purchaseType" slot-scope="text"> <div v-if="text==1"> 已入庫 </div> <div v-if="text==2" style="color:#18bc9c"> 待出貨 </div> <div v-if="text==3" style="color:#e74c3c"> 已出貨 </div> </template> <span slot="action" slot-scope="text, record"> <a @click="handleDetail(record)" v-has="'M070402'">檢視</a> </span> </a-table> </div> <printer-list-modal ref="modalForm" @ok="modalFormOk"></printer-list-modal> </a-card>
- 程式碼部分冗餘也是很多,而且很多都是重複的程式碼
2.釐清幾個概念
2.1 頁面構成
- 結構:先劃分左右,在進行上下進行組合
- 頁面可以拆成幾個大的模組,每個模組又能拆分成更小的模組
封裝做的是什麼?
把最小的模組,按照業務組成一個區域模組在把區域模組,根據頁面的構成佈局組成
2.2 元件的概念
3.通用業務元件的擴充套件性和低耦合性表現
1.通用基礎元件1.0
- 基礎元件進行封裝,減少重複程式碼
- 原有日期元件,及日期範圍選擇控制
<a-date-picker
v-model="startValue"
:disabled-date="disabledStartDate"
format="YYYY-MM-DD"
placeholder="請選擇開始時間"
@openChange="handleStartOpenChange"
class="timeBox"
:class="{nonePadding:startValue}" />
<a-date-picker v-model="endValue"
:disabled-date="disabledEndDate"
format="YYYY-MM-DD" placeholder="請選擇結束時間"
:open="endOpen"
@openChange="handleEndOpenChange"
class="timeBox end"
:class="{nonePadding:endValue}" />
- 程式碼部分
展開檢視
- 封裝後基礎業務元件
<hs-date-picker :form.sync="queryParam" :item="hsDatePick" />
<script>
hsDatePick:{
startProp:'startOrderTime', //起始日期屬性
endProp:'endOrderTime',//結束日期屬性
format:'YYYY-MM-DD HH:mm:ss',//格式化規則
},
</script>
- 對比的優勢
1.同一個頁面多次使用,只需要配置json,基礎元件的相關方法都不需要額外增加
2.頁面更加簡潔,冗餘程式碼比較少,不需要考慮通用基礎元件處理
2.通用業務元件2.0
- 原有頁面程式碼
<div class="table-page-search-wrapper">
<a-form layout="inline" class="searchBox">
<!-- <a-form layout="inline" class="searchBox" labelAlign="left"> -->
<a-row :gutter="48">
<a-col :md="24" :sm="24">
<a-form-item label="訂單狀態">
<div class="statusBtn" @click="changeStatus(item.value)" :class=" {active:currentSeleted==item.value}" v-for="(item,index) in statusObj" :key="index">{{item.name}}</div>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="48">
<a-col :md="5" :sm="24">
<a-form-item label="業務">
<a-select allowClear v-model="queryParam.salesmanName" placeholder="請選擇">
<a-select-option :value="item.id" v-for="(item, index) in personList" :key="index">{{item.userName}}</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md="5" :sm="24">
<a-form-item label="跟單">
<a-select allowClear v-model="queryParam.merchandiserName" placeholder="請選擇">
<a-select-option :value="item.id" v-for="(item, index) in personList" :key="index">{{item.userName}}</a-select-option>
</a-select>
</a-form-item>
</a-col>
<!-- <a-col :md="10" :sm="24" > <a-form-item label="下單日期" class="moreWidth"> <hs-date-picker :form.sync="queryParam" :item="hsDatePick" /> </a-form-item> </a-col> -->
<a-col :md="10" :sm="24">
<a-form-item label="下單日期" class="moreWidth">
<div><a-date-picker v-model="queryParam.startOrderTime" :disabled-date="disabledStartDate" format="YYYY-MM-DD" placeholder="請選擇開始日期" @openChange="handleStartOpenChange" class="timeBox" :class="{nonePadding:queryParam.startOrderTime}" /><a-date-picker v-model="queryParam.endOrderTime" :disabled-date="disabledEndDate" format="YYYY-MM-DD" placeholder="請選擇結束日期" :open="endOpen" @openChange="handleEndOpenChange" class="timeBox end" :class="{nonePadding:queryParam.endOrderTime}" />
</div>
</a-form-item>
</a-col>
<a-col :md="4" :sm="24" class="hasRight">
<span class="table-page-search-submitButtons" :style="advanced && { float: 'right', overflow: 'hidden' } || {} "> <a-button type="primary" @click="onSubmit">查詢</a-button> <a-button style="margin-left: 8px" @click="resetSearchForm">重置 </a-button> </span>
</a-col>
</a-row>
</a-form>
</div>
- 封裝後代碼
<hs-search-row-conditions :rowConditions="rowConditions" :form="form" />
<script>
searchArea: {
conditions: [{
name: '狀態', //展示標題名稱
prop: 'purchaseTypeList',
display: 'row', //展示行列樣式
component: 'hs-radio-div', //元件名稱
datas: that.statusObj,
}, {
name: '印表機品牌', //展示標題名稱
prop: 'brandName',
span: 3, //佔用的span數
component: 'hs-input', //元件名稱
}, {
name: '印表機型號', //展示標題名稱
prop: 'brandType',
component: 'hs-input', //元件名稱
}, {
name: '機器編號',
component: 'hs-input',
prop: 'machineNumber',
}, {
name: '主機板ID',
prop: 'mainboardId',
component: 'hs-input',
}, {
name: '噴頭型別',
prop: 'printheadType',
component: 'hs-input',
}, {
name: "入庫時間", //
span: 6,
component: 'hs-date-picker',
startProp: 'createTimeStart', //起始日期屬性
endProp: 'createTimeEnd', //結束日期屬性
format: 'YYYY-MM-DD HH:mm:ss', //格式化規則
}, {
name: "出貨時間", //
span: 6,
component: 'hs-date-picker',
startProp: 'shippingTimeStart', //起始日期屬性
endProp: 'shippingTimeEnd', //結束日期屬性
format: 'YYYY-MM-DD HH:mm:ss', //格式化規則
}],
}
</script>
- 對比優勢:
1.不需要寫任何基礎元件程式碼
2.需要增刪元件只需要對JSON中的配置項進行刪減
3.通用業務頁面元件3.0
- 對比就是剛開始講的兩個頁面對比優勢:
1.封裝後的通用業務頁面,全部是json配置而成
2.頁面程式碼幾乎為0,開發成本很低
3.頁面開發門檻降低,只要知道配置規則,稍微知道前端知識就能配置頁面
4.提高了開發效率
4.通用業務頁面4.0
- json 資料儲存資料庫
- 通用業務頁面不需要進行寫程式碼,通過頁面配置實現
- 減少業務重複程式碼開發,部分個性化開發提供介面,可直接在系統進行開發
- 秉持的理念是:設計與渲染分離
4.1通用列表頁面
4.2通用表單配置
- 通過拖動實現頁面設計
5.通用業務基礎平臺5.0
基本點:
前後端通用化,頁面可配置,後端增刪改查介面的通用化
後端通用介面提供插槽,特殊業務通過插槽進行處理,通用業務通用處理降低基礎頁面的前後端開發,後端介面封裝要求對業務剝離度要高
後端必要時引入現有設計類後端元件。
4基礎業務平臺搭建的好處
4.1統一性
- 前端頁面樣式統一後端介面統一
- 程式碼冗餘少
4.2減少重複開發
- 後端增刪改查介面減少,可以有更多時間處理核心業務
- 前端基礎頁面減少,重點是複雜頁面,和通用頁面業務元件開發
4.3提高專案開發速度
- 可以通過基礎業務平臺,快速搭建起新系統
- 新系統的基礎功能轉移更加便捷,轉移相關資料庫配置就能完成,較少考慮程式碼影響
4.4提高系統可擴充套件性
- 剝離具體業務,提高系統的整體可擴充套件性
檔案路徑:https://files.cnblogs.com/files/perferect/基礎元件平臺封裝宣導.rar?t=1648543032