npm package: @qingbing/ts-v3-query-form
Description: 以 vue3 + element-plus 为基础封装的用于列表查询的表单组件
Author: qingbing
Latest version: 2.0.7

# QueryForm 插件介绍

- [QueryForm 插件介绍](#queryform-插件介绍)
  - [1. 概要说明](#1-概要说明)
    - [1.1 地址](#11-地址)
    - [1.2 插件描述](#12-插件描述)
    - [1.3 重要依赖](#13-重要依赖)
    - [1.4 插件安装](#14-插件安装)
  - [2. 包说明](#2-包说明)
    - [2.1 属性说明](#21-属性说明)
    - [2.2 TQueryFormItem 类型](#22-tqueryformitem-类型)
    - [2.3 默认数据类型选项卡](#23-默认数据类型选项卡)
  - [3. 示例](#3-示例)
    - [3.1 全局注册使用](#31-全局注册使用)
    - [3.2 模板组件使用](#32-模板组件使用)

## 1. 概要说明
### 1.1 地址

[https://gitee.com/duqingbing/ts-v3-package/tree/ts-v3-query-form](https://gitee.com/duqingbing/ts-v3-package/tree/ts-v3-query-form)

### 1.2 插件描述

以 vue3 + element-plus 为基础封装的用于列表查询的表单组件， 该插件主要是对 @qingbing/ts-v3-xz-form 表单的二次封装，适用于不需要验证的列表查询表单， 并提供了几个特定的查询条件。

### 1.3 重要依赖

- @qingbing/ts-v3-utils
- @qingbing/ts-v3-xz-form
- vue

### 1.4 插件安装

```bash
# yarn 安装
yarn add @qingbing/ts-v3-query-form

# npm 安装
npm i @qingbing/ts-v3-query-form
```

## 2. 包说明

### 2.1 属性说明

| 属性名     | 类型           | 是否必需 | 默认值 | 意义                                                                     |
| :--------- | :------------- | :------- | :----- | :----------------------------------------------------------------------- |
| items      | TQueryFormItem | 是       | -      | 查询的表单项目                                                           |
| data       | TRecord        | 否       | {}     | 查询表单的form值, 务必传递，否则没有地方接收查询表单输出的值             |
| showFields | string[]       | 否       | []     | 控制显示的项目，默认为 [], 表示全部都显示， 指定后按照指定的字段进行展示 |

### 2.2 TQueryFormItem 类型

```ts
/**
 * 几种默认指定的属性类型
 */
export type TQueryFormDataType = "sex" | "yesNo" | "forbidden" | "enable" | "deleted" | "opened"

/**
 * 查询表单项目的类型
 */
export type TQueryFormItem = Omit<TXzFormItem, 'input_type' | 'label'> & {
    input_type: TXzFormInputType | TQueryFormDataType
    label?: string
}
```

### 2.3 默认数据类型选项卡

```ts
export default {
    // 性别
    sex: [
        { value: "0", label: "秘" },
        { value: "1", label: "男" },
        { value: "2", label: "女" },
    ],
    // 是否选择
    yesNo: [
        { value: "0", label: "否" },
        { value: "1", label: "是" },
    ],
    // 禁用状态
    forbidden: [
        { value: "0", label: "启用" },
        { value: "1", label: "禁用" },
    ],
    // 开启状态
    enable: [
        { value: "0", label: "禁用" },
        { value: "1", label: "启用" },
    ],
    // 删除状态
    deleted: [
        { value: "0", label: "正常" },
        { value: "1", label: "已删除" },
    ],
    // 开关状态
    opened: [
        { value: "0", label: "关闭" },
        { value: "1", label: "开启" },
    ],
}
```

## 3. 示例
### 3.1 全局注册使用

- 一旦注册， `QueryForm` 作为组件全局通用 
- 使用方法参考 [3.2 模板组件使用](#32-模板组件使用), 去掉组件导入的语句即可

```ts
// main.ts
import { QueryFormPlugin } from '@qingbing/ts-v3-query-form'
app.use(QueryFormPlugin, {
  name: 'QueryForm',
  options: {}
})
```

### 3.2 模板组件使用

```vue
<template>
    <el-form :inline="true" :model="queryData">
        <QueryForm :items="items" :data="queryData" />
        <el-form-item>
            <el-button type="primary" @click="handleRefreshTable">Query</el-button>
        </el-form-item>
    </el-form>
    <pre><code>{{ queryData }}</code></pre>

    <XzTable :headers="headers" :get-data="getData" :params="queryData" :refresh-key="tableKey" />
</template>

<script lang="ts" setup>
import '@qingbing/ts-v3-xz-form/dist/style.css' // xz-form 组件样式(整合了 json-editor 和 xz-editor 组件样式)
import type { TXzTableFetchData, TXzTableItem } from "@qingbing/ts-v3-xz-table"
import type { TRecord, TObject } from "@qingbing/ts-v3-utils"
import type { TQueryFormItem } from "@qingbing/ts-v3-query-form"
import type { TXzFormRemoteOption } from "@qingbing/ts-v3-xz-form"
import { XzTable } from "@qingbing/ts-v3-xz-table"
import { QueryForm } from "@qingbing/ts-v3-query-form";
import { reactive, ref } from 'vue'
import request from "axios";


const fetchSuggestions = (keyword: string, cb: (arg: any) => void) => {
    request.create({
        baseURL: 'http://mock.qiyezhu.net/mock/64e35b8e4a2b7b001dd2e4ec/example/fetch-suggestion',
        timeout: 5000, // 5000毫秒，5秒
        headers: {
            'Content-Type': 'application/json;charset=utf-8'
        }
    })
        .post('/', { keyword, })
        .then(res => {
            cb(res.data.data)
        })
        .catch(err => err)
}

const remoteOptions: TXzFormRemoteOption = (keyword, _, cb) => {
    request.create({
        baseURL: 'http://mock.qiyezhu.net/mock/64e35b8e4a2b7b001dd2e4ec/example/select-options',
        timeout: 5000, // 5000毫秒，5秒
        headers: {
            'Content-Type': 'application/json;charset=utf-8'
        }
    })
        .post('/', { keyword, })
        .then(res => {
            cb(res.data.data)
        })
        .catch(err => err)
}

const items: TQueryFormItem[] = [
    {
        input_type: "input-text",
        field: "keyword",
        label: "关键字",
    },
    {
        input_type: "sex",
        field: "sex"
    },
    {
        input_type: "yesNo",
        field: "yesNo"
    },
    {
        input_type: "forbidden",
        field: "forbidden"
    },
    {
        input_type: "enable",
        field: "enable"
    },
    {
        input_type: "deleted",
        field: "deleted"
    },
    {
        input_type: "opened",
        field: "opened"
    },
    {
        input_type: "input-select",
        field: "area",
        label: "城市",
        exts: {
            options: [
                { value: "shanghai", label: "上海" },
                { value: "beijing", label: "北京" },
                { value: "chengdu", label: "成都" },
            ]
        }
    },
    {
        input_type: "auto-complete",
        field: "suggest",
        label: "远端建议",
        exts: {
            fetchSuggestions
        }
    },
    {
        input_type: "input-select",
        field: "uid",
        label: "用户名",
        exts: {
            remoteMethod: remoteOptions
        },
    },
]

const queryData = reactive<TRecord>({})

const tableKey = ref(1)
const handleRefreshTable = () => {
    tableKey.value++
}

const headers: TXzTableItem[] = [
    {
        field: "username",
        label: "用户名",
        default: '-',
        tableConf: {
            width: "160",
            align: "left",
        },
    },
    {
        field: "sex",
        label: "性别",
        default: 'S',
        tableConf: {
            width: "100",
        },
        type: 'option',
        exts: {
            options: {
                'S': "秘",
                'F': "男",
                'M': "女",
            }
        }
    },
    {
        field: "operate",
        label: "操作",
        default: '',
        tableConf: {
            fixed: "right",
            align: "left",
            minWidth: 300,
        },
        type: 'component',
        exts: {
            component: {
                name: "operate",
                conf: {
                    isButton: true,
                    buttons: [
                        {
                            type: 'view',
                            handle: (row: TRecord) => {
                                console.log(row);
                            }
                        }, {
                            type: 'edit',
                            handle: (row: TRecord) => {
                                console.log(row);
                            }
                        },
                        {
                            type: 'delete',
                            handle: (row: TRecord, successCall: (msg: string) => void, failureCall: (msg: string) => void) => {
                                successCall('删除成功')
                                handleRefreshTable()
                            }
                        }
                    ]
                }
            },
        }
    },
]

const getData: TXzTableFetchData = (cb, params?: TObject) => {
    request.create({
        baseURL: 'http://mock.qiyezhu.net/mock/64e35b8e4a2b7b001dd2e4ec/example/table-data', // 默认就是 "/",
        timeout: 5000, // 5000毫秒，5秒
        headers: {
            'Content-Type': 'application/json;charset=utf-8'
        }
    })
        .post('/', params)
        .then(res => cb(res.data.data))
        .catch(err => err)
}
</script>
```