【vue3组件封装】含校验的Input

这篇博客介绍了Vue组件SInput的用法,它是一个带有自定义校验规则的输入框。当失去焦点时,SInput会进行校验,并在输入值不符合规则时显示错误信息。校验规则通过数组形式传递,每个规则包含类型和错误提示。博客中还展示了如何定义和使用各种校验函数,如检查是否为空、是否为IP地址等。此外,还展示了组件的完整代码实现,包括模板、脚本和样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码:https://gitee.com/chenxiangzhi/components.git
历史文章:

  1. 复选框和单选框
  2. Form和FormItem

效果

  • 失去焦点时会进行校验
  • 更新数据后会传回一个对象,包含namevalue
    在这里插入图片描述

使用

<template>
    <s-input 
        @update="updateForm" 
        name="ip" 
        :value="state.ip"
        :rules="[
           { type: 'required', message: 'ip不能为空' },
           { type: 'ip', message: 'ip格式不对' },
        ]"
    />
</template>


<script lang="ts" setup>
import { reactive } from "vue"
import { SInput } from "@/components"
const state = reactive({
  ip: ""
})
const updateForm = (param) => {
  state[param.name] = param.value
}
</script>

校验规则传的是一个数组,里面每个元素包含type校验种类与message校验失败时的提示说明。每个type校验种类将对应于一个校验函数,这由自己自定义。

Types

// 属性
type InputProp={
  type: string,				// 输入框类型
  name: string,
  value: string|number|boolean,
  placeholder?: string,
  rules?: RuleProp[],			// 校验规则
  inputStyle: Object			// 输入框样式
}

// 校验类型:每个校验类型会对应一个校验函数。
type RuleKeys = "required" | "ip" | "port" | "range"; 
interface IRuleStrategies {
   [index in RuleKeys]: (...params: any[]) => boolean;
   [index: string]: (...params: any[]) => boolean;
}

// 校验对象
interface RuleProp {
   type: RuleKeys;
   message: string;
}

SInput

<template>
    <div class="input-container">
        <input
            :type="type"
            class="input-control"
            @blur="testError"
            :value="value"
            @input="input"
            :class="{ 'is-invalid': inputRef.error }"
            :placeholder="placeholder"
            :style="{...inputStyle }"
        />
        <div v-if="inputRef.error" class="error-text">
            {{ inputRef.message }}
        </div>
    </div>
</template>

<script lang="ts" setup>
import { PropType, reactive } from "vue"
import { RuleProp } from "@types"
import { ruleStrategies } from "@/utils"

const emitFn = defineEmits(["update"])
const props = defineProps({
  type: {
    type: String,
    default: "text"
  },
  name: String,
  value: [String, Number, Boolean],
  placeholder: String,
  rules: Array as PropType<RuleProp[]>,
  inputStyle: Object
})

// 响应式错误信息
const inputRef = reactive({
  error: false,
  message: ""
})

// 检查错误
const testError = () => {
  if (props.rules) {
   // 对所有校验规则进行校验,只要有一个不通过就为不通过
    const allPassed = props.rules.every((rule: RuleProp) => {
      let passed = true
      // 首先将错误说明赋值给响应式对象inputRef
      inputRef.message = rule.message
     	// 接着在校验函数中找到对应的校验函数进行校验
      passed = ruleStrategies[rule.type](props.value) // 根据校验类型判断是否通过
      return passed
    })
    // 主要有不通过的,就会显示错误信息
    inputRef.error = !allPassed
  }
}

// 传回数据
const input = (e: Event) => {
  const targetValue = (e.target as HTMLInputElement).value
  emitFn("update", { name: props.name, value: targetValue })  // 传回一个对象
}
</script>

<style lang="less">
.input-container {
   .input-control{
      padding: 4px 10px;
      border-radius: @smallRadius;
      border: 1px solid @borderColor;
      align-items: center;
      font-size: 1em;
      &:focus{
         border: 1px solid @activeColor;
         outline: 2px solid @mainColor;
      }
   }
   .error-text{
      padding:6px 0 0 1px;
      color:@danger;
      text-align:left;
   }
}
</style>

校验函数

import {IRuleStrategies} from '@types'

// 判断是否为空
const isRequired=(val:string):boolean=>{
    return val!== ""
}

// 判断是否为整数
const isInteger=(value:any)=>{
    return Number.isInteger(Number(value))
}

// 判断是否为ip
const isIp=(ip:string):boolean=>{
    var rep = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
    return rep.test(ip)
}

// 判断端口是否合法
const isPort=(port:number):boolean=>{
    if(!isInteger(port)||65535<port||port<1){
        return false;
    }  
    return true;
}

// 判断整数范围
const isInRange:number,max:number=20,min:number=-10):boolean=>{
    if(!isInteger(value)||value>max||min<-10){
        return false
    }
    return true
}

// 导出校验策略
export const ruleStrategies:IRuleStrategies={
    "required":isRequired,
    "ip":isIp,
    "port":isPort,
    "range":isInRange
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值