复习vue(11)组件通信(兄弟传参 || 祖孙传参)

194 阅读2分钟

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。

组件通信(兄弟传参 || 祖孙传参)

事件总线 EventBus

  • 什么是事件总线?
    • 每个组件都是一个vue的实例,相互之间不能互通数据;
    • 要修改数据一定要通知,所以找一个第三方,让第三方监听事件,在事件触发时执行对应的修改数据操作.这个第三方就是事件总线; -事件总线的的用法:
    • 创建一个空的vue实例: let eventBus = new Vue();
    • eventBus.$on(自定义事件名,函数名)监听事件
    • eventBus.$emit(事件名) 触发事件
示例代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>

<body>

  <div id="app">
    <prev></prev>
    <next></next>
  </div>

  <script src="vue.js"></script>
  <script>
    // 每个组件都是一个 Vue的实例,相互之间不能互通数据;
    // 要修改数据一定要通知,所以找一个第三方,让第三方监听事件,在事件触发时执行对应的修改数据的操作;
    // eventBus.$on(自定义事件名, 事件函数) 监听事件
    // eventBus.$emit(事件名) 触发事件

    let eventBus = new Vue(); // 这第三方就是一个空的 Vue 实例,叫做事件总线 EventBus
    let prev = {
      data() {
        return {
          color: 'green'
        }
      },
      created() {
        eventBus.$on('changeRed', this.toRed) // 监听 changeRed 事件,当事件触发时,会执行 this.toRed 方法
      },
      methods: {
        toRed(x) {
          console.log(x); // x 是事件触发时,传递的数据
          this.color = 'red';
        }
      },
      template: `<div :style="{background: color}">{{color}}</div>`
    };
    let next = {
      data() {
        return {
          color: '红色'
        }
      },
      methods: {
        red() {
          eventBus.$emit('changeRed', 'hahaha')
        }
      },
      template: `<div><button @click="red">变红</button></div>`
    };

    let vm = new Vue({
      el: '#app',
      data: {},
      components: {
        prev,
        next
      }
    });
  // 兄弟组件之间通信,通过 EventBus,
  // 谁的数据需要被改变,谁监听事件,谁发起改变谁触发事件;
  // 例如本例中,next 要修改 prev 的数据,
  // 所以在 prev 的 created 中 eventBus.$on() 监听事件,
  // 而 next 发起改变,所以在 next 中 $emit() 事件;

  // 哥哥改弟弟同理;

  </script>
</body>

</html>


keep-alive(动态组件补充)

  • 什么是 keep-alive?

component 虽然可以绑定动态组件,但是在组件切换时,原来的组件就会被销毁,数据会丢失,为了解决这个问题我们使用keep-alive;

包裹动态组件时,会缓存不活动的组件实例,而不是销毁他们

代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>

<body>

  <div id="app">
    <label>HOME <input type="radio" value="home" v-model="title"></label>
    <label>List <input type="radio" value="list" v-model="title"></label>
    <keep-alive>
      <component :is="title"></component>
    </keep-alive>

  </div>

  <script src="vue.js"></script>
  <script>
    //   创建组件
    //   动态组件在进行切换时,会将上一个组件销毁,然后再挂载最新的组件
    //   动态组件,需要使用内置的 component 组件 // <component :is="title"></component>
    //   在这个组件上有一个 is 属性,动态绑定该属性,当被绑定的值发生变化时,Vue 会渲染 is 最新的值对应的组件;
    let home = {
      template: `<div>HOME <input type="text" v-model="home"></div>`,
      data() {
        return {
          home: ''
        }
      },
      mounted() {
        console.log('挂载home')
      },
      destroyed() {
        console.log('home销毁')
      }
    };

    let list = {
      template: `<div>LIST <input type="text" v-model="list"></div>`,
      data() {
        return {
          list: ''
        }
      },
      mounted() {
        console.log('list挂载')
      },
      destroyed() {
        console.log('list销毁')
      }
    };

    let vm = new Vue({
      el: '#app',
      data: {
        title: 'home'
      },
      components: {
        home,
        list
      }

    })
  </script>
</body>

</html>