最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

element-ui封裝一個Table模板組件的示例

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

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

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

搜索功能區(qū):

提供searchBar插槽,可以自定義搜索輸入框,搜索、重置按鈕必有,新增按鈕通過props控制顯隱。這里對應(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ū):

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

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

可對應(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>

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

實現(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)]
  );
}

分頁器區(qū):

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

實現(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封裝一個Table模板組件的示例的詳細內(nèi)容,更多關(guān)于element-ui封裝組件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue2.0 + element UI 中 el-table 數(shù)據(jù)導(dǎo)出Excel的方法

    vue2.0 + element UI 中 el-table 數(shù)據(jù)導(dǎo)出Excel的方法

    下面小編就為大家分享一篇vue2.0 + element UI 中 el-table 數(shù)據(jù)導(dǎo)出Excel的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • Vue2.0父子組件傳遞函數(shù)的教程詳解

    Vue2.0父子組件傳遞函數(shù)的教程詳解

    這篇文章主要介紹了Vue2.0父子組件傳遞函數(shù)的教程詳解,需要的朋友可以參考下
    2017-10-10
  • Vue結(jié)合echarts實現(xiàn)繪制水滴圖

    Vue結(jié)合echarts實現(xiàn)繪制水滴圖

    這篇文章主要為大家詳細介紹了Vue如何結(jié)合echarts實現(xiàn)水滴圖的繪制,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-07-07
  • vue中style設(shè)置scoped后部分樣式不生效的解決

    vue中style設(shè)置scoped后部分樣式不生效的解決

    這篇文章主要介紹了vue中style設(shè)置scoped后部分樣式不生效的解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-09-09
  • vue中keep-alive內(nèi)置組件緩存的實例代碼

    vue中keep-alive內(nèi)置組件緩存的實例代碼

    這篇文章主要介紹了vue中的keep-alive內(nèi)置組件緩存,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • vue中v-if和v-show使用區(qū)別源碼分析

    vue中v-if和v-show使用區(qū)別源碼分析

    這篇文章主要為大家介紹了vue中v-if和v-show使用區(qū)別源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Vue3實現(xiàn)組件二次封裝的小技巧分享

    Vue3實現(xiàn)組件二次封裝的小技巧分享

    組件的二次封裝:保留組件已有的功能,需要重寫組件方法,當組件已有大量功能時候,則需要重寫很多重復(fù)代碼,且組件功能進行修改的時候,封裝的組件也需要對應(yīng)修改,從而造成許多開發(fā)和維護成本,本文給大家分享了Vue3實現(xiàn)組件二次封裝的小技巧,需要的朋友可以參考下
    2024-09-09
  • Vue2實現(xiàn)txt文件在線預(yù)覽的代碼示例

    Vue2實現(xiàn)txt文件在線預(yù)覽的代碼示例

    txt文件在線預(yù)覽不需要下載另外的插件,主要有兩種形式,一種是上傳完成后實現(xiàn)預(yù)覽;另一種是后端提供文件下載接口,獲取文件在線地址實現(xiàn)預(yù)覽;本文給大家介紹了Vue2實現(xiàn)txt文件在線預(yù)覽的代碼示例,需要的朋友可以參考下
    2025-01-01
  • Vue Element 分組+多選+可搜索Select選擇器實現(xiàn)示例

    Vue Element 分組+多選+可搜索Select選擇器實現(xiàn)示例

    這篇文章主要介紹了Vue Element 分組+多選+可搜索Select選擇器實現(xiàn)示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • Vuex中actions的使用教程詳解

    Vuex中actions的使用教程詳解

    actions作為Vuex的五大核心之一,它的屬性是用來處理異步方法的,通過提交mutations實現(xiàn)。本文將具體介紹一下actions的使用教程,需要的可以參考一下
    2022-01-01

最新評論

鸡泽县| 宜宾县| 仪征市| 慈利县| 舞阳县| 上饶市| 通河县| 昭苏县| 巴青县| 株洲市| 永修县| 略阳县| 临清市| 南投市| 鹤岗市| 澄迈县| 铜山县| 南溪县| 泗洪县| 鹤壁市| 甘泉县| 拜泉县| 敖汉旗| 宝山区| 东方市| 揭西县| 民县| 龙岩市| 宝鸡市| 岫岩| 万山特区| 板桥市| 庄浪县| 吴堡县| 安阳市| 津市市| 齐河县| 建始县| 敦化市| 莱西市| 呼玛县|