Files
vue-vben-admin/src/views/demo/form/index.vue
2021-07-15 18:05:13 +08:00

480 lines
10 KiB
Vue

<template>
<PageWrapper title="表单基础示例" contentFullHeight>
<CollapseContainer title="基础示例">
<BasicForm
autoFocusFirstItem
:labelWidth="200"
:schemas="schemas"
:actionColOptions="{ span: 24 }"
@submit="handleSubmit"
@reset="handleReset"
>
<template #localSearch="{ model, field }">
<ApiSelect
:api="optionsListApi"
showSearch
v-model:value="model[field]"
optionFilterProp="label"
resultField="list"
labelField="name"
valueField="id"
/>
</template>
<template #remoteSearch="{ model, field }">
<ApiSelect
:api="optionsListApi"
showSearch
v-model:value="model[field]"
:filterOption="false"
resultField="list"
labelField="name"
valueField="id"
:params="searchParams"
@search="onSearch"
/>
</template>
</BasicForm>
</CollapseContainer>
</PageWrapper>
</template>
<script lang="ts">
import { computed, defineComponent, unref, ref } from 'vue';
import { BasicForm, FormSchema, ApiSelect } from '/@/components/Form/index';
import { CollapseContainer } from '/@/components/Container';
import { useMessage } from '/@/hooks/web/useMessage';
import { PageWrapper } from '/@/components/Page';
import { optionsListApi } from '/@/api/demo/select';
import { useDebounceFn } from '@vueuse/core';
import { treeOptionsListApi } from '/@/api/demo/tree';
const provincesOptions = [
{
id: 'guangdong',
label: '广东省',
value: '1',
key: '1',
},
{
id: 'jiangsu',
label: '江苏省',
value: '2',
key: '2',
},
];
const citiesOptionsData = {
guangdong: [
{
label: '珠海市',
value: '1',
key: '1',
},
{
label: '深圳市',
value: '2',
key: '2',
},
{
label: '广州市',
value: '3',
key: '3',
},
],
jiangsu: [
{
label: '南京市',
value: '1',
key: '1',
},
{
label: '无锡市',
value: '2',
key: '2',
},
{
label: '苏州市',
value: '3',
key: '3',
},
],
};
const schemas: FormSchema[] = [
{
field: 'field1',
component: 'Input',
label: '字段1',
colProps: {
span: 8,
},
// componentProps:{},
// can func
componentProps: ({ schema, formModel }) => {
console.log('form:', schema);
console.log('formModel:', formModel);
return {
placeholder: '自定义placeholder',
onChange: (e: any) => {
console.log(e);
},
};
},
renderComponentContent: () => {
return {
prefix: () => 'pSlot',
suffix: () => 'sSlot',
};
},
},
{
field: 'field2',
component: 'Input',
label: '带后缀',
defaultValue: '111',
colProps: {
span: 8,
},
componentProps: {
onChange: (e: any) => {
console.log(e);
},
},
suffix: '天',
},
{
field: 'field3',
component: 'DatePicker',
label: '字段3',
colProps: {
span: 8,
},
},
{
field: 'field4',
component: 'Select',
label: '字段4',
colProps: {
span: 8,
},
componentProps: {
options: [
{
label: '选项1',
value: '1',
key: '1',
},
{
label: '选项2',
value: '2',
key: '2',
},
],
},
},
{
field: 'field5',
component: 'CheckboxGroup',
label: '字段5',
colProps: {
span: 8,
},
componentProps: {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
},
{
field: 'field7',
component: 'RadioGroup',
label: '字段7',
colProps: {
span: 8,
},
componentProps: {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
},
{
field: 'field8',
component: 'Checkbox',
label: '字段8',
colProps: {
span: 8,
},
renderComponentContent: 'Check',
},
{
field: 'field9',
component: 'Switch',
label: '字段9',
colProps: {
span: 8,
},
},
{
field: 'field10',
component: 'RadioButtonGroup',
label: '字段10',
colProps: {
span: 8,
},
componentProps: {
options: [
{
label: '选项1',
value: '1',
},
{
label: '选项2',
value: '2',
},
],
},
},
{
field: 'field11',
component: 'Cascader',
label: '字段11',
colProps: {
span: 8,
},
componentProps: {
options: [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
],
},
},
{
field: 'field30',
component: 'ApiSelect',
label: '懒加载远程下拉',
required: true,
componentProps: {
// more details see /src/components/Form/src/components/ApiSelect.vue
api: optionsListApi,
params: {
id: 1,
},
resultField: 'list',
// use name as label
labelField: 'name',
// use id as value
valueField: 'id',
// not request untill to select
immediate: false,
onChange: (e) => {
console.log('selected:', e);
},
// atfer request callback
onOptionsChange: (options) => {
console.log('get options', options.length, options);
},
},
colProps: {
span: 8,
},
defaultValue: '0',
},
{
field: 'field31',
component: 'Input',
label: '下拉本地搜索',
helpMessage: ['ApiSelect组件', '远程数据源本地搜索', '只发起一次请求获取所有选项'],
required: true,
slot: 'localSearch',
colProps: {
span: 8,
},
defaultValue: '0',
},
{
field: 'field32',
component: 'Input',
label: '下拉远程搜索',
helpMessage: ['ApiSelect组件', '将关键词发送到接口进行远程搜索'],
required: true,
slot: 'remoteSearch',
colProps: {
span: 8,
},
defaultValue: '0',
},
{
field: 'field33',
component: 'ApiTreeSelect',
label: '远程下拉树',
helpMessage: ['ApiTreeSelect组件', '使用接口提供的数据生成选项'],
required: true,
componentProps: {
api: treeOptionsListApi,
resultField: 'list',
},
colProps: {
span: 8,
},
},
{
field: 'field20',
component: 'InputNumber',
label: '字段20',
required: true,
colProps: {
span: 8,
},
},
{
field: 'province',
component: 'Select',
label: '省份',
colProps: {
span: 8,
},
componentProps: ({ formModel, formActionType }) => {
return {
options: provincesOptions,
placeholder: '省份与城市联动',
onChange: (e: any) => {
// console.log(e)
let citiesOptions =
e == 1
? citiesOptionsData[provincesOptions[0].id]
: citiesOptionsData[provincesOptions[1].id];
// console.log(citiesOptions)
if (e === undefined) {
citiesOptions = [];
}
formModel.city = undefined; // reset city value
const { updateSchema } = formActionType;
updateSchema({
field: 'city',
componentProps: {
options: citiesOptions,
},
});
},
};
},
},
{
field: 'city',
component: 'Select',
label: '城市',
colProps: {
span: 8,
},
componentProps: {
options: [], // defalut []
placeholder: '省份与城市联动',
},
},
{
field: 'field21',
component: 'Slider',
label: '字段21',
componentProps: {
min: 0,
max: 100,
range: true,
marks: {
20: '20°C',
60: '60°C',
},
},
colProps: {
span: 8,
},
},
{
field: 'field22',
component: 'Rate',
label: '字段22',
defaultValue: 3,
colProps: {
span: 8,
},
componentProps: {
disabled: false,
allowHalf: true,
},
},
];
export default defineComponent({
components: { BasicForm, CollapseContainer, PageWrapper, ApiSelect },
setup() {
const check = ref(null);
const { createMessage } = useMessage();
const keyword = ref<string>('');
const searchParams = computed<Recordable>(() => {
return { keyword: unref(keyword) };
});
function onSearch(value: string) {
keyword.value = value;
}
return {
schemas,
optionsListApi,
onSearch: useDebounceFn(onSearch, 300),
searchParams,
handleReset: () => {
keyword.value = '';
},
handleSubmit: (values: any) => {
createMessage.success('click search,values:' + JSON.stringify(values));
},
check,
};
},
});
</script>