基于 ChatGPT、Tailwind CSS、Vue3.0 快速开发一个表单

683 阅读2分钟

效果演示

在线演示:基于 Tailwind CSS 的报名表单页面

截图演示

需求分析

使用 Tailwind CSS,开发一个报名的表单页面。 表单项有姓名、手机号、性别、兴趣爱好、个人介绍,兼容下移动端。 手机号要做格式校验; 性别是单选框。

初始化项目

创建项目+依赖

pnpm create vite learn-tailwind-css --template vue

pnpm i -D tailwindcss postcss autoprefixer

// 创建配置文件
npx tailwindcss init -p

找到tailwind.config.js配置好content字段:

/** @type {import('tailwindcss').Config} */
export default {
  content: [    './src/**/*.{vue,js,ts,jsx,tsx}'
],
  theme: {
    extend: {},
  },
  plugins: [],
}
复制代码

把 main.css 替换为下面的内容,否则样式会出错⚠⚠⚠

@tailwind base;
@tailwind components;
@tailwind utilities;

ChatGPT 生成代码

image.png

QA 环节

QA 环节主要是了解 ChatGPT 的实现思路和原理,方便我们进行微调。

Q(我):

py-12 是什么意思

A(ChatGPT):

sm:px-6 是 Tailwind CSS 中的一种响应式类名,它表示在屏幕宽度大于等于640px 时,元素左右方向上的内边距(padding)为 6 个单位。其中 px 表示左右方向的内边距,6 是具体的数值。而在默认情况下,一个单位等于 0.25rem

因此,sm:px-6 可以让一个元素在屏幕宽度大于等于640px 时,在左右方向上添加 1.5rem 的内边距。此外,Tailwind CSS 还提供了多种响应式类名,用于根据屏幕宽度不同来调整元素样式,这也是它受欢迎的原因之一。

Q:

mt-8 sm:mx-auto sm:w-full sm:max-w-md 什么意思

A:

mt-8 sm:mx-auto sm:w-full sm:max-w-md 是一个包含多个 Tailwind CSS 类的元素样式。它表示:

  • mt-8:上方向外边距为 8 个单位(默认单位为 0.25rem,即 2rem)。
  • sm:mx-auto:在屏幕宽度大于等于 640px 时,设置水平方向的外边距为自动(即元素居中对齐)。
  • sm:w-full:在屏幕宽度大于等于 640px 时,设置元素宽度为父容器的 100%。
  • sm:max-w-md:在屏幕宽度大于等于 640px 时,设置元素最大宽度为 md(默认情况下,md 表示约 28rem)。

综合起来,这个样式可以让一个元素在移动端上有一定的上外边距并在桌面端上水平居中、宽度为 100%,同时限制其最大宽度为 md,使其不会过于宽大。

微调代码

这里我们根据自己的喜好或者需求进行微调,马上就能通过验收了。

<script setup>

</script>

<template>
<!-- 表单页面内容 -->
<div class="min-h-screen bg-gray-100 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
  <div class="sm:mx-auto sm:w-full sm:max-w-md">
    <h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900">
      报名表单
    </h2>
  </div>

  <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
    <div class="bg-white py-8 px-4 shadow rounded-lg sm:px-10">
      <form class="space-y-6" action="#" method="POST">
        <div>
          <label for="name" class="block text-sm font-medium text-gray-700">
            姓名
          </label>
          <div class="mt-1">
            <input id="name" name="name" type="text" autocomplete="name" required
              class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
            >
          </div>
        </div>
        <div>
          <label for="phone" class="block text-sm font-medium text-gray-700">
            手机号
          </label>
          <div class="mt-1">
            <input id="phone" name="phone" type="text" autocomplete="tel" required
              class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
              pattern="^1[3|4|5|7|8][0-9]{9}$"  
            >
          </div>
        </div>
        <div>
          <label class="block text-sm font-medium text-gray-700">性别</label>
          <div class="mt-2">
            <div>
              <label for="gender_male" class="inline-flex items-center">
                <input id="gender_male" type="radio" name="gender" value="male"
                  class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300"
                >
                <span class="ml-2 text-gray-900"></span>
              </label>
            </div>
            <div class="mt-2">
              <label for="gender_female" class="inline-flex items-center">
                <input id="gender_female" type="radio" name="gender" value="female"
                  class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300"
                >
                <span class="ml-2 text-gray-900"></span>
              </label>
            </div>
          </div>
        </div>
        <div>
          <label class="block text-sm font-medium text-gray-700">
            兴趣爱好
          </label>
          <div class="mt-2 space-y-2">
            <div>
              <label for="interest_music" class="inline-flex items-center">
                <input id="interest_music" type="checkbox" name="interests[]" value="music"
                  class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
                >
                <span class="ml-2 text-gray-900">音乐</span>
              </label>
            </div>
            <div>
              <label for="interest_reading" class="inline-flex items-center">
                <input id="interest_reading" type="checkbox" name="interests[]" value="reading"
                  class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
                >
                <span class="ml-2 text-gray-900">阅读</span>
              </label>
            </div>
            <div>
              <label for="interest_travelling" class="inline-flex items-center">
                <input id="interest_travelling" type="checkbox" name="interests[]" value="travelling"
                  class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
                >
                <span class="ml-2 text-gray-900">旅游</span>
              </label>
            </div>
          </div>
        </div>
        <div>
          <label for="about" class="block text-sm font-medium text-gray-700">
            个人介绍
          </label>
          <div class="mt-1">
            <textarea id="about" name="about" rows="3"
              class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md placeholder-gray-400 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm"
            ></textarea>
          </div>
          <p class="mt-2 text-sm text-gray-500">
            简要介绍自己的兴趣爱好或者其他信息。
          </p>
        </div>
        <div>
          <button 
            class="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
          >
            提交
          </button>
        </div>
      </form>
    </div>
  </div>
</div>

</template>

<style scoped>

</style>