前言
我们接着上一篇文章 03-01-Vue组件的定义和注册 来讲。
下一篇文章 04-Vue:ref获取页面节点–很简单
父组件向子组件传值
我们可以这样理解:Vue实例就是一个父组件,而我们自定义的组件(包括全局组件、私有组件)就是子组件。
【重点】需要注意的是,子组件不能直接使用父组件中的数据。父组件可以通过props
属性向子组件传值。
父组件向子组件传值的代码举例
父组件:
<template>
<div id="app">
<MyComponent :msg="message"></MyComponent>
</div>
</template>
<script>
import MyComponent from './components/MyComponent.vue';
export default {
components:{
MyComponent
},
data(){
return{
message: '这是父组件中的变量'
}
}
};
</script>
子组件:
<template>
<div>
这是组件中的内容, msg: {{ msg }}
</div>
</template>
<script>
export default {
props: ['msg']
};
</script>
<style>
</style>
效果如下:
父组件给子组件传值的步骤:
根据上方截图,我们可以总结出父组件给子组件传值的步骤如下。
(1)在子组件的props
属性中声明父亲传递过来的数据
(2)使用子组件的模板时,绑定props中对应的属性
(3)父组件在引用子组件时,进行属性绑定。
子组件中,data中的数据和props中的数据的区别:
-
子组件中的 data 数据,并不是通过 父组件传递过来的,而是子组件自身私有的,比如: 子组件通过 Ajax ,请求回来的数据,都可以放到 data 身上。props 中的数据,都是通过 父组件 传递给子组件的。
-
data中的数据是可读可写的;props中的属性只是可读的,无法重新赋值,重新赋值会报错(也就是说,子组件不要直接去修改父组件中的数据)。
父组件将方法传递给子组件
父组件通过事件绑定机制,将父组件的方法传递给子组件
父组件代码:
<template>
<div id="app">
<!-- 父组件向子组件 传递 方法,是通过 事件绑定机制; v-on。当我们自定义了 一个 事件属性 parent-show(这个地方不能用驼峰命名)之后,-->
<!-- 那么,子组件就能够,通过 emit 来调用 传递进去的 这个 方法了 -->
<!-- 【第一步】。意思是说,`show`是父组件的方法名,`parent-show`是自定义的时间属性,稍后要在子组件中用到 -->
<MyComponent :msg="message" @parentShow="show"></MyComponent>
</div>
</template>
<script>
import MyComponent from "./components/MyComponent.vue";
export default {
components: {
MyComponent,
},
data() {
return {
message: "这是父组件中的变量",
};
},
methods: {
// 定义父组件的show方法
show() {
console.log("这是父组件的方法");
},
},
};
</script>
子组件代码:
<template>
<!-- 【第二步】按照正常的写法来:点击按钮,调用子组件的方法 -->
<div @click="handleClick">这是组件中的内容, msg: {{ msg }}</div>
</template>
<script>
export default {
props: ["msg"],
methods: {
handleClick() {
// 当点击子组件的按钮时,如何 拿到 父组件传递过来的 func 方法,并调用这个方法???
// emit 英文原意: 是触发,调用、发射。意思是,触发父组件的方法
// 【第三步】 在子组件的方法中,通过 emit 触发父组件的方法
this.$emit("parentShow");
},
},
};
</script>
<style>
</style>
效果如下:(点击子组件,触发了父组件的方法)
根据上面的代码,我们可以总结出,父组件将方法传递给子组件,分为三步,具体可以看上方代码的注释。
子组件向父组件传值
上面的一段中,我们再看一遍父组件将方法传递给子组件的这段代码(一定要再看一遍,因为我们是要在此基础之上做修改)。
如果要实现子组件向父组件传值,代码是类似的,我们只需要在子组件通过emit
触发父组件的方法时,把子组件的参数带出去就可以了。代码如下。
父组件代码:
<template>
<div id="app">
<MyComponent :msg="message" @parentShow="show"></MyComponent>
</div>
</template>
<script>
import MyComponent from "./components/MyComponent.vue";
export default {
components: {
MyComponent,
},
data() {
return {
message: "这是父组件中的变量",
};
},
methods: {
// 定义父组件的show方法
show(data1, data2) { //【第二步】父组件里放两个参数,这个两个参数就代表着子组件中的`childData1`、`childData2`
console.log("这是父组件的方法");
console.log('子组件传值:',data1, data2);
},
},
};
</script>
子组件代码:
<template>
<div @click="handleClick">这是组件中的内容, msg: {{ msg }}</div>
</template>
<script>
export default {
props: ["msg"],
methods: {
handleClick() {
// 子组件如果要给父组件传递参数,在触发 emit 的时候,通过参数的形式带出去就可以了
// 【第一步】在子组件里,我们带两个参数出去,传给父组件
this.$emit("parentShow", 'childData1', 'childData2');
},
},
};
</script>
<style>
</style>
运行结果:(点击之后)
代码举例2:(将子组件中的data数据传递给父组件,存放到父组件的data中)
在上方代码的基础之上,做改进。
父组件代码
<template>
<div id="app">
<MyComponent :msg="message" @parentShow="show"></MyComponent>
</div>
</template>
<script>
import MyComponent from "./components/MyComponent.vue";
export default {
components: {
MyComponent,
},
data() {
return {
message: "这是父组件中的变量",
parentData: null,
};
},
methods: {
// 定义父组件的show方法
show(arg) {//【第二步】父组件里放参数,这个参数就代表着子组件中的 child.data
console.log("父组件提供的方法");
this.parentData = arg; //将参数arg传递给父组件的data,也就达到了目的:子组件传递数据,赋值给父组件
console.log(
"打印父组件的数据(这是子组件传过来的):" +
JSON.stringify(this.parentData)
);
},
},
};
</script>
子组件代码
<template>
<div @click="handleClick">这是组件中的内容, msg: {{ msg }}</div>
</template>
<script>
export default {
props: ["msg"],
data(){
return{
childData: { //定义自组件的数据
name: 'HydeLinjr',
age: 26
}
}
},
methods: {
handleClick() {
// 子组件如果要给父组件传递参数,在触发 emit 的时候,通过参数的形式带出去就可以了
// 【第一步】在子组件里,我们带两个参数出去,传给父组件
this.$emit("parentShow", this.childData);
},
},
};
</script>
<style>
</style>
运行结果:(点击之后)