This is the fourth day of my participation in the August More text Challenge. For details, see:August is more challenging
Recently I opened a new project to briefly describe my table encapsulation.
Problem analysis
Why encapsulate
First of all, why encapsulate table? Is it because of technology? No, it is because of laziness.
What are the contents of the package
There are two main components, a table component and a paging component
Once you have that figured out, you can start wrapping components.
Encapsulating the Table component
Validate data format
To determine the data format, we need to look at the el-table component
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column fixed="right" label="Operation" width="100">
<template slot-scope="scope">
<el-button @click="handleClick(scope.row)" type="text" size="small">To view</el-button>
<el-button type="text" size="small">The editor</el-button>
</template>
</el-table-column>
</el-table>
Copy the code
Now let’s think about data types like Lebel, prop, widht button types, events, and so on,
let paramsType = {
data: Array./ / data
loading: Boolean.selectionShow: Boolean.columns:Array= [{label: String.prop: String.filter: Function.isSlot: Boolean.width: Number.tempalte: Function.btns: Array= [{name: String.btnType: String.clickType: String.routerType: String.url: String.query: Function.btnClick: Function}]}]}Copy the code
With the number data document defined, we can begin to encapsulate the component
Packaging components
Encapsulating global Components
The reason for wrapping global components is to save trouble, all of it, all of it. Create a components file under SRC and write our components in it. Each component is recommended to have a separate folder for easy maintenance.
Create your own table.vue component. I’ll call it FrTable.
The global use imports the FrTable file into the index.js file under components, where all components are traversed and exported
The code is as follows:
import TrTable from './FrTable/index'
const components = [TrTable]
const install = (Vue) = > {
components.map(component= > {
Vue.component(component.name, component)
})
}
if (typeofWindow ! = ='undefined' && window.Vue) {
install(Window.Vue)
}
export default {
install
}
Copy the code
Then export to main.js and use the component with vue.use (), as shown below
import globalComponents from '@/components/index'
Vue.use(globalComponents)
Copy the code
Use in pages
<fr-table />
Copy the code
Table Component Encapsulation
Questions to consider
How many cases are there in the table,
- Normal data type display
- Unique way to show
- There are operation buttons
For the first type, we don’t really need to do much, we just need to render through the for loop.
The second one is actually fine, we can customize it through slot
Third, the operation of buttons. There are many types of buttons
Type of button
- For normal use of the button, click the function
- The button acts as a jump
- The button opens a new page
- Buttons act as custom events
Code writing
Now that we’ve analyzed all the problems with the table, we just need to type in the code.
Case one
<el-table :data="data" border :loading="loading"> <! - check -- - ><el-table-column v-if="selectionShow" type="selection" width="50" align="center" :reserve-selection="true" />
<template v-for="(item, index) in columns">
<el-table-column :key="index" v-bind="item">
<! -- Custom table header -->
<template v-if="item.customHeader" slot="header">
<slot :name="item.headerProp" />
</template>
<template slot-scope="scope">
<span v-html="handleFilter(item, scope.row, item.prop)" />
</template>
</el-table-column>
</template>
</el-table>
Copy the code
So here we can see the handleFilter method which handles the data,
Data types are classified into normal data types, data types to be converted, and data types to be converted by templates. The codes are as follows
handleFilter(item, val, prop) {
let value = val[prop]
if (item.templet) value = item.templet(val)
return item.filter ? this.$options.filters[item.filter](val[prop]) : value
},
Copy the code
The first case is simple, with simple data rendering and custom header rendering, and the overall top is multiple selections + normal forms
Case two
Custom lists
<template slot-scope="scope"> <! -- Custom content --><slot
v-if="item.isSlot"
:name="item.prop"
:row="scope.row"/
>
</template>
Copy the code
For a custom category, we just need isSlot set to true, name to Prop, and Row to data
The third kind of
The third button is divided into four cases
<template v-if="item.btns">
<el-button
v-for="(btn, i) in item.btns"
:key="i"
class="mr_10"
:size="btn.mini ? btn.mini: 'small'"
:type="btn.type ? btn.type: 'primary'"
@click="btnClickfunc(btn, scope.row)"
>
{{ btn.name }}
</el-button>
</template>
Copy the code
The button is still looped, mainly event analysis, through the btnClickfunc event operation.
btnClickfunc(column, row) {
const path = {
[column.routerType]: column.url,
query: column.query ? column.query(row) : ' '
}
if (column.clickType === 'router') {
this.$router.push(path)
} else if (column.clickType === 'router_blank') {
const routeData = this.$router.resolve(path)
window.open(routeData.href, '_blank')}else if (column.clickType === 'btnClick') {
column.btnClick(row)
} else {
this.$emit('btnClickFunc', { column: column, row: row })
}
},
Copy the code
We do different things for different types.
Props specifies the value of the props parameter
The current parameters are the same as the parameters we defined, so the code is as follows
/ / data
data: {
type: Array.required: true
},
// Header parameters
columns: {
type: Array.required: true
},
loading: {
type: Boolean.default: false
},
// Multi-checkbox selection
selectionShow: {
type: Boolean.default: false
},
Copy the code
From there, all that remains is how the components are used
Use of components
<fr-table
ref="mt"
:loading="loading"
:data="list"
:columns="columns"
>
</fr-table>
Copy the code
Basically, if you need to use multiple choices, define your own method, same with sorting.
Paging Component Encapsulation
Refer to the Element paging component
<el-pagination
style="margin-top:40px;"
background
layout="prev, pager, next"
:page-size="pageLimit"
:total="total"
:current-page="currentPage"
@current-change="handleCurrentChange"
/>
handleCurrentChange(val) {
console.log(val)
}
Copy the code
Data definition
The definition is as follows:
total: Number.pageLimit: Number.currentPage: Number.Copy the code
encapsulation
<el-pagination
style="margin-top:40px;"
background
layout="prev, pager, next"
:page-size="pageLimit"
:total="total"
:current-page="currentPage"
@current-change="handleCurrentChange"
/>
handleCurrentChange(val) {
this.$emit('currentChange', val)
}
Copy the code
If it looks simple, it is.
We then add the paging events and parameters to the component, and our entire table component encapsulation is complete.
The above is all knowledge points, there is insufficient to point out, please also give advice!!