复习vue(10)组件的数据通信

170 阅读3分钟

「这是我参与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>