什麼樣的內容需要封裝
一段代碼在項目中出現兩次就開始考慮是否應該進行封裝,出現三次就肯定要封裝,大到一個頁面,一個組件,小到一個function和一個css樣式。
封裝原則
以下將封裝出來的通用組件叫做子組件,引用通用組件的界面叫做父組件。
封裝出來的組件必須具有高性能,低耦合的特性,主要從以下幾點入手:
1.數據從父組件傳入
子組件本身不要生成數據,如果需要生成數據,只能在組件內部進行使用,不要傳遞出去。
父組件使用props對子組件進行傳參:
// 父組件向子組件傳值
props: {
// 表格顯示的數據
tableData: {
type: Array,
default: function() {
return [];
}
},
// 表格的操作
tableOption: {
type: Array,
default: function() {
return [];
}
},
// 控制操作列是否顯示
isOperate: {
type: Boolean,
default: function() {
return false;
}
}
}
對於通過props傳入的參數,不建議對其進行操作,因爲會同時修改父組件裏面的數據(如果修改的話,控制檯中也會報錯的),如果需要修改數據,可以傳遞給父組件,讓父組件去修改(在父組件中處理事件)。
2.在父組件中處理事件
父組件中處理的事件是和後端交互的事件,比如發起的axios的請求,但並不是所有的事件都放到父組件中處理,比如組件內部的一些交互行爲,或者處理的數據只在組件內部傳遞,就可以在子組件中處理。
// 子組件中
changeApproval(id) {
this.$emit("pushId", id);
}
// 父組件中
<common-dialog @pushId="getId"></common-dialog>
getId(id) {
this.approvalForm.approval = id;
}
3.記得留一個slot
一個通用的組件,往往不能完美的適應所有的應用場景,所以在封裝組件的時候,只需要完成組件的80%的功能,剩下的20%讓父組件通過slot解決。
<!-- 子組件 表格操作列 並不能確定表格是否有操作列,且也不能確定操作列都有什麼按鈕 -->
<el-table-column label="操作" v-if="isOperate" min-width="150px">
<template slot-scope="scope">
<slot name="operate" :row="scope.row"></slot>
</template>
</el-table-column>
!-- 父組件 填充表格操作列 -->
<common-table :tableData="tableData" :tableOption.sync="tableOption" :isOperate="isOperate">
<!-- 操作列,填充operate的插槽 -->
<template slot="operate" slot-scope="scope">
<!-- 具體要顯示的按鈕可以在這裏自定義 -->
<el-button type="primary" size="mini">查看</el-button>
</template>
</common-table>
知識點補充:什麼是slot?
slot是一個插槽,用於分發內容。相當於我在餐廳(子組件)給你佔了一個位置,上面寫上operate,那你來這裏喫飯,如果你是operate,你就可以坐在這個位置上,如果你不是,你就不能坐在這個位置上。
簡單說就是把父組件中的內容放到對應的插槽的位置上
4.不要依賴vuex
如果要抽離組件儘量不要使用vuex來實現參數的傳遞,因爲vuex是用來管理組件狀態的,雖然可以用來傳參,但是不推薦,可以選擇放到localstorage中,或者通過props傳遞等方式。
5.合理使用scoped
樣式中添加scoped可以讓樣式只對當前組件生效,但是一味使用scoped,會產生重複代碼,所以需要有一個全局的樣式,組件內只寫針對於組件的樣式,避免重複的樣式代碼。
6.組件具有單一職責
封裝業務組件或者基礎組件,如果不能給這個組件起一個有意義的名字,證明這個組件承擔的職責可能不夠單一,需要繼續抽組件,直到它可以是一個獨立的組件即可。
封裝成果
爲了適應項目的需求,對ElementUI表格進行了二次封裝,具體鏈接可點擊: