vue 父子组件传值

2022-08-29 17:37:25 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

父子组件传值 最常用的方法(4种)

1 . 父组件 传递数据 给子组件(props)vue官方文档

特别注意!!特别注意!!特别注意!! props传值的类型如果是Object类型,如对象,数组等,传递过去的是地址,在子组件中修改这些数据,会连带的把父组件中的值一并修改,强烈建议在子组件中深拷贝之后再使用这些值。然后使用$emit的形式,将修改好的值再传递给父组件,这样数据就会以一种单向的,可预测的形式进行修改(如果不深拷贝,会造成数据被修改后,很难找到修改源头,非常恶心)

父组件 父组件,定义变量testText,将这个变量传递给子组件 :testText表示:子组件那边用testText这个变量接收(这个可以随便怎么命名) 后面这个testText表示:父组件要传给子组件的变量testText

代码语言:javascript复制
<template>
	<div>
		parent-one
		<childOne :testText="testText"></childOne>
	</div>
</template>
<script> import childOne from "../components/child-one"; export default { 
     data() { 
     return { 
     testText: "这是一段传给子组件的文字", }; }, components: { 
     childOne, }, }; </script>

子组件 子组件使用props接收,父组件传递过来的数据 props的使用灵活性非常高

1.可以是数组(多个值,用逗号,隔开)

代码语言:javascript复制
props: ["testText"],

2.可以是对象(多个值,用逗号,隔开)

代码语言:javascript复制
props: { 
   
	testText: String,
	// testText: [String, Array],
	// testText: String || Array,
},

3.可以是对象,且对象属性也可以是对象,在对象中定义多种限制属性 type包括String Number Boolean Array Object Date Function Symbol

代码语言:javascript复制
props: { 
   
	testText: { 
   
		type: String,
		default: "123",
		validator: (value) => { 
   
			return ["success", "warning", "danger"].indexOf(value) !== -1;
		},
	},
},
代码语言:javascript复制
<template>
	<div>
		{ 
   { 
   this.testText}}
	</div>
</template>

<script>
export default { 
   
	data() { 
   
		return { 
   };
	},
	props: { 
   
		testText: { 
   
			type: String,
			default: "123",
			validator: (value) => { 
   
				return ["success", "warning", "danger"].indexOf(value) !== -1;
			},
		},
	},
};
</script>

2 . 在父组件中使用 $refs 调用子组件中的方法

步骤

1 . 给子组件定义一个ref属性,并命名

2 . this.$refs.属性名.子组件方法()的形式调用,也可以向子组件函数中传递参数

(需要注意的是,如果子组件使用了v-for,那么this.$refs会得到一个数组)

父组件

代码语言:javascript复制
<template>
	<div>
		parent-one
		<button @click="handle_parent">触发子组件事件</button>
		<childOne ref="childOne"></childOne>
	</div>
</template>
<script>
import childOne from "../components/child-one";
export default { 
   
	methods: { 
   
		handle_parent() { 
   
			const arr = [1, 2, 3];
			this.$refs.childOne.handle_child_one(arr);
		},
	},
	components: { 
   
		childOne,
	},
};
</script>

子组件

代码语言:javascript复制
<template>
	<div></div>
</template>

<script>
export default { 
   
	methods: { 
   
		handle_child_one(value) { 
   
			console.log("子组件child_one中的事件被触发了");
		},
	},
};
</script>

3 . 父组件使用 $children 调用子组件中的方法

注意:this.$children获取的是子组件数组

如果父组件中只定义了一个子组件,那么要使用this.$children[0].子组件方法()调用子组件中的方法 如果父组件中定义了多个子组件,【$children并不保证顺序,也不是响应式的】

而且如果一个父组件中,注册了很多个子组件的话,使用数组下标的方式定位子组件,会造成代码理解成本高,难以维护等问题,所以个人感觉这个方法比较鸡肋

代码语言:javascript复制
<template>
	<div>
		parent-one
		<button @click="handle_parent">触发子组件事件</button>
		<childOne ref="childOne"></childOne>
    	<childTwo></childTwo>
	</div>
</template>
<script>
import childTwo from "../components/child-two";
import childOne from "../components/child-one";
export default { 
   
	methods: { 
   
		handle_parent() { 
   
			this.$children[0].handle_child_one();
		},
	},
	components: { 
   
    	childTwo,
		childOne,
	},
};
</script>

4 . 子组件使用 $parent 调用父组件中的函数或者属性

$children不同,$parent获取的不是数组,而是一个父组件实例 因为:父组件中可以有很多个不同子组件 但是:子组件在同一个父组件中,只能存在一个,或者说一种,无论v-for多少个子组件,这些子组件都还是在同一个父组件中,所以在哪个父组件中引入子组件,$parent直接就指向该父组件 (所以形式上,$parent要比$children好用)

子组件

代码语言:javascript复制
<template>
	<div>
		这是子组件1
    <button @click="handle_parent">调用父组件</button>
	</div>
</template>

<script>
export default { 
   
	methods: { 
   
    handle_parent(){ 
   
      // 调用父组件中的 apply_children 函数
      this.$parent.apply_children()
    }
	},
};
</script>

而且因为this.$parent是直接获取父组件实例,所以可以通过this.$parent.父组件属性||父组件方法直接修改父组件中data中的值

5 . 子组件使用 $emit 调用父组件中的方法

老生常谈,没啥花里胡哨的,就是一个 子组件 向 父组件 通讯的方法

有两个参数,一个是 【父组件的函数名】(准确说不是父组件函数名,而是子组件在父组件中定义在子组件身上的函数名,文字比较绕,看代码吧),另一个是要传递给父组件的【参数】,注意看官方文档,函数名是个字符串,记得带上引号

父组件

代码语言:javascript复制
<template>
	<div>
		parent-one
		// 这个 @apply-children 就是子组件需要触发的事件
		<childOne ref="childOne" @apply-children="testchildren"></childOne>
	</div>
</template>
<script>
import childOne from "../components/child-one";
export default { 
   
	methods: { 
   
		testchildren(value) { 
   
			console.log("父组件parent-one中的方法被调用了");
			console.log("子组件传过来的参数:"   value);
		},
	},
	components: { 
   
		childOne,
	},
};
</script>

子组件

代码语言:javascript复制
<template>
	<div>
		这是子组件1
		<button @click="handle_parent">调用父组件</button>
	</div>
</template>

<script>
export default { 
   
	methods: { 
   
		handle_parent() { 
   
			this.$emit("apply-children",'123');
		},
	},
};
</script>

$emit

$parent

子组件向父组件通讯

子组件向父组件通讯

父子通讯常用(推荐使用)

访问组件的应急方法(应急使用)

父子通讯常用(推荐使用)

该子组件定义在多个父组件中时,虽然vue知道定义在哪个父组件,但是开发人员不是很清楚,不利于代码的维护,且 访问组件之外的上下文违反了基于模块开发的第一原则,所以我们要尽量避免使用$parent

$emit 需要触发绑定函数,子组件需要绑定一个供触发的函数

不需要任何绑定,本质是直接获取父组件实例,可以直接调用父组件中的函数、属性

6 . 子(孙)组件使用 $attr 获取父(子)组件传递过来的参数

使用场景:父、子、孙三个组件相继传值,父组件希望把值传给孙子组件,但是又不想向vuex里面添加数据时使用(当然,父子组件传值也是可以用的)

父组件 在父组件中定义两个变量,分别传给子组件,孙子组件

代码语言:javascript复制
<template>
	<div>
		parent-one
		<childOne :parent_to_child="parent_to_child" :parent_to_grand="parent_to_grand"></childOne>
	</div>
</template>
<script>
import childOne from "../components/child-one";
export default { 
   
	data() { 
   
		return { 
   
			parent_to_child: "这是一段父组件传递给子组件的数据",
			parent_to_grand: "这是一段父组件传递给子组件的数据",
		};
	},
	components: { 
   
		childOne,
	},
};
</script>

子组件 在子组件中打印一下this.$attrs

代码语言:javascript复制
<template>
	<div>
		这是子组件1
		<grandOne v-bind="$attrs"></grandOne>
	</div>
</template>

<script>
import grandOne from "./componentsGrand/grand-one";
export default { 
   
	mounted() { 
   
		console.log(this.$attrs);
	},
	components: { 
   
		grandOne,
	},
};
</script>

注意:根据官方文档,这里有个注意点用大白话说就是,this.$attrs只包含【父组件传递过来的变量,减去,props的数据】,现在我们给子组件加上props接收一个数据,其他代码不变

代码语言:javascript复制
export default { 
   
	props: ["parent_to_grand"],
	mounted() { 
   
		console.log(this.$attrs);
	},
	components: { 
   
		grandOne,
	},
};

再打印一下this.$attrs,会减去props中接受的属性

代码语言:javascript复制
<grandOne v-bind="$attrs"></grandOne>

孙组件 再使用this.$attrs获取 父组件 传递过来的参数,其中会自动过滤掉被 子组件 props 获取过的属性

孙组件

代码语言:javascript复制
<template>
	<div>
		孙子组件1
	</div>
</template>
<script>
export default { 
   
	data() { 
   
		return { 
   };
	},
	mounted() { 
   
		console.log(this.$attrs);
	},
};
</script>

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/145426.html原文链接:https://javaforall.cn

0 人点赞