Conversation
|
@Gitzzr is attempting to deploy a commit to the weisheng's projects Team on Vercel. A member of the Team first needs to authorize it. |
✅ Deploy Preview for wot-design-uni ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
Walkthrough在 wd-input 组件的 Changes
Sequence Diagram(s)(无 —— 变更为局部的组件同步修正,未满足序列图生成条件) Estimated code review effort🎯 3 (中等) | ⏱️ ~20 分钟 可能相关的 Issue
可能相关的 PRs
建议的审查者
诗歌
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/uni_modules/wot-design-uni/components/wd-input/wd-input.vue`:
- Line 22: inputRef.value.value = newVal is a direct DOM assignment that only
works on H5 and breaks cross-platform compatibility; remove the direct DOM write
(the three lines referencing inputRef and setting .value) and rely on the
reactive v-model update via inputValue (handled in the watcher), or if you
absolutely need DOM write for H5 only, wrap that block with conditional
compilation (// `#ifdef` H5 ... // `#endif`) around the inputRef assignment; locate
the watcher/update logic using inputValue and inputRef in wd-input.vue to apply
the change.
| <slot v-else name="prefix"></slot> | ||
| </view> | ||
| <input | ||
| ref="inputRef" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check if the file exists and get its structure
cd src/uni_modules/wot-design-uni/components/wd-input && wc -l wd-input.vue && echo "---" && head -n 50 wd-input.vueRepository: Moonofweisheng/wot-design-uni
Length of output: 2403
🏁 Script executed:
# Get the specific lines mentioned in the review
cat -n src/uni_modules/wot-design-uni/components/wd-input/wd-input.vue | sed -n '1,30p'Repository: Moonofweisheng/wot-design-uni
Length of output: 1780
🏁 Script executed:
# Check lines 93, 129, 274-289
cat -n src/uni_modules/wot-design-uni/components/wd-input/wd-input.vue | sed -n '85,100p;120,135p;265,295p'Repository: Moonofweisheng/wot-design-uni
Length of output: 2314
🌐 Web query:
uni-app Vue 3 ref input element H5 WeChat mini-program behavior differences value assignment
💡 Result:
在 uni-app(Vue 3) 里,用 ref 去拿 <input> 并“直接给元素赋值”在 H5 和 微信小程序(mp-weixin) 上行为确实会不一样,核心原因是:H5 有真实 DOM;小程序逻辑层/视图层分离,没有可同步操作的 DOM。
1) H5:ref 基本等同拿到 DOM,可直接改 el.value
H5 下 <input ref="inp" /> 通常能拿到对应元素对象,因此像下面这种直接赋值一般可立即反映到界面:
inp.value.value = 'abc' // 或 inp.value.setAttribute('value','abc')2) 微信小程序:不要指望用 ref 当 DOM,用“数据驱动”更新 value
小程序端由于逻辑层与视图层分离,大多数同步 DOM API 不可用,可操作能力受限。(doc.dcloud.net.cn)
并且在 非 uni-app x 场景下,用 refs 去取“内置组件引用”往往会是 undefined(或拿到的也不是 H5 那种 DOM)。(doc.dcloud.net.cn)
因此在 mp-weixin,正确且跨端的做法是:
- 用
v-model/:value绑定数据,通过修改响应式数据来改输入框显示 - 必要时配合
nextTick确保渲染时序
示例:
<template>
<input v-model="val" />
</template>
<script setup>
import { ref, nextTick } from 'vue'
const val = ref('')
async function setVal(v){
val.value = v
await nextTick()
}
</script>3) 如果你在看 uni-app x:小程序端拿到的也只是“受限的 UniElement”,且通常要配合 id
uni-app x 文档明确提到:小程序平台如果期望用 ref 获取到 UniElement,需要在该元素上设置 id,并且小程序端 UniElement 可用属性/方法是受限的(偏样式/布局查询等)。(doc.dcloud.net.cn)
结论:
- H5 可以“ref → DOM → 直接改
.value”。 - mp-weixin 应该“改绑定数据(v-model/:value)→ 框架渲染更新”,不要依赖
ref直接给 input 元素赋值。(doc.dcloud.net.cn)
Citations:
- 1: https://doc.dcloud.net.cn/uni-app-x/mp?utm_source=openai
- 2: https://doc.dcloud.net.cn/uni-app-x/mp?utm_source=openai
- 3: https://doc.dcloud.net.cn/uni-app-x/vue/built-in.html?utm_source=openai
- 4: https://doc.dcloud.net.cn/uni-app-x/mp?utm_source=openai
🌐 Web query:
uni-app Vue 3 template ref native input element across platforms H5 小程序 APP
💡 Result:
在 uni-app(Vue 3)里,<input> 用 template ref 想“拿到原生 DOM input 元素”做跨端统一,是做不到的:只有 H5 才有真实 DOM;小程序/App(非 nvue)没有浏览器 DOM 这一层(且部分小程序里 input 聚焦时还是“原生组件”表现),因此 ref 的含义会变。(uniapp.dcloud.io)
各端 ref 能拿到什么
- H5:
ref基本可拿到 HTMLInputElement(可focus()/select()等)。 - 小程序 / App(vue 页面):不要期待拿到原生 DOM。
ref更接近“组件/元素代理对象”,并且在小程序端如果想用ref得到UniElement,通常还需要给该元素设置id,且能力受限。(doc.dcloud.net.cn)
跨端推荐做法(不要依赖原生 DOM)
1) 用 focus 属性做统一“聚焦/失焦”
<template>
<input v-model="val" :focus="focusIt" />
</template>
<script setup>
import { ref, nextTick } from 'vue'
const val = ref('')
const focusIt = ref(false)
async function focus() {
focusIt.value = false
await nextTick()
focusIt.value = true
}
</script>2) 需要“查位置/尺寸”等:用 uni.createSelectorQuery()(跨端)
createSelectorQuery 用来查节点信息(如 boundingClientRect),需要在 mounted 之后调用。(en.uniapp.dcloud.io)
注意:
nodesRef.node()主要用于取 canvas 的 Node,并不是用来获取 input 原生节点的。(en.uniapp.dcloud.io)
3) 仅 H5 才写 DOM 逻辑:用条件编译隔离
<input ref="i" />
<script setup>
import { ref, onMounted } from 'vue'
const i = ref(null)
onMounted(() => {
// `#ifdef` H5
i.value?.focus?.()
// `#endif`
})
</script>如果你具体是想做“自动聚焦 / 光标定位 / 选择文本 / 获取键盘高度适配”等哪一种,我可以按目标给你一套真正跨 H5/小程序/App 的实现方式。
Citations:
- 1: https://uniapp.dcloud.io/component/native-component?utm_source=openai
- 2: https://doc.dcloud.net.cn/uni-app-x/vue/built-in.html?utm_source=openai
- 3: https://en.uniapp.dcloud.io/api/ui/nodes-info.html?utm_source=openai
- 4: https://en.uniapp.dcloud.io/api/ui/nodes-info.html?utm_source=openai
删除或条件编译直接的 DOM 赋值,避免跨端兼容性问题
第 287 行 inputRef.value.value = newVal 直接赋值仅在 H5 生效,小程序/APP 端 ref 不能获取原生 DOM,此赋值会被忽略。由于第 284 行已通过 v-model 绑定的 inputValue.value = newVal 进行了响应式更新,直接 DOM 赋值是冗余且有害的。
建议方案:
- 完全移除第 286-288 行的 DOM 直接赋值逻辑(推荐),让 v-model 自动同步
- 或使用条件编译
//#ifdefH5包裹,仅在 H5 下执行(如有特殊需求)
相关代码位置
284: inputValue.value = newVal
285: // 强制更新 DOM
286: if (inputRef.value) {
287: inputRef.value.value = newVal
288: }
🤖 Prompt for AI Agents
In `@src/uni_modules/wot-design-uni/components/wd-input/wd-input.vue` at line 22,
inputRef.value.value = newVal is a direct DOM assignment that only works on H5
and breaks cross-platform compatibility; remove the direct DOM write (the three
lines referencing inputRef and setting .value) and rely on the reactive v-model
update via inputValue (handled in the watcher), or if you absolutely need DOM
write for H5 only, wrap that block with conditional compilation (// `#ifdef` H5
... // `#endif`) around the inputRef assignment; locate the watcher/update logic
using inputValue and inputRef in wd-input.vue to apply the change.
31a23d8 to
3fb95ef
Compare
Fix: 修复父组件修改值后 wd-input 显示不更新
🐛 问题描述
修复
wd-input组件在被二次封装时,当父组件在input事件中修改值,且修改后的值与之前的modelValue相同时,输入框显示不更新的问题。相关 Issue: #1458
📋 问题原因
当用户输入触发父组件修改值时的执行流程:
wd-input的v-model更新内部inputValue为用户输入的值@input事件中处理后emit新值(例如限制小数位)props.modelValue相同(无变化)wd-input的watch不会触发(Vue 的 watch 只在值变化时触发)inputValue与props.modelValue不一致示例场景:
123.456123.45props.modelValue之前就是123.45(无变化)watch不触发,输入框仍显示123.456🔧 修改内容
1. 添加必要的导入
2. 修改 handleInput 函数(核心修复)
修改前:
修改后:
💡 技术实现
为什么需要
nextTick?nextTick确保在父组件处理完update:modelValue事件并更新props.modelValue后再执行检查。这样可以获取到父组件处理后的最新值。为什么不使用
watch?watch只在值变化时触发。当父组件修改后的值与之前的modelValue相同时,watch不会触发,无法同步inputValue。性能影响
input事件会执行一次nextTick(微任务,性能开销极小)inputValue🧪 测试方法
测试场景 1: 限制小数位数
测试步骤:
123.456,变成123.456预期结果: 输入框显示
123.45(修复前会显示123.456)测试场景 2: 千分位格式化
测试步骤:
12345,变成12345预期结果: 输入框正确显示格式化后的值
测试场景 3: 限制输入范围
测试步骤:
999,变成999预期结果: 输入框显示
100(最大值)测试场景 4: 正常输入(无修改)
测试步骤:
预期结果: 输入框显示与输入内容一致(无影响)
📊 影响范围
受益场景
所有需要在
input事件中对值进行处理的二次封装场景:兼容性
✅ 检查清单
🔗 相关链接
📝 备注
此修复采用纯响应式方案,通过
nextTick等待父组件处理完毕后同步内部状态,无需直接操作 DOM,确保跨平台兼容性。