「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。
组件的数据通信
- 为什么要传递数据
- 子组件中的数据不能全都是写死的,而是有一部分从父组件传递过来的
(父传子)
- 为了把父组件的数据传递给子组件,子组件在标签上动态绑定了一个属性,这个属性绑定的数据,并且在子组件的 props 中注册这个属性
- 子组件如果想使用父组件的数据,就使用对应的props就可以了(父传子用props)
单向数据流:
数据只能通过父组件传递子组件,而不能直接从子组件传给父组件,子组件也不能直接修改父组件的数据;
当父组件的数据发生改变之后,子组件收到的数据也会跟着变化;直接修改从父组件中的数据会引发 vue 的报错
如果子组件想修改父组件的数据,只能通知父组件,让父组件修改数据
(子传父)
- 子组件传递父组件同过事件机制,通知父组件,让父组件修改数据;
- 父组件中使用子组件时要监听一个自定义事件,如@chang-msg=modify [事件名不要写驼峰]
- 当子组件要修改某个数据时调用
this.$emit(事件名,数据); - 子组件
$emit后,父组件收到这个事件会执行事件绑定的方法,方法的形参可以接收子组件$emit的数据 - 父组件监听事件,给事件绑定一个方法,这个方法有一个形参用于接收子组件
$emit的数据 - 子组件
$emit事件,并且传入数据;
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<son :pmsg="msg" @change-msg="modify"></son>
</div>
<script src="vue.js"></script>
<script>
let son = {
data() {
return {
msg: '123'
}
},
template: `<div>{{pmsg}} <button @click="fn">修改</button></div>`,
props: ['pmsg'],
methods: {
fn() {
this.$emit('change-msg', '12345上山打老虎');
}
}
};
let vm = new Vue({
el: '#app',
data: {
msg: 'msg from parent'
},
methods: {
modify(val) {
// console.log(val);
this.msg = val;
}
},
components: {
son
}
});
// 子组件传递给父组件通过事件机制,通知父组件,让父组件修改数据;
// 父组件中使用子组件时要监听一个自定义的事件,如上面的 @change-msg=modify 【事件名不要写驼峰】
// 当子组件要修改某个数据时调用 this.$emit(事件名, 数据);
// 子组件 $emit 后,父组件收到这个事件会执事件绑定的的方法,方法的形参可以接收子组件 $emit 的数据
// 父组件监听事件,给事件绑定一个方法,这个方法有一个形参用于接收子组件 $emit 的数据
// 子组件 emit 事件,并且传入数据
</script>
</body>
</html>
sync 修饰符和事件简写
- sync修饰符是什么?
父子组件通信时,子组件向父组件传递数据需要在父组件监听事件,在子组件触发事件. vue 为了简化处理这一过程,提供了sync修饰符和事件的简化处理;
如何使用sync修饰符
- 父组件在使用子组件时,在prop后面增加sync修饰符,取消监听事件;
- 子组件触发事件时,事件名写 update:prop 属性名
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--在 prop 后面添加 .sync 修饰符,在子组件中 emit update:prop-->
<child :money.sync="money"></child>
</div>
<script src="vue.js"></script>
<script>
let child = {
data() {
return {}
},
props: ['money'],
template: `<div>儿子:{{money}} <button @click="fn">多要压岁钱</button></div>`,
methods: {
fn() {
this.$emit('update:money', 8888)
}
}
};
let vm = new Vue({
el: '#app',
data: {
money: 200
},
components: {
child
}
})
</script>
</body>
</html>