欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

element-ui封裝一個(gè)Table模板組件的示例

 更新時(shí)間:2021年01月04日 10:29:49   作者:不死小強(qiáng)  
這篇文章主要介紹了element-ui封裝一個(gè)Table模板組件的示例,幫助大家更好的理解和學(xué)習(xí)vue框架的使用,感興趣的朋友可以了解下

大家在做后臺(tái)管理系統(tǒng)的時(shí)候,寫(xiě)的最多的可能就是表格頁(yè)面了,一般分三部分:搜索功能區(qū)、表格內(nèi)容區(qū)和分頁(yè)器區(qū)。一般這些功能都是使用第三方組件庫(kù)實(shí)現(xiàn),比如說(shuō)element-ui,或者vuetify。這兩個(gè)組件庫(kù)都各有各的優(yōu)點(diǎn),但就table組件來(lái)說(shuō),我還是比較喜歡vuetify的實(shí)現(xiàn),不用手寫(xiě)一個(gè)個(gè)column,只要傳入headers的配置數(shù)組就行,甚至分頁(yè)器都內(nèi)置在了table組件里,用起來(lái)十分方便。有興趣可以看看:vuetify data table。

上面是一個(gè)經(jīng)典的用element-ui開(kāi)發(fā)的table頁(yè)面,而且實(shí)際工作中如果每個(gè)table頁(yè)面都寫(xiě)一遍,重復(fù)代碼太多了,所以不妨寫(xiě)一個(gè)table模板組件,減少重復(fù)代碼。我的思路是這樣的:

搜索功能區(qū):

提供searchBar插槽,可以自定義搜索輸入框,搜索、重置按鈕必有,新增按鈕通過(guò)props控制顯隱。這里對(duì)應(yīng)的代碼如下:

genSearchBar() {
  if (this.noSearchBar || !this.$scopedSlots.searchBar) return '';
  return (
    <el-form class="seatch-form" inline={true} label-width="100">
      {this.$scopedSlots.searchBar()}
      <el-button
        class="filter-item"
        icon="el-icon-search"
        type="primary"
        onClick={this.handleSearchBtnClick}
      >
        查詢
      </el-button>
      <el-button
        class="filter-item"
        icon="el-icon-refresh"
        onClick={this.handleResetBtnClick}
      >
        重置
      </el-button>
      <el-button
        class="filter-item"
        icon="el-icon-plus"
        type="primary"
        v-show={this.showAddBtn}
        onClick={this.handleAddBtnClick}
      >
        新增
      </el-button>
    </el-form>
  );
}

表格內(nèi)容區(qū):

通過(guò)傳入headers自動(dòng)生成columns,參數(shù)如下:

{
  label: '性別',
  prop: 'sex',
  width: '180',
  filter: 'sexFilter'
}

可對(duì)應(yīng)如下代碼:

<el-table-column
         prop="sex"
         label="性別"
         width="180">
  <template slot-scope="scope">{{scope.row.sex | sexFilter}}</template>
</el-table-column>

注意,只支持全局filter。

如果你想自定義column,也提供tableColumn插槽,支持自定義column,可以如下配置:

{
  prop: 'action'
}
<el-table-column
         prop="action"
         label="操作"
         width="180">
  <template slot-scope="scope">
    <el-button>編輯</el-button>
    <el-button>刪除</el-button>
  </template>
</el-table-column>

這樣,就會(huì)按傳入的prop匹配對(duì)應(yīng)的column,十分方便。

實(shí)現(xiàn)代碼如下:

genTableSlot(h) {
  let customeColumns = this.$scopedSlots.tableColumn
    ? this.$scopedSlots.tableColumn()
    : [];
  return this.headers.map((item) => {
    // 根據(jù)item.prop判斷是否使用傳入的插槽內(nèi)容
    let foundItem = customeColumns.find(
      (ele) =>
        ele.componentOptions &&
        ele.componentOptions.propsData.prop === item.prop
    );
    return foundItem
      ? foundItem
      : h('el-table-column', {
         props: {
           ...item,
         },
         scopedSlots: {
           default: (props) => {
             // 根據(jù)傳入的全局filter處理column數(shù)據(jù)
             let filter = this.$options.filters[
               item.filter
             ];
             let itemValue = props.row[item.prop];
             return h(
               'span',
               filter ? filter(itemValue) : itemValue
             );
           },
         },
       });
  });
}
genTable(h) {
  return h(
    'el-table',
    {
      ref: 'tableRef',
      props: {
        ...this.$attrs,
        data: this.data,
      },
      on: {
        'selection-change': (val) => {
          this.$emit('selection-change', val);
        },
      },
    },
    [...this.genTableSlot(h)]
  );
}

分頁(yè)器區(qū):

如無(wú)特殊需求,分頁(yè)器功能一致,所以直接內(nèi)置。

實(shí)現(xiàn)代碼如下:

genPagination() {
  return (
    <div class="pagination-wrap">
      <el-pagination
        layout="total,prev,pager,next,jumper"
        current-page={this.current}
        page-size={this.pageSize}
        total={this.total}
        {...{
          on: { 'current-change': this.handleCurrentChange },
        }}
      ></el-pagination>
    </div>
  );
}

最后附完整代碼和demo:

<script>
export default {
  name: 'TableTemplate',
  props: {
    data: {
      type: Array,
      default: () => [],
      required: true,
    },
    headers: {
      type: Array,
      default: () => [],
      required: true,
    },
    current: {
      type: Number,
      default: 1,
    },
    pageSize: {
      type: Number,
      default: 10,
    },
    total: {
      type: Number,
      default: 0,
    },
    noSearchBar: Boolean,
    showAddBtn: Boolean,
  },
  mounted() {
    this.$nextTick(() => {
      this.$emit('search');
    });
  },
  methods: {
    genSearchBar() {
      if (this.noSearchBar || !this.$scopedSlots.searchBar) return '';
      return (
        <el-form class="seatch-form" inline={true} label-width="100">
          {this.$scopedSlots.searchBar()}
          <el-button
            class="filter-item"
            icon="el-icon-search"
            type="primary"
            onClick={this.handleSearchBtnClick}
          >
            查詢
          </el-button>
          <el-button
            class="filter-item"
            icon="el-icon-refresh"
            onClick={this.handleResetBtnClick}
          >
            重置
          </el-button>
          <el-button
            class="filter-item"
            icon="el-icon-plus"
            type="primary"
            v-show={this.showAddBtn}
            onClick={this.handleAddBtnClick}
          >
            新增
          </el-button>
        </el-form>
      );
    },
    genTableSlot(h) {
      let customeColumns = this.$scopedSlots.tableColumn
        ? this.$scopedSlots.tableColumn()
        : [];
      return this.headers.map((item) => {
        // 根據(jù)item.prop判斷是否使用傳入的插槽內(nèi)容
        let foundItem = customeColumns.find(
          (ele) =>
            ele.componentOptions &&
            ele.componentOptions.propsData.prop === item.prop
        );
        return foundItem
          ? foundItem
          : h('el-table-column', {
             props: {
               ...item,
             },
             scopedSlots: {
               default: (props) => {
                 let filter = this.$options.filters[
                   item.filter
                 ];
                 let itemValue = props.row[item.prop];
                 return h(
                   'span',
                   filter ? filter(itemValue) : itemValue
                 );
               },
             },
           });
      });
    },
    genTable(h) {
      return h(
        'el-table',
        {
          ref: 'tableRef',
          props: {
            ...this.$attrs,
            data: this.data,
          },
          on: {
            'selection-change': (val) => {
              this.$emit('selection-change', val);
            },
          },
        },
        [...this.genTableSlot(h)]
      );
    },
    genPagination() {
      return (
        <div class="pagination-wrap">
          <el-pagination
            layout="total,prev,pager,next,jumper"
            current-page={this.current}
            page-size={this.pageSize}
            total={this.total}
            {...{
              on: { 'current-change': this.handleCurrentChange },
            }}
          ></el-pagination>
        </div>
      );
    },
    resetPagination() {
      this.$emit('update:current', 1);
    },
    handleCurrentChange(val) {
      this.$emit('update:current', val);
      this.$emit('search');
    },
    handleSearchBtnClick() {
      this.$emit('search');
    },
    handleResetBtnClick() {
      this.resetPagination();
      this.$emit('reset');
    },
    handleAddBtnClick() {
      this.$emit('add');
    },
    getTableRef() {
      return this.$refs.tableRef;
    },
  },
  render(h) {
    return (
      <div>
        {this.genSearchBar()}
        {this.genTable(h)}
        {this.genPagination()}
      </div>
    );
  },
};
</script>

<style scoped>
.seatch-form {
  text-align: left;
}
.pagination-wrap {
  margin-top: 20px;
  text-align: right;
}
</style>

Demo:

<template>
  <div>
    <table-template
      border
      :headers="headers"
      :data="tableData"
      :current.sync="current"
      :total="total"
      ref="tableTemplate"
      showAddBtn
      @search="handleSearch"
      @reset="handleReset"
      @add="handleAdd"
      @selection-change="handleSelectionChange"
    >
      <template #searchBar>
        <el-form-item label="姓名:" prop="title">
          <el-input class="filter-item" v-model="searchForm.title" ></el-input>
        </el-form-item>
      </template>
      <template #tableColumn>
        <el-table-column
          prop="selection"
          type="selection"
          width="55"
        ></el-table-column>
        <el-table-column prop="test" label="姓名" width="180">
          <template slot-scope="scope">
            <el-popover trigger="hover" placement="top">
              <p>姓名:{{ scope.row.name }}</p>
              <p>住址:{{ scope.row.address }}</p>
              <div slot="reference" class="name-wrapper">
                <el-tag size="medium">{{scope.row.name}}</el-tag>
              </div>
            </el-popover>
          </template>
        </el-table-column>
      </template>
    </table-template>
  </div>
</template>

<script>
import TableTemplate from './TableTemplate';
export default {
  name: 'Demo',
  components: {
    TableTemplate,
  },
  data() {
    return {
      current: 1,
      total: 100,
      headers: [
        {
          prop: 'selection',
        },
        {
          label: '姓名',
          prop: 'name',
          width: '100',
        },
        {
          label: '年齡',
          prop: 'year',
        },
        {
          label: '性別',
          prop: 'sex',
          width: 'sexFilter',
        },
        {
          prop: 'test',
        },
      ],
      tableData: [
        {
          name: 'curry',
          year: 18,
          sex: 'female',
          address: '天安門',
        },
      ],
      searchForm: {
        title: '',
      },
    };
  },
  methods: {
    handleSearch() {
      console.log(this.current);
    },
    handleReset() {
      this.searchForm = {
        title: '',
      };
    },
    handleAdd() {
      console.log('添加');
    },
    handleSelectionChange(val) {
      console.log(val);
    },
    getTableRef() {
      console.log(this.$refs.tableTemplate.getTableRef());
    },
  },
};
</script>

以上就是element-ui封裝一個(gè)Table模板組件的示例的詳細(xì)內(nèi)容,更多關(guān)于element-ui封裝組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue過(guò)濾器,生命周期函數(shù)和vue-resource簡(jiǎn)單介紹

    Vue過(guò)濾器,生命周期函數(shù)和vue-resource簡(jiǎn)單介紹

    這篇文章主要介紹了Vue過(guò)濾器,生命周期函數(shù)和vue-resource簡(jiǎn)單介紹,幫助大家更好的理解和使用vue,感興趣的朋友可以了解下
    2021-01-01
  • 前端Vue項(xiàng)目部署到服務(wù)器的全過(guò)程以及踩坑記錄

    前端Vue項(xiàng)目部署到服務(wù)器的全過(guò)程以及踩坑記錄

    使用Vue做前后端分離項(xiàng)目時(shí),通常前端是單獨(dú)部署,用戶訪問(wèn)的也是前端項(xiàng)目地址,因此前端開(kāi)發(fā)人員很有必要熟悉一下項(xiàng)目部署的流程,下面這篇文章主要給大家介紹了關(guān)于前端Vue項(xiàng)目部署到服務(wù)器的全過(guò)程以及踩坑記錄的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • 基于vue實(shí)現(xiàn)pdf預(yù)覽功能

    基于vue實(shí)現(xiàn)pdf預(yù)覽功能

    隨著互聯(lián)網(wǎng)的發(fā)展,PDF?文件在信息交流和文檔分享中起著重要的作用,通過(guò)在?Vue?組件中實(shí)現(xiàn)?PDF?預(yù)覽功能,我們可以為用戶提供便捷的內(nèi)容閱讀體驗(yàn),下面我們就來(lái)看看具體實(shí)現(xiàn)方法吧
    2023-08-08
  • vue3?element?plus?table?selection展示數(shù)據(jù),默認(rèn)選中功能方式

    vue3?element?plus?table?selection展示數(shù)據(jù),默認(rèn)選中功能方式

    這篇文章主要介紹了vue3?element?plus?table?selection展示數(shù)據(jù),默認(rèn)選中功能方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • vue element input如何讓瀏覽器不保存密碼

    vue element input如何讓瀏覽器不保存密碼

    這篇文章主要介紹了vue element input如何讓瀏覽器不保存密碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue下跨域設(shè)置的相關(guān)介紹

    vue下跨域設(shè)置的相關(guān)介紹

    本篇文章主要介紹了vue下跨域設(shè)置的相關(guān)介紹,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 使用開(kāi)源Cesium+Vue實(shí)現(xiàn)傾斜攝影三維展示功能

    使用開(kāi)源Cesium+Vue實(shí)現(xiàn)傾斜攝影三維展示功能

    這篇文章主要介紹了使用開(kāi)源Cesium+Vue實(shí)現(xiàn)傾斜攝影三維展示,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • 詳解VUE 數(shù)組更新

    詳解VUE 數(shù)組更新

    這篇文章主要介紹了VUE 數(shù)組更新問(wèn)題,文中給大家介紹了vue如何監(jiān)聽(tīng)數(shù)據(jù)的變化的 ,需要的朋友可以參考下
    2017-12-12
  • Vue項(xiàng)目中使用Bootstrap

    Vue項(xiàng)目中使用Bootstrap

    這篇文章介紹了Vue項(xiàng)目中使用Bootstrap的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • 快速解決vue在ios端下點(diǎn)擊響應(yīng)延時(shí)的問(wèn)題

    快速解決vue在ios端下點(diǎn)擊響應(yīng)延時(shí)的問(wèn)題

    今天小編就為大家分享一篇快速解決vue在ios端下點(diǎn)擊響應(yīng)延時(shí)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08

最新評(píng)論