【vant】打开vant表单的正确形式(基于vant表单的二次封装)

这篇具有很好参考价值的文章主要介绍了【vant】打开vant表单的正确形式(基于vant表单的二次封装)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

最近在用vant做关于移动端的项目,由于表单字段太多,不想写直接写到template中,这样太繁琐了,所以我们以把表单弄成schema配置形式:

// data.ts
import type { ItemSchema } from '@/typing/helper';
import { StudentField } from '@/components';
import { getDictTextByCode } from '@/data/dict';

import {
  textField,
  switchField,
  dividerField,
  dictField,
  selectField,
  entityField,
} from '@/helpers';

export const baseFormSchema: ItemSchema[] = [
  dividerField('普通文本'),
  textField('name', '姓名', { required: true }),
  dividerField('文本域'),
  textField('address', '地址', { type: 'textarea' }),
  dividerField('是否字段'),
  switchField('isMarried', '是否婚配'),
  dividerField('字典选择'),
  dictField('marital', '婚姻情况', 'marital'),
  dividerField('select'),
  selectField('way', '交通工具', [
    { text: '汽车', code: 1 },
    { text: '步行', code: 2 },
  ]),
  dividerField('实体选择(学生)'),
  entityField('studentId', '学生', StudentField, {
    change(record) {
      console.log(record);
    },
  }),
];

form组件使用:

<template>
  <div class="content">
    <code>
      <pre>{{ formValue }}</pre>
    </code>
    <TwiceForm :form-schema="baseFormSchema" v-model="formValue"></TwiceForm>
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue';
  import { TwiceForm } from '@/components';
  import { baseFormSchema } from '@/views/form/data';

  const formValue = ref({
    name: '',
    age: '',
    address: '',
    isMarried: true,
    marital: -1,
    way: 1,
    studentId: '',
  });
</script>
<style lang="less" scoped></style>

就是通过数据驱动生成表单(效果如下)。
【vant】打开vant表单的正确形式(基于vant表单的二次封装),javascript,前端,开发语言
也可以戳链接亲自体验:vant_twice_form

小成果

这样不仅表单字段配置起来方便,更能解决一些业务交互上的一些需求:

比如根据一个字段值判断是否需要填写后续字段

【vant】打开vant表单的正确形式(基于vant表单的二次封装),javascript,前端,开发语言

又比如选实体字段时把带回来的记录显示到表单中:

【vant】打开vant表单的正确形式(基于vant表单的二次封装),javascript,前端,开发语言
下面就看看我是怎么做的吧。

实现步骤(以文本字段为例):

  • 根据字段类型封装生成该类型schema的方法
import { merge } from 'lodash-es';
import type { Props, ItemSchema } from '@/typing/helper';
import { Field } from 'vant';

/** 
 * 文本字段
 * @param field
 * @param label
 * @param props
 */
export function textField(
  field: string,
  label: string,
  props?: Props
): ItemSchema {
  return {
    component: Field,
    props: merge(
      {
        field,
        label,
        placeholder: `请输入${label}`,
        rules: props?.required
          ? [{ required: true, message: `${label}不能为空` }]
          : [],
      },
      props
    ),
  };
}
  • 把生成的schema列表遍历出来
<template>
  <Form ref="formRef">
    <template v-for="schema in formSchema" :key="schema">
      <template v-if="schema?.props?.field">
        <template v-if="calcShow(schema)">
          <component
            :is="schema.component"
            v-bind="schema.props"
            v-model="formValue[schema.props.field]"
            @change="
              (record) =>
                schema?.props?.change &&
                schema?.props?.change(record, formValue, formSchema)
            "
          />
        </template>
      </template>
      <component v-else :is="schema.component" v-bind="schema.props" />
    </template>
  </Form>
</template>

<script setup lang="ts">
  import { ref, unref, watch, computed } from 'vue';
  import { Form } from 'vant';

  import type { ItemSchema } from '@/typing/helper';

  const props = defineProps<{
    formSchema: ItemSchema[];
    modelValue: any;
  }>();
  const formValue = ref(props.modelValue);
  const formRef = ref();

  const emits = defineEmits<{
    (e: 'update:modelValue', params: any): void;
    (e: 'submit', params: any): void;
  }>();

  watch(formValue.value, (value) => {
    emits('update:modelValue', unref(value));
  });

  const calcShow = computed(
    () => (schema: ItemSchema) => schema?.props?.show === false ? false : true
  );

  defineExpose({
    // 表单校验
    validate: async () => await formRef.value.validate(),
    // 设置值(清空、回显)
    setValue: function <T>(value: T) {
      formValue.value = value;
    },
  });
</script>
<style lang="less" scoped></style>
  • 配置schema
import {
  textField,
  dividerField,
} from '@/helpers';

export const baseFormSchema: ItemSchema[] = [
  dividerField('普通文本'),
  textField('name', '姓名', { required: true }),
]
  • 使用form组件
<template>
  <div class="content">
    <code>
      <pre>{{ formValue }}</pre>
    </code>
    <TwiceForm :form-schema="baseFormSchema" v-model="formValue"></TwiceForm>
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue';
  import { TwiceForm } from '@/components';
  import { baseFormSchema } from '@/views/form/data';

  const formValue = ref({
    name: '',
    age: '',
    address: '',
    isMarried: true,
    marital: -1,
    way: 1,
    studentId: '',
  });
</script>
<style lang="less" scoped></style>

就先记录到这里,后续更新追记。感兴趣可以仓库看源码;文章来源地址https://www.toymoban.com/news/detail-545697.html

到了这里,关于【vant】打开vant表单的正确形式(基于vant表单的二次封装)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于Vant组件库二次封装组件(TS+Vue3.x环境)

    1. 今天的需求是封装一个 Navigation Bar 导航栏组件,目的是给到App几乎所有的页面复用:      2. 因为之前的项目里使用过Vant组件库,笔者第一时间想到了Vant组件库中的 NavBar 组件,和当前App的需求匹配度很高。Vant组件库的 NavBar 组件: 3. 相信你也发现了,Vant组件库默认主题

    2023年04月18日
    浏览(32)
  • axios的二次封装

    1 axios是干什么的? XMLHttpRequest、jq、fetch、axios都是用来向服务器端发送请求,并获得响应 2 为什么要进行二次封装axios? 为了封装请求拦截器,响应拦截器 请求拦截器:可以在发送请求之前可以处理一些业务 响应拦截器:当服务器数据返回以后,可以处理一些事情 在src下创

    2023年04月12日
    浏览(76)
  • 关于axios的二次封装

    @1 第一步 我们一般都会先导入axios         import axios from ‘axios’ @2 第二步 创建axios的实例 可以同时创建多个实例 每个实例配置不同         const http = axios.create( {                  // 这里面可以做一些基础的配置 比如基础路径 ,axios 请求超时的时间            

    2024年02月03日
    浏览(34)
  • Axios的二次封装(简单易懂)

    是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端 简单的理解就是ajax的封装 在使用Vue.js框架开发前端项目时 会经常发送ajax请求服务端接口 在开发过程中 需要对axios进一步封装 方便在项目中的使用 从浏览器中创建 XMLHttpRequest 从 node.js 发出 http 请求 支持 Promise API 拦截请求

    2023年04月09日
    浏览(66)
  • Vue——axios的二次封装

    在 Vue 中,发送请求一般在 created 钩子中,当然放在 mounted 钩子中也没问题。 以下请求的前提都是安装了 axios,并且 import axios from \\\'axios\\\' 成功导入 Axios官网链接 get 请求传参,在地址里面通过 ?xxx=123 的形式 post 请求传参,在第二个参数里面传递 请求配置里面可以设置很多属性

    2024年02月11日
    浏览(30)
  • Vue项目中axios的二次封装

    Vue 项目使用过程中一般会对 axios 进行二次封装, 以期在合适的时机处理一些全局的需求, 比如常见的 请求拦截器 和 响应拦截器. 接下来简单聊聊具体的操作步骤. 执行以下指令: 在 src 文件夹下创建 api 文件夹, 并创建 index.js、axios.js 和 users.js 文件. index.js 文件的作用的将当前

    2024年01月19日
    浏览(72)
  • vue中axios的二次封装——vue 封装axios详细步骤

        api统一管理,不管接口有多少,所有的接口都可以非常清晰,容易维护。     通常我们的项目会越做越大,页面也会越来越多,如果页面非常的少,直接用axios也没有什么大的影响,那页面组件多了起来,上百个接口呢,这个时候后端改了接口,多加了一个参数什么的呢

    2024年02月02日
    浏览(33)
  • jq插件:jqgrid和validform的二次封装

    做久了vue和react框架项目,偶尔也需要做做原生的项目。不可否认vue的双向绑定机制确实很香,但是也是建立在原生js基础上。所以,只有做更多的原生js项目,才能更加了解vue框架的底层原理。在日常开发中,也会不可避免的会遇到原生开发的需求。这里主要介绍下jqgrid和

    2024年02月10日
    浏览(32)
  • 【vue2小知识】实现axios的二次封装

    🥳博       主: 初映CY的前说(前端领域) 🌞个人信条: 想要变成得到,中间还有做到! 🤘 本文核心 :在vue2中实现axios的二次封装 目录 一、平常axios的请求发送方式 二、axios的一次封装 三、axios的二次封装  四、总结 【前言】我们在使用axios发送请求的时候,如果是直

    2024年02月01日
    浏览(32)
  • element ui 表格组件与分页组件的二次封装

    目录 效果图  组件封装  parseTime函数 debounce 函数 render通用渲染模版 页面使用 【扩展】vue 函数式组件 函数式组件特点: 函数式组件的优点: 【扩展】vue中的render函数 一、初步认识render函数 二、为什么使用render函数 三、render函数的解析 【扩展】添加操作栏显示权限 结构

    2024年02月08日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包