跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

uni-app自定义组件方法 uni-app组件之间如何传值

uni-app父子组件v-model传值需遵循value/input规范,自定义key用v-model:xxx;App端nvue不支持v-model和uni.$on;props引用类型需深拷贝;跨组件通信优先url参数+onLoad,避免ref调用。 uni-app 父子组件用
v-model
传值最省事,但得写对绑定逻辑 uni-app 的
v-model
不是原生 Vue 那套的简单糖衣——它默认只认
value
prop 和
input
事件。如果你自定义组件里用的是
props: ['msg']
+
this.$emit('change', val)
,
v-model
就会静默失效,没报错也没反应。 实操建议: 父组件写
子组件必须声明
props: ['value']
,且触发
this.$emit('input', newValue)
如果想换 key(比如用
msg
代替
value
),得显式写
v-model:msg="text"
+ 子组件
props: ['msg']
+
this.$emit('update:msg', val)
H5 和小程序平台都支持,但 App 端(nvue)不支持
v-model
,得切回
@input
+
:value
手动绑定 跨层级或非父子组件用
uni.$emit
/
uni.$on
,但别忘了销毁 uni-app 提供了全局事件总线
uni.$emit
和
uni.$on
,适合页面跳转后、兄弟组件间、或者从 uni-app 页面向自定义组件传参这种“不好直接引用”的场景。 常见错误现象:页面 A 发送事件,页面 B 的组件监听了,但 B 被关闭后监听器还在内存里,下次进 A 再发一次,B 的旧实例就又响应一遍——结果数据错乱、重复请求、甚至报
Cannot read property 'xxx' of null
。 实操建议: 在组件
mounted
里用
uni.$on('login-success', handler)
监听 必须在
beforeDestroy
(Vue 2)或
onUnload
(uni-app 生命周期)里调用
uni.$off('login-success', handler)
不要用匿名函数监听:
uni.$on('x', () => {...})
→ 后续无法
off
App 端 nvue 页面不支持
uni.$on
,得改用
uni.$emit
+ 页面级
onLoad
中监听(仅限页面)
props
传对象或数组时,子组件改了父组件数据会意外同步 这是 JS 引用类型的老问题,但在 uni-app 里更容易被忽略——因为 template 里看不出深浅拷贝,
props
又是只读警告(开发时可能关了提示),结果子组件一改
props.list.push()
,父组件的数据就变了。 使用场景:表单组件接收一个
config
对象做初始设置,用户操作后子组件想更新它并同步给父组件。 实操建议: 子组件内部要用
JSON.parse(JSON.stringify(props.obj))
或
Object.assign({}, props.obj)
做浅拷贝(仅一层) 深层嵌套对象推荐用
lodash.cloneDeep
,但注意小程序端不能直接 require,得用 npm 构建后引入 更稳妥的做法是:父组件传原始数据,所有修改都通过
$emit
抛出去,由父组件决定是否更新自身 data App 端 nvue 中,props 是深拷贝传递的,不会出现这个问题;但 H5 和微信小程序仍是引用传递 页面和自定义组件之间传值,优先走
url 参数 + onLoad
,别硬绑
ref
有人想在页面里
ref
一个自定义组件然后直接调它的方法,比如
this.$refs.child.doSubmit()
。这在 H5 上能跑,但微信小程序里
ref
指向的是虚拟节点,不是真实组件实例,调方法会报
doSubmit is not a function
;App 端 nvue 更干脆,
ref
根本不生效。 实操建议: 页面跳转传参统一走
uni.navigateTo({ url: '/pages/list/list?category=1&keyword=test' })
目标页面在
onLoad
里取
options.category
,再通过
props
传给子组件 如果需要反向触发(比如子组件要通知页面刷新),用
uni.$emit
+ 页面监听,比
ref
兼容性高得多 真要调子组件方法?只在 H5 场景下考虑,并加运行时判断:
if (uni.getSystemInfoSync().platform === 'h5') { this.$refs.child?.doX() }
复杂点在于不同平台对响应式机制和事件系统的实现差异太大,同一个写法在 H5 行、小程序卡、App 端直接挂——传值逻辑得按平台兜底,而不是指望一套代码全跑通。

相关文章