ai-要約を取得 文章摘要

Vue3.2+Vite+Typescript 开发双端招聘全过程系列导航

  1. 基础环境配置(一)
  2. 可复用的页面交互逻辑(二)
  3. 个人中心模块(三) ⇦当前位置🪂
  4. 即将闪亮登场..

子组件中的标签重复渲染问题发现与解决

点击查看详情

此为一个展示账户信息的页面组件 - /src/my/components/AccountInfo.vue

<script setup lang="ts">
import { useRouter } from 'vue-router'
import { myStore } from '@/stores/my'

const store = myStore()
const router = useRouter()

const gotoPath = path => {
router.push(path)
}

if (!store.userInfo.user_name) {
store.getUserInfo()
}

console.log('accountInfo setup start')
</script>

<template>
<div class="account-info">
<p>
<label
>账户余额 <van-icon name="question-o" @click="gotoPath('/my/account/CoinExplain')"
/></label>
<span>提现<van-icon name="arrow" /></span>
</p>
<!-- 这里,逻辑上的瑕疵居然会导致该组件重复渲染,真是晕了 -->
<h3>{{ store.userInfo.account_price?.toFixed(2) ?? '0.00' }}</h3>
</div>
</template>

其中,store.userInfo.account_price?.toFixed(2) 导致控制台出现了一个有关报错,起初我没有在意,但是在父页面执行刷新时,导致该组件出现了重复二次渲染的现象。

原因为:store.userInfo 是响应式数据,当其值从 null/undefined 变为有值时会触发渲染。

其中:

  • ?. 安全访问属性
  • ?? 提供默认值

输入框 type=number时的莫名提示解决

点击查看详情

实际页面中,输入 123.45 点击提交时, 输入框会弹出一个距离最近的有效值提示,提示输入123 或124 。

这个问题的根本原因是 浏览器对 <input type="number"> 的默认行为 结合 浮点数精度处理 导致的。以下是详细分析和解决方案:


🔍 问题根源分析

  1. 浏览器对 type="number" 的默认行为

​ 当使用 <input type="number"> 时:

  • 浏览器会自动进行步进值(step)校验
  • 默认 step="1",导致浏览器会尝试将输入值对齐到最近的整数
  • 触发条件:提交表单或失去焦点时
  1. 浮点数精度问题(关键原因)
  • 当你输入 123.45 时,实际存储的值可能是 123.44999999999999(二进制浮点数误差)
  • 浏览器根据 step="1" 的规则,会将其修正为最近的整数:
    • 123.449... → 向下取整提示 123
    • 123.55 → 向上取整提示 124

🛠️ 解决方案

方案1:强制指定 step 属性(推荐)

<input 
type="number"
v-model="state.price"
step="0.01" <!-- 允许2位小数 -->
min="0"
max="50000"
>

效果

  • 明确告知浏览器允许2位小数
  • 不再进行整数修正

方案2:改用 type="text" + 自定义校验

<input 
type="text"
v-model="state.price"
@input="handlePriceInput"
pattern="^\d+(\.\d{1,2})?$" <!-- 正则验证 -->
>

JS 处理

const handlePriceInput = (e) => {
// 过滤非数字字符
state.price = e.target.value.replace(/[^\d.]/g, '')
}

方案3:精确控制数值(处理浮点数误差)

// 提交时强制修正精度
const submit = () => {
const fixedPrice = parseFloat((state.price).toFixed(2)) // 强制2位小数
// 使用 fixedPrice 提交
}

🌟 最佳实践建议

  1. 始终为 type="number" 设置明确的 step

    <input type="number" step="any">  <!-- 允许任意小数 -->
    <!-- 或 -->
    <input type="number" step="0.01"> <!-- 明确2位小数 -->