npm package: @hxyfe/simple-table
Description: schema config table depends on element-ui
Author: lazy.b
Latest version: 1.0.2

# SimpleTabel 简单列表

## 介绍

基于 element-ui 以及 mc-form， 使用 config 对象进行配置生成的简单列表

## 引入

安装： `npm i --save @hxyfe/simple-table`  

全局注册：
```js
import Vue from 'vue';
import SimpleTable from '@hxyfe/simple-table';

Vue.component(SimpleTable.name, SimpleTable);
```

## API

### Props

表单组件的属性：  

| 参数         | 说明                                           | 类型                       | 默认值  |
| ------------ | ---------------------------------------------- | -------------------------- | ------- |
| api          | 列表请求数据的方法（必须）                     | Function                   | -       |
| config       | 当前列表的配置参数（必须）                     | Object                     | -       |
| commonParams | 其他请求的公共参数，如果有改变则会自动发起请求 | Object                     | -       |
| defaultFetch | 默认列表发起第一次请求的时机                   | created/mounted/其他任意值 | created |

> 除上面列出的属性外，其他定义在 `SimpleTable` 上的属性均会透传给 `element-ui` 的 [Table](https://element.eleme.cn/#/zh-CN/component/table#table-attributes) 组件  

**api** 的要求：  
  1. 必须是一个返回 promise 的函数  
  2. 该函数的入参是接口的请求参数  
  3. 返回的resolve 的对象包含两个键名 列表总数据量 totalRecord 和 当前请求的列表数据 recordList  
  4. 也就是说结构为: { totalRecord: 0, recordList: [] }  

```js
// api 的示例代码
api(params) {
  // 如果有其他固定参数，也可以在这里传入
  // 例如 : params.xxx = 'xxx';
  return this.$http.post('/list', params).then((res) => {
    const data = {};
    data.totalRecord = res.totalRecord;
    data.recordList = res.recordList || [];

    return data;
  });
},
```

**commonParams** 的说明：  
  1. 如果请求列表数据的接口入参除了搜索条件外还有其他入参则可以使用该属性传入  
  2. 该属性会被深度监听，如果有任何变动则会发起新的请求  
  3. 由于该属性变动导致发起的请求不会重置其他条件，也就是搜索条件和翻页都不会做修改  
  4. 如果是不需要响应的请求参数就不应该定义在该属性内，可以在定义 api 方法时传入  

**defaultFetch** 的说明：  
  1. created： 在组件 created 时机发起第一次请求；  
  2. mounted： 在组件 mounted 时机发起第一次请求；  
  3. 其他任意值： 不自动发起第一次请求，需要使用者主动发起请求  

**config** 对象的属性：  

| 参数       | 说明               | 类型           | 默认值 |
| ---------- | ------------------ | -------------- | ------ |
| search     | 列表的搜索参数     | Object         | -      |
| columns    | 列表的配置参数     | Array          | -      |
| pagination | 列表的翻页配置参数 | boolean/Object | -      |

**config** 的说明：  
  1. search 的具体配置和 [mc-form](https://github.com/AdonisLau/mc-form) 配置参数完全一致，请参考该组件文档进行配置  
  2. columns 中扩展了 renderCell 属性，可以定义一个字符串或者一个方法  
     1. 如果定义的是字符串，则该字符串代表一个 `SimpleTable` 具名 slot-scope  
     2. 如果定义的是方法，则该方法不要使用箭头函数定义，且不要进行 `this` 绑定  
     3. 如果定义的是方法，该方法内部 `this` 将直接指向当前 `vm` 实例，也就是可以拿到当前实例上的方法和数据，且该方法可以写 `jsx`  
     4. columns 中的配置大部分直接透传给 [table-column](https://element.eleme.cn/#/zh-CN/component/table#table-column-attributes) ，所以除了 `renderCell` 外，其他和 element-ui 中的属性一模一样  
  3. pagination 配置了列表的翻页数据  
     1. 如果没有该属性，或者属性值为一个 “假值” 则不渲染翻页器，且请求参数中也不会有相关参数  
     2. 如果传入一个非对象真值，例如 `true` ，则会使用默认的配置参数渲染翻页器  
     3. 如果传入一个对象值，则会使用该对象配置对默认配置进行覆盖  
     4. 翻页器使用的是 [Pagination](https://element.eleme.cn/#/zh-CN/component/pagination#attributes) 实现，所以具体可配置项也和该组件一模一样  

### Events

和 [Table](https://element.eleme.cn/#/zh-CN/component/table#table-events) 支持的事件一样  

### 方法

通过 ref 可以获取到 SimpleTable 实例并调用实例方法  

| 方法名       | 说明         | 参数    | 返回值 |
| ------------ | ------------ | ------- | ------ |
| fetchRecords | 重新请求数据 | -       | -      |
| reset        | 重置搜索条件 | boolean | -      |

**reset** 如果传入 “真值” 则重置搜索条件并且发起请求，否则只重置搜索条件  

```html
    <simple-table
      ref="sTable"
      :api="api"
      :config="config"
      :commonParams="commonParams"
      defaultFetch="mounted"
    ></simple-table>
```

```js
    fetch() {
      this.$refs.sTable && this.$refs.sTable.fetchRecords();
    },

    // 或者操作列表内置的 form ，但是不建议做这种操作
    // this.$refs.sTable.$refs.form.setOptions('categoryId', 'data', d);
```

## 代码演示

### 基础用法

使用该组件后，一个列表基本写完配置就写完了  

```html
<simple-table ref="sTable" :api="api" :config="config" :commonParams="commonParams">
  <template slot="test" slot-scope="{ row }">
    <span>{{ row.type | test }}</span>
  </template>
</simple-table>
```

```js
import { api } from '../mock/index';

const COLUMNS = [
  {
    type: 'index',
    width: '50',
    align: 'center',
    label: '序号',
  },
  {
    property: 'appId',
    'show-overflow-tooltip': true,
    width: '150',
    label: '公众号ID',
  },
  {
    property: 'wechatName',
    'show-overflow-tooltip': true,
    minWidth: '200',
    label: '名称',
  },
  {
    'show-overflow-tooltip': true,
    minWidth: '200',
    label: '测试 slot',
    renderCell: 'test',
  },
  {
    'show-overflow-tooltip': true,
    minWidth: '200',
    label: '测试 箭头函数',
    renderCell: ({ row }) => typeof row,
  },
  {
    'show-overflow-tooltip': true,
    width: '100',
    label: '公众号类型',
    renderCell({ row }) {
      return <span>{row.type}</span>;
    },
  },
  {
    width: '230',
    label: '操作',
    align: 'center',
    fixed: 'right',
    renderCell({ row }) {
      const { log } = this;

      return (
        <div>
          <el-button type='text' onClick={() => log(row.wechatName)}>
            打印name
          </el-button>
          <el-button type='text' onClick={() => log(row.appId)}>
            打印appId
          </el-button>
        </div>
      );
    },
  },
];

// 搜索表单配置
const FORM_CONFIG = {
  gutter: 20,
  labelWidth: '100px',
  properties: [
    {
      field: 'itemCode',
      value: null,
      label: '商品编号',
      type: 'text',
      ui: {
        column: 8,
      },
    },
    {
      field: 'itemName',
      value: null,
      label: '商品名称',
      type: 'text',
      ui: {
        column: 8,
      },
    },

    {
      field: 'goodsStatus',
      value: null,
      label: '商品状态',
      type: 'select',
      ui: {
        column: 8,
        clearable: true,
      },
      options: {
        data: [{ label: '嘿嘿嘿', value: '1' }],
      },
    },
    {
      field: 'scanStartTime-scanEndTime',
      value: null,
      label: '时间',
      type: 'datetimerange',
      ui: {
        column: 16,
      },
    },
  ],
};

export default {
  filters: {
    test(val) {
      return val % 2 ? '嘿嘿' : '哈哈';
    },
  },

  data() {
    return {
      config: {
        search: FORM_CONFIG,
        columns: [...COLUMNS],
        pagination: true,
      },
      commonParams: {},
    };
  },

  methods: {
    log(msg) {
      console.log(`点击打印数据：${msg}`);
    },

    api(data) {
      console.log('当前请求参数为', data);
      return api(data);
    },
  },
};
```

```js
// '../mock/index';
const item = {
  id: 2,
  wechatId: 'aaaaaa',
  wechatName: '测试公众号',
  appId: '1414',
  type: 2,
};

let start = 0;
const getList = () => {
  const recordList = [];
  for (let i = 0; i < 10; i++) {
    const temp = { ...item };
    Object.keys(temp).forEach((k) => {
      temp[k] += start++;
    });
    recordList.push(temp);
  }

  return recordList;
};

export const api = () => Promise.resolve({
  totalRecord: 666,
  recordList: getList(),
});

```