vue
項目中,組件是項目的基石,每一個頁面都是組件來組裝起來,我司沒有本身的組件庫,選用的是ElementUI
組件庫,在它的基礎上再次封裝。vue
因爲是後臺管理項目,各類單據漫天飛,並且單據列表要可編輯,可驗證,基於業務封裝了可編輯表格組件node
業務需求:webpack
每列可編輯,則須要每列的字段須要一個可編輯的屬性edit
來肯定是否能夠編輯,輸入的值能夠被驗證,須要咱們傳入驗證規則。git
props
props: { // 表格數據 tableData: { type: Array, default: () => [] }, // 須要驗證的列字段 columns: { type: Array, default: () => [] }, // 是否可編輯 defaultEdit: { type: Boolean, default: true }, // 驗證集合 verifyRules: { type: Object, default: () => {} } }
閱讀el-table
源碼,能夠看到,表格組件擁有本身的store
,一些須要通訊的狀態都是它來維護的,咱們也可建立一個自有的table-store.js來維護編輯狀態github
// 初始化數據 this.store = new TableStore({ list: this.tableData, columns: this.columns, defaultEdit: this.defaultEdit });
edit-table-cell
利用slot
插槽來傳遞編輯狀態和驗證規則web
<slot v-else :cellState="cellState" :validateCell="validateCell"></slot> ... computed: { isInput() { return this.slotName === 'input'; }, rowState() { const states = this.editTable.store.states; const rowState = states.get(this.row); return rowState; }, cellState() { const cellState = this.rowState.get(this.prop); return cellState; } }, methods: { // 驗證 validateCell(cb) { this.editTable .verifyTableCell(this.row, this.prop, this.cellState) .then(errMsg => { const valid = !errMsg; typeof cb === 'function' && cb(valid); }); } }
// edit-table.vue <page-edit-table ref="editTable" v-model="tableData" :columns="['categoryName', 'name', 'purchaseDate']" :default-edit="true" :verify-rules="verifyRules" > <el-table ref="table" v-loading="loading" :data="tableData" tooltip-effect="dark" highlight-current-row border stripe style="width: 100%" > <el-table-column align="center" label="序號" width="50"> <template slot-scope="scope">{{ scope.$index + 1 }}</template> </el-table-column> <el-table-column label="品目名稱" prop="categoryName" show-overflow-tooltip> <template slot-scope="{ row }"> <edit-table-cell :row="row" prop="categoryName"> <template slot-scope="{ cellState, validateCell }"> <el-select v-if="cellState.edit" v-model="row.categoryName" clearable placeholder="請選擇品目" @change="validateCell" > <el-option label="你" value="1"></el-option> <el-option label="好" value="2"></el-option> <el-option label="呀" value="3"></el-option> </el-select> <span v-if="!cellState.edit">{{ row.categoryName }}</span> </template> </edit-table-cell> </template> </el-table-column> ....
效果以下vue-cli
具體代碼可查看組件segmentfault
el-tree
樹形組件其實已經支持了自定義節點內容,可是咱們要在它的基礎上改變節點內容,這裏主要是運用了Vue.set
向響應式對象中添加一個屬性。app
// 部分代碼 append(node, data) { const { label } = this.configProps; const newChild = { id: id++, [label]: `三級-${id}`, children: [], isEdit: false }; if (!data.children) { this.$set(data, 'children', []); } data.children.push(newChild); this.$emit('addNode', node, data); }, edit(node, data) { if (!node.isEdit) { this.$set(node, 'isEdit', true); } this.$nextTick(() => { this.$refs[`treeInput${node.id}`].focus(); }); this.$emit('editNode', node, data); }
效果以下:優化
組件是項目的積木條,公用組件的封裝成功與否實際上是對項目的開發效率有直接影響。具體代碼可查看vue-template,基於vue-cli3.0
搭建的後臺模版。
參考: