当前位置: 首页 > 工具软件 > ListPage > 使用案例 >

封装组件——listPage页头及分页(vue+element)

翟鹏
2023-12-01
<template>
  <div id="listPage">
    <scpsForm :label-width="labelWidth"
              inline
              :size="size"
              v-if="showSearchForm">
      <el-card class="___search"
               shadow="never">
        <div class="search-box"
             style="min-height: 38px;">
          <search class="normalSearch"
                  tag="search"></search>
          <el-form-item>
            <div class="searchIcon"
                 @click="showSearchMore = !showSearchMore"
                 v-if="searchMore && !hideMoreClick">
              <div class="searchIconBox">
                <touch-ripple :speed="2"
                              :opacity="0.3"
                              color="#fff"
                              transition="ease">
                  <el-button type="primary">更多</el-button>
                </touch-ripple>
              </div>
            </div>
          </el-form-item>

          <!-- <slot name="search">
          </slot> -->
          <div class="rightAction">
            <slot name="action">
              <el-form-item v-if="action.indexOf('import') >= 0">
                <el-upload class="upload-demo"
                           ref="upload"
                           action="#"
                           :show-file-list="false"
                           :on-change="uploadChange"
                           :auto-upload="false">
                  <el-button slot="trigger"
                             size="small"
                             type="primary">导入</el-button>
                </el-upload>
                <slot name="appendBtn"> </slot>
              </el-form-item>
              <el-form-item>
                <el-button type="primary"
                           v-if="action.indexOf('add') >= 0"
                           @click="$emit('add')">{{addTitle?addTitle:'新增'}}</el-button>
              </el-form-item>
              <el-form-item>
                <el-button type="primary"
                           v-if="action.indexOf('export') >= 0"
                           @click="$emit('export')">{{exportTitle?exportTitle:'导出'}}</el-button>
              </el-form-item>
            </slot>
          </div>
        </div>
        <el-collapse-transition v-if="searchMore">
          <el-form-item v-show="showSearchMore">
            <search class="___searchMore"
                    tag="searchMore"></search>
            <!-- <slot name="searchMore">
            </slot> -->
          </el-form-item>
        </el-collapse-transition>
      </el-card>
    </scpsForm>

    <slot>
    </slot>

    <div class="mt10"
         v-if="showPageInfo">
      <slot name="page">
        <page-info :total="total"
                   :page="page"
                   :immediate="immediate"
                   @getDataList="_getDataList"
                   layout="prev, pager, next,sizes,jumper"></page-info>
      </slot>
    </div>
  </div>
</template>

<script>
import { touchRipple } from "vue-touch-ripple";
import "vue-touch-ripple/dist/vue-touch-ripple.css";
export default {
  provide() {
    return {
      parentThis: this,
    };
  },
  components: {
    touchRipple,
    search: {
      inject: ["parentThis"],
      props: ["tag"],
      render(h) {
        let node = null;
        let parentSearchNumber = this.parentThis.$parent.$props.searchNumber;
        let searchSlot = this.parentThis.$parent.$slots.search;
        if (searchSlot == undefined) {
          return;
        }
        if (this.tag == "search") {
          node = h("span", {}, searchSlot.slice(0, parentSearchNumber));
        } else {
          node = h("span", {}, searchSlot.slice(parentSearchNumber));
        }
        return node;
      },
    },
  },
  props: {
    immediate: {
      type: Boolean,
      default: true,
    },
    addTitle: {
      type: String,
      default: "",
    },
    exportTitle: {
      type: String,
      default: "",
    },
    hideMoreClick: {
      type: Boolean,
      default: false,
    },
    showMoreSearch: {
      default: false,
      type: Boolean,
    },
    // showSearch: {
    //   type: Boolean,
    //   default: true
    // },
    labelWidth: {
      type: String,
      default: "100px",
    },
    searchNumber: {
      type: [Number, String],
      default: 1,
    },
    total: {
      type: Number,
      default: 0,
    },
    getDataList: {
      type: Function,
      default: () => {},
    },
    action: {
      type: Array,
      default: () => ["add"],
    },
    actions: {
      type: Array,
      default: () => [],
    },
    size: {
      type: String,
      default: "small",
    },
    showPageInfo: {
      type: Boolean,
      default: true,
    },
    showSearchForm: {
      type: Boolean,
      default: true,
    },
  },
  // updated() {
  //   let searchSlot = this.$slots.search;
  //   if (searchSlot.length <= this.searchNumber) {
  //     this.searchMore = false;
  //   } else {
  //     this.searchMore = true;
  //   }
  // },
  mounted() {
    //  console.log(this.$slots.default[0]);
    let searchSlot = this.$slots.search;
    if (searchSlot && searchSlot.length > this.searchNumber) {
      this.searchMore = true;
    }
    this.showSearchMore = this.showMoreSearch;
  },
  created() {},

  data() {
    return {
      showMoreHandler: false,
      showSearchMore: false,
      searchMore: false,
      page: 1,
    };
  },
  methods: {
    uploadChange(file) {
      this.$emit("import", file.raw);
      return false;
    },
    async _getDataList(page, size) {
      this.page = page;
      await this.getDataList(this.page, size);
    },
    refresh(page, extraParam) {
      if (!page) {
        page = this.page;
      } else {
        this.page = page;
      }
      this.getDataList(page, 10, extraParam);
    },
  },
};
</script>

<style lang="scss">
#listPage {
  .upload-demo {
    margin-left: 10px;
    display: inline-block;
  }
  .___search {
    position: relative;
  }
}
.searchIcon {
  .___searchMore {
  }

  // #browseButton {
  //   cursor: pointer;
  //   color: #fff;
  //   background: #409eff;
  //   padding: 0 10px;
  //   border-radius: 2px;
  // }
  display: inline-block;
  .icon {
    margin-left: 10px;
  }
}
.comm-search .el-card__body {
  padding: 13px 10px 0 0 !important;
}
.moreSearch {
  background: #f2f2f2 !important;
  border: 1px solid #e5e5e5 !important;
  color: #666 !important;
  margin-left: 20px !important;
  cursor: pointer !important;
  padding: 0 25px !important;
  margin-right: 10px !important;
  height: 34px !important;
}
.moreSearch:hover {
  background: #fff7f7 !important;
}
</style>

 类似资料: