page.md 8.73 KB

Mixin Page 标准页

根据JSON Scheme配置自动生成一个筛选条件表单

52a3208c9c7bd5ef3a634be490df5af0f2d334bc/examples/views/docs/develop/mixin/page.md#">基础用法

MIX_PAGE混入配置项,会默认提供一套分页查询的业务逻辑。

::: snippet 预置了许多业务逻辑,避免重复维护相同的业务逻辑

<template>
  <div>
    <div class="page-search">
      <el-form :model="searchModel" label-width="80px" size="small">
        <el-row>
          <el-col :span="6">
            <el-form-item label="姓名">
              <el-input v-model.trim="searchModel.name"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="18" style="text-align: right;">
            <el-form-item>
              <el-button-group>
                <el-button :loading="loading" type="primary" @click="onSearch">查询</el-button>
                <el-button @click="onReset">重置</el-button>
              </el-button-group>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <div class="page-action">
      <el-button type="primary" size="small">新增</el-button>
    </div>
    <el-table class="page-table" v-loading="loading" v-bind="tableProps" :data="tableData">
      <el-table-column label="姓名" prop="name" min-width="100" show-overflow-tooltip></el-table-column>
      <el-table-column label="年龄" prop="age" min-width="120" show-overflow-tooltip></el-table-column>
    </el-table>
    <el-pagination class="page-pagination" v-bind="paginationProps" v-on="paginationEvent"></el-pagination>
  </div>
</template>

<script>
// import MIX_PAGE from '@/mixins/page'; 注:使用时解除此注释

export default {
  mixins: [MIX_PAGE],
  data() {
    return {
      searchModel: {
        name: '',
      },
    };
  },
  methods: {
    searchAPI(params) {
      return new Promise(resolve => {
        setTimeout(() => {
          const source = [
            { id: '0', name: '李饼', age: 32 },
            { id: '1', name: '陈拾', age: 20 },
            { id: '3', name: '王七', age: 26 },
            { id: '4', name: '崔倍', age: 27 },
            { id: '5', name: '孙豹', age: 38 },
            { id: '6', name: '庞柏', age: 42 },
            { id: '7', name: '蔡疏', age: 60 },
            { id: '8', name: '卢纳', age: 55 },
          ];
          const list = source.filter(item => `${item.name}`.includes(params.name));
          resolve({
            result: list,
            totalCount: list.length
          });
        }, 1500);
      });
    },
  },
};
</script>

:::

52a3208c9c7bd5ef3a634be490df5af0f2d334bc/examples/views/docs/develop/mixin/page.md#">推荐用法

z-formz-table等组件配合,可以最大限度的减少代码量,开发者只需要重点关心与业务相关的数据渲染

::: snippet MIX_PAGE混入配置项,会默认提供一套分页查询的业务逻辑。

<template>
  <div>
    <div class="page-search">
      <z-form :model="searchModel" label-width="80px" size="small" span="6">
        <z-form-item label="姓名" prop="name">
          <el-input v-model="searchModel.name"></el-input>
        </z-form-item>
        <z-form-item span="18" style="text-align: right">
          <el-button-group>
            <el-button :loading="loading" type="primary" @click="onSearch">查询</el-button>
            <el-button @click="onReset">重置</el-button>
          </el-button-group>
        </z-form-item>
      </z-form>
    </div>
    <div class="page-action">
      <el-button type="primary" size="small">新增</el-button>
    </div>
    <z-table class="page-table" v-loading="loading" v-bind="tableProps">
      <el-table-column prop="name" label="姓名"></el-table-column>
      <el-table-column prop="age" label="年龄"></el-table-column>
    </z-table>
    <el-pagination class="page-pagination" v-bind="paginationProps" v-on="paginationEvent"></el-pagination>
  </div>
</template>

<script>
// import MIX_PAGE from '@/mixins/page'; 注:使用时解除此注释

export default {
  mixins: [MIX_PAGE],
  data() {
    return {
      searchModel: {
        name: '',
      },
    };
  },
  methods: {
    searchAPI(params) {
      return new Promise(resolve => {
        setTimeout(() => {
          const source = [
            { id: '0', name: '李饼', age: 32 },
            { id: '1', name: '陈拾', age: 20 },
            { id: '3', name: '王七', age: 26 },
            { id: '4', name: '崔倍', age: 27 },
            { id: '5', name: '孙豹', age: 38 },
            { id: '6', name: '庞柏', age: 42 },
            { id: '7', name: '蔡疏', age: 60 },
            { id: '8', name: '卢纳', age: 55 },
          ];
          const list = source.filter(item => `${item.name}`.includes(params.name));
          resolve({
            result: list,
            totalCount: list.length
          });
        }, 1500);
      });
    },
  },
};
</script>

:::

52a3208c9c7bd5ef3a634be490df5af0f2d334bc/examples/views/docs/develop/mixin/page.md#">内置方法

本混入配置中,内置了originData对象和getOriginData方法。

::: snippet originData表示当前页面的初始data值,getOriginData方法可获得一个新的初始值对象

<template>
  <div>
    <div>model初始值:{{ originData.model }}</div>
    <el-input v-model="model.name" size="mini" style="width: 200px; margin: 10px 0"></el-input>
    <el-button type="primary" size="mini" @click="handleReset">重置</el-button>
    <div>model当前值:{{ model }}</div>
  </div>
</template>

<script>
export default {
  mixins: [MIX_PAGE],
  data() {
    return {
      model: {
        name: '张三',
      },
    };
  },
  methods: {
    handleReset() {
      // 注意:切记不可写成 this.model = this.originData.model; 否则会导致originData被改变!
      this.model = this.getOriginData().model;
    }
  },
};
</script>

:::

52a3208c9c7bd5ef3a634be490df5af0f2d334bc/examples/views/docs/develop/mixin/page.md#">源文件

import MIX_ORIGIN from '@/mixins/origin'; // 初始值逻辑混入

export default {
  mixins: [MIX_ORIGIN],
  data() {
    return {
      auto: true, // 页面加载时自动查询
      tableData: [], // 表格数据
      loading: false, // 加载状态
      total: 0, // 数据总量
      currentPage: 1, // 当前页码
      pageSize: 10, // 分页大小
      pageSizes: [10, 20, 50, 100], // 分页大小选项
      layout: 'total, sizes, prev, pager, next, jumper', // 分页器默认设置
      searchModel: {}, // 搜索表单绑定值
      form: {}, // 常规表单绑定值
      submitting: false, // 提交状态
      selection: [], // 表格选中项
      collapsed: false, // 展开状态
    };
  },
  computed: {
    // 搜索栏折叠按钮文本
    toggleText() {
      return this.collapsed ? '收起' : '展开';
    },
    // 表格属性
    tableProps() {
      return {
        size: 'mini',
        rowKey: 'id',
        border: true,
        highlightCurrentRow: true,
        data: this.tableData,
      };
    },
    // 表格事件
    tableEvent() {
      return {
        'selection-change': this.onSelectionChange,
      };
    },
    // 分页参数
    pageParams() {
      return {
        currentPage: this.currentPage,
        pageSize: this.pageSize,
      };
    },
    // 分页器属性
    paginationProps() {
      return {
        'current-page': this.currentPage,
        'page-sizes': this.pageSizes,
        'page-size': this.pageSize,
        layout: this.layout,
        total: this.total,
      };
    },
    // 分页器事件
    paginationEvent() {
      return {
        'size-change': this.onPageSizeChange,
        'current-change': this.onCurrentPageChange,
      };
    },
  },
  created() {
    if (this.auto) {
      this.search();
    }
  },
  methods: {
    // 空Promise
    emptyPromise() {
      return new Promise(resolve => resolve());
    },
    // 重置查询
    onSearch() {
      this.currentPage = 1;
      this.loadData();
    },
    // 切换展开状态
    toggle() {
      this.collapsed = !this.collapsed;
    },
    // 查询数据
    search() {
      this.loadData();
    },
    // 加载数据
    async loadData() {
      this.loading = true;
      const params = {
        ...this.searchModel,
        ...this.pageParams,
      };
      const searchAPI = this.searchAPI || this.emptyPromise;
      await searchAPI(params)
        .then(response => {
          const { result = [], totalCount = 0 } = response || {};
          this.tableData = result || [];
          this.total = totalCount || 0;
        })
        .finally(() => {
          this.loading = false;
        });
    },
    // 重置搜索表单
    onReset() {
      this.searchModel = this.cloneDeep(this.originData).searchModel;
    },
    // 多选
    onSelectionChange(selection) {
      this.selection = selection;
    },
    // 切换当前页码
    onCurrentPageChange(value) {
      this.currentPage = value;
      this.$nextTick(this.loadData);
    },
    // 切换最大页码
    onPageSizeChange(value) {
      this.currentPage = 1;
      this.pageSize = value;
      this.$nextTick(this.loadData);
    },
  },
};