Vue 输入框样式定制(圆角 / 特殊样式 / 场景化)

Vue 中输入框(<input>/<textarea>)的样式定制核心是 CSS 样式 + Vue 动态绑定,以下覆盖「基础圆角输入框」「不同风格输入框(渐变 / 磨砂 / 搜索框)」「场景化输入框(验证码 / 密码 / 多行文本)」,适配 Vue2/Vue3,支持 <script setup> 和选项式 API。

一、基础圆角输入框(常用)

核心通过 CSS 的 border-radius 控制圆角,搭配 border/padding/focus 优化交互,Vue 中可封装为通用组件复用。

1. 基础圆角输入框组件(Vue3 + <script setup>

vue

<!-- components/InputRound.vue -->
<template>
  <div class="input-wrapper">
    <!-- 基础输入框 -->
    <input
      type="text"
      class="round-input"
      :placeholder="placeholder"
      v-model="inputValue"
      @input="$emit('update:modelValue', inputValue)"
    />
  </div>
</template>

<script setup>
import { ref, defineProps, defineEmits } from 'vue';

// 声明Props(支持自定义占位符、初始值)
const props = defineProps({
  placeholder: {
    type: String,
    default: '请输入内容'
  },
  modelValue: {
    type: String,
    default: ''
  }
});

// 声明事件(双向绑定)
const emit = defineEmits(['update:modelValue']);

// 本地值绑定
const inputValue = ref(props.modelValue);
</script>

<style scoped>
/* 外层容器(可选,用于统一布局) */
.input-wrapper {
  width: 300px;
  margin: 10px 0;
}

/* 圆角输入框核心样式 */
.round-input {
  /* 圆角:数值越大越圆,50%为圆形(需固定宽高) */
  border-radius: 8px; 
  /* 基础样式 */
  width: 100%;
  height: 40px;
  padding: 0 12px;
  border: 1px solid #e5e7eb; /* 浅灰色边框 */
  font-size: 14px;
  box-sizing: border-box; /* 防止padding撑大宽度 */
  outline: none; /* 清除默认聚焦外框 */
  transition: all 0.2s; /* 过渡动画 */
}

/* 聚焦状态 */
.round-input:focus {
  border-color: #409eff; /* 蓝色边框 */
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2); /* 聚焦光晕 */
}

/* 禁用状态 */
.round-input:disabled {
  background-color: #f9fafb;
  color: #9ca3af;
  cursor: not-allowed;
}

/* 错误状态(可通过动态class绑定) */
.round-input.error {
  border-color: #ef4444;
}
</style>

2. 父组件使用

vue

<template>
  <div>
    <h3>基础圆角输入框</h3>
    <InputRound 
      placeholder="请输入用户名" 
      v-model="username" 
    />
    <!-- 错误状态示例 -->
    <InputRound 
      placeholder="请输入手机号" 
      v-model="phone" 
      :class="{ error: !phone }"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import InputRound from './components/InputRound.vue';

const username = ref('');
const phone = ref('');
</script>

3. 不同圆角效果参考

样式需求border-radius 值效果描述
轻微圆角4px/6px简约风格,适配大部分场景
明显圆角8px/12px主流移动端风格
胶囊型输入框20px/50px高度 40px 时,20px 为胶囊型
圆形输入框50%需固定宽高相等(如 40px)

二、特殊风格输入框(渐变 / 磨砂 / 搜索框)

基于基础圆角样式,扩展个性化风格,适配不同 UI 设计需求。

1. 渐变边框输入框

vue

<template>
  <div class="gradient-input-wrapper">
    <input
      type="text"
      class="gradient-input"
      placeholder="渐变边框输入框"
      v-model="value"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue';
const value = ref('');
</script>

<style scoped>
.gradient-input-wrapper {
  width: 300px;
  padding: 2px; /* 渐变背景的宽度 */
  background: linear-gradient(90deg, #409eff, #67c23a); /* 渐变 */
  border-radius: 8px; /* 和输入框圆角一致 */
}

.gradient-input {
  width: 100%;
  height: 40px;
  padding: 0 12px;
  border: none; /* 隐藏默认边框 */
  border-radius: 6px; /* 比外层小2px,露出渐变边框 */
  background: #fff;
  outline: none;
  box-sizing: border-box;
}
</style>

2. 磨砂玻璃输入框(毛玻璃效果)

vue

<template>
  <div class="glass-bg"> <!-- 磨砂背景容器 -->
    <input
      type="text"
      class="glass-input"
      placeholder="磨砂玻璃输入框"
      v-model="value"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue';
const value = ref('');
</script>

<style scoped>
/* 背景容器 */
.glass-bg {
  width: 300px;
  padding: 20px;
  background: url('https://picsum.photos/800/400') no-repeat center;
  background-size: cover;
  border-radius: 12px;
}

/* 磨砂输入框 */
.glass-input {
  width: 100%;
  height: 44px;
  padding: 0 16px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.2); /* 半透明 */
  backdrop-filter: blur(10px); /* 磨砂核心 */
  -webkit-backdrop-filter: blur(10px); /* 兼容webkit */
  color: #fff;
  outline: none;
  font-size: 14px;
}

.glass-input::placeholder {
  color: rgba(255, 255, 255, 0.7);
}
</style>

3. 带图标的搜索输入框

vue

<template>
  <div class="search-input-wrapper">
    <svg class="search-icon" viewBox="0 0 1024 1024" width="16" height="16">
      <path fill="#9ca3af" d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.3 256.6 112 331.8 112 412c0 80.2 31.3 155.4 87.9 212.1C256.6 680.7 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0 0 11.6 0l43.6-43.5a8.2 8.2 0 0 0 0-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C205.3 528 182 471.8 182 412s23.3-116 65.6-158.4C296 205.3 352.2 182 412 182s116 23.3 158.4 65.6C612.7 296 636 352.2 636 412s-23.3 116-65.6 158.4z"></path>
    </svg>
    <input
      type="text"
      class="search-input"
      placeholder="请输入搜索内容"
      v-model="searchValue"
    />
    <button v-if="searchValue" class="clear-btn" @click="searchValue = ''">×</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
const searchValue = ref('');
</script>

<style scoped>
.search-input-wrapper {
  display: flex;
  align-items: center;
  width: 300px;
  height: 40px;
  padding: 0 12px;
  border: 1px solid #e5e7eb;
  border-radius: 20px; /* 胶囊型 */
  background: #fff;
}

.search-icon {
  margin-right: 8px;
  flex-shrink: 0;
}

.search-input {
  flex: 1;
  height: 100%;
  border: none;
  outline: none;
  font-size: 14px;
  background: transparent;
}

.clear-btn {
  width: 16px;
  height: 16px;
  border: none;
  background: transparent;
  color: #9ca3af;
  font-size: 16px;
  cursor: pointer;
  padding: 0;
  margin-left: 8px;
}
</style>

三、场景化输入框(验证码 / 密码 / 多行文本)

1. 验证码输入框(6 位数字,格子样式)

vue

<template>
  <div class="code-input-wrapper">
    <input
      v-for="(item, index) in 6"
      :key="index"
      class="code-input"
      type="text"
      maxlength="1"
      v-model="codeList[index]"
      @input="handleCodeInput(index)"
      @focus="focusIndex = index"
    />
  </div>
</template>

<script setup>
import { ref, watch } from 'vue';

// 验证码数组
const codeList = ref(['', '', '', '', '', '']);
// 当前聚焦索引
const focusIndex = ref(0);

// 输入后自动聚焦下一个
const handleCodeInput = (index) => {
  if (codeList.value[index] && index < 5) {
    const nextInput = document.querySelectorAll('.code-input')[index + 1];
    nextInput?.focus();
  }
};

// 监听验证码完成
watch(
  () => codeList.value.join(''),
  (code) => {
    if (code.length === 6) {
      console.log('验证码输入完成:', code);
    }
  }
);
</script>

<style scoped>
.code-input-wrapper {
  display: flex;
  justify-content: space-between;
  width: 300px;
}

.code-input {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  text-align: center;
  font-size: 18px;
  outline: none;
}

.code-input:focus {
  border-color: #409eff;
}
</style>

2. 密码输入框(带显示 / 隐藏切换)

vue

<template>
  <div class="password-input-wrapper">
    <input
      :type="showPwd ? 'text' : 'password'"
      class="password-input"
      placeholder="请输入密码"
      v-model="password"
    />
    <button class="pwd-toggle-btn" @click="showPwd = !showPwd">
      {{ showPwd ? '隐藏' : '显示' }}
    </button>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const password = ref('');
const showPwd = ref(false);
</script>

<style scoped>
.password-input-wrapper {
  display: flex;
  align-items: center;
  width: 300px;
  height: 40px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 0 12px;
}

.password-input {
  flex: 1;
  height: 100%;
  border: none;
  outline: none;
  font-size: 14px;
}

.pwd-toggle-btn {
  width: 40px;
  height: 24px;
  border: none;
  background: #f3f4f6;
  border-radius: 4px;
  color: #666;
  font-size: 12px;
  cursor: pointer;
}
</style>

3. 多行文本输入框(textarea 圆角 + 自适应高度)

vue

<template>
  <textarea
    class="textarea-input"
    placeholder="请输入多行内容"
    v-model="content"
    :style="{ height: `${textareaHeight}px` }"
    @input="autoResize"
  ></textarea>
</template>

<script setup>
import { ref, onMounted } from 'vue';

const content = ref('');
const textareaHeight = ref(80); // 初始高度

// 自适应高度
const autoResize = (e) => {
  // 重置高度为自动,获取滚动高度,再设置
  e.target.style.height = 'auto';
  textareaHeight.value = e.target.scrollHeight;
  // 限制最大高度
  if (textareaHeight.value > 200) {
    textareaHeight.value = 200;
  }
};

// 初始化时执行一次
onMounted(() => {
  autoResize({ target: document.querySelector('.textarea-input') });
});
</script>

<style scoped>
.textarea-input {
  width: 300px;
  padding: 12px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  outline: none;
  resize: none; /* 禁用手动调整大小 */
  font-size: 14px;
  line-height: 1.5;
  transition: border-color 0.2s;
  box-sizing: border-box;
}

.textarea-input:focus {
  border-color: #409eff;
}
</style>

四、Vue 动态样式绑定(进阶)

通过 Vue 的 :class/:style 动态控制输入框样式,适配不同状态。

示例:根据状态切换输入框样式

vue

<template>
  <input
    type="text"
    v-model="value"
    :class="[
      'base-input',
      { 'input-success': isSuccess },
      { 'input-error': isError },
      { 'input-large': size === 'large' }
    ]"
    :style="{ borderRadius: radius + 'px' }"
  />
</template>

<script setup>
import { ref, computed } from 'vue';

const value = ref('');
const isSuccess = ref(false);
const isError = ref(false);
const size = ref('large');
const radius = ref(8); // 动态控制圆角

// 校验输入内容
const checkValue = () => {
  if (!value.value) {
    isError.value = true;
    isSuccess.value = false;
  } else {
    isError.value = false;
    isSuccess.value = true;
  }
};
</script>

<style scoped>
.base-input {
  width: 300px;
  height: 40px;
  padding: 0 12px;
  border: 1px solid #e5e7eb;
  outline: none;
  transition: all 0.2s;
}

.input-success {
  border-color: #67c23a;
}

.input-error {
  border-color: #ef4444;
}

.input-large {
  height: 48px;
  font-size: 16px;
  border-radius: 12px;
}
</style>

五、

建议:

  1. 兼容性backdrop-filter(磨砂)需兼容移动端,可加 -webkit- 前缀;
  2. 无障碍:输入框需加 placeholderaria-label,聚焦状态需明显;
  3. 性能:避免频繁动态修改 border-radius 等样式(触发重绘),优先用 class 切换;
  4. 复用性:将常用输入框封装为组件(如 InputRound/InputSearch),通过 Props 控制样式;
  5. 适配:移动端输入框高度建议 44px(符合触控习惯),PC 端 36-40px。

核心:

  • 基础样式:border-radius 控制圆角,focus/disabled 优化交互;
  • 特殊样式:渐变 / 磨砂依赖 CSS 背景 / 滤镜,图标输入框依赖 Flex 布局;
  • 动态控制:通过 :class/:style 绑定 Vue 状态,适配不同场景;
  • 场景化:验证码 / 密码框需结合交互逻辑(自动聚焦 / 显示隐藏),多行文本需自适应高度。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值