vue. js management method of background table component encapsulation

  • 2021-11-10 08:35:53
  • OfStack

Directory problem analysis
Why encapsulate
What are the encapsulated contents
Encapsulate table components
Confirm data format
Packaging component
Encapsulate global components
table component encapsulation
Paging component encapsulation
Data definition
Encapsulation
Summarize

Recently, I opened a new project and briefly described my own table package.

Problem analysis

Why encapsulate

First of all, why is it encapsulated because of the pursuit of technology? No, it is lazy and doesn't want to paste and copy the code straight, so I want to encapsulate table. When creating a new table, I only need to fill in the data.

What are the encapsulated contents

There are two main components, one is the table component and the other is the paging component

Knowing this, you can start packaging components.

Encapsulate table components

Confirm data format

First determine the data format, which 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"> View </el-button>
        <el-button type="text" size="small"> Edit </el-button>
     </template>
   </el-table-column>
</el-table>

Now let's consider data types such as 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
        }
      ]
    }
  ] 
}

After defining the number data document, we can begin to encapsulate the component

Packaging component

Encapsulate global components

The reason why the global components are encapsulated is to save trouble, and all the purposes are to be lazy.

src under the creation of components file, which writes our components, each component recommended a separate folder, easy for us to maintain.

Create your own table. vue component, my name is FrTable, content for the time being, first said the reference.

Global usage

Import FrTable file to index. js file under components, traverse all components here, and export

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 (typeof Window !== 'undefined' && window.Vue) {
  install(Window.Vue)
}

export default {
  install
}

Then export to main. js and use the component through Vue. use (), as follows


import globalComponents from '@/components/index'
Vue.use(globalComponents)

Use in the page


<fr-table />

table component encapsulation

Issues under consideration

How many cases are there in table,

Normal data type display Unique display mode There are operation buttons

For the first type, we actually don't need to operate too much, just need to render through for loop.

The second one is actually good. We can customize it through slot

Third, the operation of buttons. Buttons can actually be divided into many types

Type of button

Normal use of buttons, click function Button take-off action Button to open a new page Button acts as a custom event

Code writing

From the above, we have analyzed all the problems of table, and now we only need to type the code.

Case 1


<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 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>

Here we can see the handleFilter method

This method to process data,

Data types are divided into normal data types, data types to be converted, data types to be converted by templates,

The code is 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
},

The first case is relatively simple, just simple data rendering and customized header rendering, and the overall above is multiple selection function + normal form

Case 2

Custom list


<template slot-scope="scope">
   <!--  Custom content  -->
   <slot
      v-if="item.isSlot"
      :name="item.prop"
      :row="scope.row"/
   >
</template>

Custom category, we only need isSlot to be set to true, name to prop, row to data

Type 3

The third button is divided into four situations


<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>

Button in fact or loop rendering, mainly event analysis, through 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 })
      }
},

According to different types, we do different treatments.

Values of props Parameters

The current parameter and the parameter we defined are 1, so the code is as follows


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
        }
      ]
    }
  ] 
}

0

Since then, only the way the components are used is left

Use of components


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
        }
      ]
    }
  ] 
}

1

It is roughly as follows. If you need to use multiple choices, you can define your own methods and sort them in one way.

Paging component encapsulation

Refer to element paging component


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
        }
      ]
    }
  ] 
}

2

Data definition

The definition is as follows:


total: Number,
pageLimit: Number,
currentPage: Number,

Encapsulation


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
        }
      ]
    }
  ] 
}

4

Does it look very simple? In fact, it is as simple as that.

Then we add paging events and parameters to the component, and our whole table component encapsulation is completed. At this point, we have completed all the work of the whole table component encapsulation.

Summarize


Related articles: