Vue中v-for同名变量时如何传递父组件的同名数据给子组件
Vue组件作用域访问问题解答
父组件代码
<template> <div id="user"> Hello there! {{msg}} {{name}} You have below messages <Message v-for='(msg,index) in messages' :messageText='msg' :messageNumber='index+1' :welcome-msg='{{msg}}'></Message> </div> </template> <script> import Message from "./Message.vue"; export default { data () { return { msg: 'Welcome dear', name: 'Max', messages: [ 'Message 1', 'Message 2'] } }, components: { Message } } </script>
子组件代码
<template> <div> {{messageNumber}}. {{messageText}} - {{welcomeMsg}} </div> </template> <script> export default { props: { messageNumber: Number, messageText: String, welcomeMsg: String } } </script>
你的问题
你尝试将父组件中值为Welcome dear的msg数据传递给子组件,好奇是否可以通过作用域指定的方式访问父组件的msg以传递给welcome-msg属性(你已经知道可以通过修改v-for循环变量名实现,但想了解Vue特有作用域访问方法)。
解答
首先要明确两个关键点:
1. 你的代码里的语法错误
你原来写的:welcome-msg='{{msg}}'是错误的——Vue的v-bind(冒号开头的属性绑定)内部直接写变量/表达式即可,不需要嵌套插值语法{{}},正确的写法应该是:welcome-msg="msg"(不过这里的msg会被循环变量遮蔽)。
2. 如何在被遮蔽的情况下访问父组件的msg
在Vue的模板作用域中,当你处于v-for这类子作用域时,如果当前作用域的变量名和父作用域的变量名重复(比如这里循环变量叫msg,和父组件的msg重名),确实会发生变量遮蔽。此时你可以通过**$parent**来直接访问父组件的实例数据,写法如下:
<Message v-for='(msg,index) in messages' :messageText='msg' :messageNumber='index+1' :welcome-msg='$parent.msg'></Message>
这样就能绕过循环变量的遮蔽,准确拿到父组件中值为Welcome dear的msg了。
不过这里要提醒一句:$parent的写法会让子组件和父组件产生耦合,一旦组件层级变化(比如中间多了一层组件),$parent指向的对象也会改变,所以更推荐的做法还是像你补充的那样修改循环变量名,比如改成item,这样代码更清晰、更健壮:
<Message v-for='(item,index) in messages' :messageText='item' :messageNumber='index+1' :welcome-msg='msg'></Message>
额外知识点
Vue模板的作用域规则是:
- 每个组件的模板有自己独立的作用域,但子作用域(如
v-for、v-if内部)可以向上访问父级作用域的所有变量。 - 如果当前作用域有同名变量,会优先使用当前作用域的变量(即变量遮蔽)。
- 除了
$parent,Vue还提供了$root来访问根组件实例,但同样要谨慎使用,避免耦合。
内容的提问来源于stack exchange,提问作者Karthikeyan
相关产品推荐
相关产品推荐

