【vue】$parent和$children的使用

  • 父组件访问子组件:使用$children$refs reference
  • 子组件访问父组件:使用$parent

$parent

<body>
		<div id="app">
			<mxc></mxc>
		</div>
		<template id="mxc">
			<div>我是子组件啊</div>
			<button @click="btnClick">更加颤抖的child</button>
		</template>
		
		<script>
			const app=new Vue({
				el:'#app',
				data:{
					message:'你好'
				},
				components:{
					mxc:{
						template:'#mxc',
						methods:{
							btnClick(){
								console.log(this.$parent)
							}
						}
					}
				}
			})
		</script>
	</body>

在这里插入图片描述
(但是在实际中$parent用的非常少——考虑到耦合度的原因)

子组件访问根组件:$root

	<body>
		<div id="app">
			<mxc></mxc>
		</div>
		<template id="mxc">
			<div>
				<div>我是mxc组件</div>
				<cdn></cdn>
			</div>
		</template>
		<template id="mxca">
			<div>
				<div>我是子子组件啊</div>
				<button @click="btnClick">巨颤祖child</button>
			</div>
		</template>
		
		<script>
			const app=new Vue({
				el:'#app',
				data:{
					message:'你好'
				},
				components:{
					mxc:{
						template:'#mxc',
						data(){
							return{
								name:'我是中间子组件的name'
							}
						},
						components:{
							cdn:{
								template:'#mxca',
								methods:{
									btnClick(){
										console.log(this.$parent.name)
										console.log(this.$root.message)
									}
								}
							}
						}
					}
				}
			})
		</script>
	</body>

在这里插入图片描述

$children

children很特别,查阅资料可以发现:this.$children是一个数组类型,它包含了所有子组件对象:

<body>
	<div id="app">
		<mxc></mxc>
		<mxc></mxc>
		<mxc></mxc>
		<button @click="btnClick">颤抖吧</button>
	</div>
	<template id="mxc">
		<div>我是子组件啊</div>
	</template>
	
	<script>
		const app=new Vue({
			el:'#app',
			data:{
				message:'你好'
			},
			methods:{
				btnClick(){
					console.log(this.$children)
				}
			},
			components:{
				mxc:{
					template:'#mxc',
					methods:{
						showMessage(){
							console.log('mxcnb')
						}
					}
				}
			}
		})
	</script>
</body>

点击(父组件)按钮之后:
在这里插入图片描述
我们还可以通过循环拿到所有子组件数据:

<body>
	<div id="app">
		<mxc></mxc>
		<mxc></mxc>
		<mxc></mxc>
		<button @click="btnClick">颤抖吧</button>
	</div>
	<template id="mxc">
		<div>我是子组件啊</div>
	</template>
	
	<script>
		const app=new Vue({
			el:'#app',
			data:{
				message:'你好'
			},
			methods:{
				btnClick(){
					console.log(this.$children)
					for(let c of this.$children){
						console.log(c.name)
					}
				}
			},
			components:{
				mxc:{
					template:'#mxc',
					data(){
						return{
							name:'我是子组件的name'
						}
					},
					methods:{
						showMessage(){
							console.log('mxcnb')
						}
					}
				}
			}
		})
	</script>
</body>

点击(父组件)按钮之后:
在这里插入图片描述
因为是数组,所以我们可以通过比如:this.$children[2]来拿到第三个子组件的数据。
但是这么做有一个问题:比如开发时突然在这三个子组件中又插入了一个子组件(可能相同,也可能不同),这时候【2】就不再是我们需要的了。。。

所以我们可以用vue-DOM之光:$refs

<body>
	<div id="app">
		<mxc></mxc>
		<mxc></mxc>
		<mxc ref="aaa"></mxc>
		<button @click="btnClick">颤抖吧</button>
	</div>
	<template id="mxc">
		<div>我是子组件啊</div>
	</template>
	
	<script>
		const app=new Vue({
			el:'#app',
			data:{
				message:'你好'
			},
			methods:{
				btnClick(){
					console.log(this.$refs)
					console.log(this.$refs.aaa)
				}
			},
			components:{
				mxc:{
					template:'#mxc',
					data(){
						return{
							name:'我是子组件的name'
						}
					},
					methods:{
						showMessage(){
							console.log('mxcnb')
						}
					}
				}
			}
		})
	</script>
</body>

点击(父组件)按钮之后:
在这里插入图片描述

为什么叫“DOM之光”呢?因为它和原生JS中的document.querySelector(‘xxx’)功能一样,它可以在vue中获取元素/匹配组件

参考:
vue父子组件间引用: p a r e n t 、 parent、 parentchildren

<think>我们正在讨论Vue.js中的$parent$children属性。根据用户的要求,我们需要提供用法示例。注意,用户提供的引用内容中并没有直接关于$parent$children的示例,但我们可以结合Vue.js的官方知识来回答。 在Vue.js中,每个组件实例都有$parent$children属性: - $parent:指向父组件实例(如果当前组件有父组件) - $children:指向当前组件的直接子组件实例数组(注意:不保证顺序,也不是响应式的) 但是,官方文档通常建议避免直接使用$parent$children,因为这样会使组件间形成紧耦合。推荐使用propsevents进行父子组件通信。然而,在某些情况下,直接访问父组件或子组件可能是必要的。 下面我们将通过示例来展示$parent$children的用法。 ### 示例1:访问父组件($parent) 假设有一个父组件一个子组件,子组件通过$parent访问父组件的数据或方法。 父组件(ParentComponent.vue): ```vue <template> <div> <child-component></child-component> </div> </template> <script> import ChildComponent from './ChildComponent.vue' export default { components: { ChildComponent }, data() { return { parentMessage: 'Hello from Parent' } }, methods: { parentMethod() { console.log('Parent method called') } } } </script> ``` 子组件(ChildComponent.vue): ```vue <template> <div> <button @click="callParentMethod">Call Parent Method</button> </div> </template> <script> export default { methods: { callParentMethod() { // 通过$parent访问父组件的属性或方法 console.log(this.$parent.parentMessage) // 输出:Hello from Parent this.$parent.parentMethod() // 输出:Parent method called } } } </script> ``` ### 示例2:访问子组件($children) 父组件通过$children数组访问子组件的实例。 父组件(ParentComponent.vue): ```vue <template> <div> <child-component ref="firstChild"></child-component> <child-component ref="secondChild"></child-component> <button @click="callChildMethods">Call Child Methods</button> </div> </template> <script> import ChildComponent from './ChildComponent.vue' export default { components: { ChildComponent }, methods: { callChildMethods() { // 通过$children访问子组件 // 注意:$children是一个数组,但不保证顺序,所以通常使用ref来获取特定子组件 this.$children.forEach(child => { child.childMethod() }) } } } </script> ``` 子组件(ChildComponent.vue): ```vue <template> <div> Child Component </div> </template> <script> export default { methods: { childMethod() { console.log('Child method called') } } } </script> ``` ### 注意事项 1. **$children的局限性**:$children并不保证顺序,且不是响应式的。如果子组件是动态渲染的(例如使用v-for),$children数组可能不会按预期更新。因此,官方建议使用refs来直接访问子组件。 使用refs的示例: ```vue <template> <div> <child-component ref="firstChild"></child-component> <child-component ref="secondChild"></child-component> <button @click="callChildMethods">Call Child Methods</button> </div> </template> <script> import ChildComponent from './ChildComponent.vue' export default { components: { ChildComponent }, methods: { callChildMethods() { // 通过refs访问 this.$refs.firstChild.childMethod() this.$refs.secondChild.childMethod() } } } </script> ``` 2. **紧耦合问题**:使用$parent$children会使组件间形成紧耦合,使得组件难以复用测试。因此,在可能的情况下,优先使用propsevents进行通信。 3. **边界情况**:在根实例上,$parent为undefined,在根实例的子组件中,$parent指向根实例。 ### 替代方案 - **Props向下传递数据**:父组件通过props向子组件传递数据。 - **Events向上传递消息**:子组件通过$emit触发事件,父组件监听事件。 - **Provide/Inject**:在祖先组件中提供数据,然后在后代组件中注入。适用于跨多级组件传递数据,避免逐层传递props。 ### 总结 虽然Vue提供了$parent$children属性来访问父组件子组件,但在实际开发中应谨慎使用,因为它们会使组件间形成紧耦合。在大多数情况下,使用propsevents是更好的选择。如果需要跨层级通信,可以考虑使用Vuex或Provide/Inject。 §§相关问题§§ 1. Vue.js中如何通过refs访问子组件? 2. Vue.js中provide/inject的使用场景是什么? 3. Vue.js中如何避免组件间的紧耦合?</think>### Vue.js 中 `$parent` `$children` 用法详解 在 Vue.js 中,`$parent` `$children` 是组件实例的内置属性,用于访问组件的父子关系。它们提供了一种直接访问组件层级的方式,但需谨慎使用以避免过度耦合。以下是具体用法示例: --- #### 一、核心概念 1. **`$parent`** - 指向当前组件的**直接父组件实例** - 如果当前组件是根组件,则 `$parent` 为 `undefined` - 示例:`this.$parent` 获取父组件 2. **`$children`** - 包含当前组件的**直接子组件实例数组** - 数组顺序与模板中子组件顺序一致(但不保证动态组件的顺序) - 示例:`this.$children[0]` 获取第一个子组件 --- #### 二、使用示例 ##### 1. 通过 `$parent` 访问父组件数据/方法 ```vue <!-- 父组件 ParentComponent.vue --> <template> <div> <child-component /> <p>父组件数据: {{ message }}</p> </div> </template> <script> export default { data() { return { message: "Hello from Parent" }; }, methods: { parentMethod() { console.log("父组件方法被调用"); } } } </script> ``` ```vue <!-- 子组件 ChildComponent.vue --> <template> <button @click="callParent">调用父组件方法</button> </template> <script> export default { methods: { callParent() { // 访问父组件数据 console.log(this.$parent.message); // "Hello from Parent" // 调用父组件方法 this.$parent.parentMethod(); // 输出: "父组件方法被调用" } } } </script> ``` ##### 2. 通过 `$children` 操作子组件 ```vue <!-- 父组件 ParentComponent.vue --> <template> <div> <child-component ref="firstChild" /> <child-component /> <button @click="updateChildren">更新所有子组件</button> </div> </template> <script> export default { methods: { updateChildren() { // 遍历所有直接子组件 this.$children.forEach(child => { child.childMethod(); // 调用子组件方法 }); // 通过 ref 获取特定子组件 this.$refs.firstChild.specificMethod(); } } } </script> ``` ```vue <!-- 子组件 ChildComponent.vue --> <script> export default { methods: { childMethod() { console.log("子组件方法被调用"); }, specificMethod() { console.log("特定子组件方法"); } } } </script> ``` --- #### 三、注意事项 1. **避免过度依赖** - 使用 `$parent/$children` 会导致组件紧耦合,降低可复用性 - 优先使用 **Props/Events** 进行父子通信 2. **动态组件问题** `$children` 数组顺序不保证与动态组件(如 `v-if`)的顺序一致: ```vue <div> <child-a v-if="showA" /> <child-b /> </div> ``` 当 `showA` 变化时,`$children` 索引可能改变。 3. **替代方案推荐** - **Props 向下传递数据** ```vue <!-- 父组件 --> <child :message="parentData" /> ``` - **Events 向上传递消息** ```vue <!-- 子组件 --> <button @click="$emit('notify')">通知父组件</button> ``` - **Provide/Inject** 用于深层嵌套组件(跨多级传递)[^1] - **Vuex 状态管理** 复杂场景使用全局状态管理 4. **特殊场景应用** - 在 UI 库开发中操作嵌套组件(如树形控件)[^3] - 面包屑导航组件中访问路由层级[^2] --- ### 总结 | 属性 | 指向 | 使用场景 | 注意事项 | |--------------|--------------------|-----------------------------------|------------------------------| | **`$parent`** | 直接父组件实例 | 紧急修复/快速原型开发 | 破坏组件封装性 | | **`$children`**| 直接子组件实例数组 | 批量操作子组件 | 动态组件顺序不可靠 | **最佳实践**: 在大多数场景下,优先使用 **Props/Events** 或 **Vuex** 进行组件通信。`$parent/$children` 应作为最后手段,仅用于特殊需求或开发工具库[^4]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值