Vue组件间通信方法总结(父子组件、兄弟组件及祖先后代组件间)

yizhihongxing

Vue组件间通信方法总结

Vue组件通信是Vue开发者必须掌握的技能之一。本文将总结Vue中组件间通信的各种方法,包括父子组件、兄弟组件及祖先后代组件间通信。

父子组件通信

父子组件通信是Vue中最常见的通信方式。下面分别介绍组件间通信的几种方法。

Props

在Vue中父组件可以通过Props向子组件传递数据,子组件通过props选项接收父组件传递过来的数据,使得父子组件关系更加紧密。

<!-- 父组件模板 -->
<template>
  <div>
    <child :message="parentMsg"></child>
  </div>
</template>

<!-- 父组件 -->
<script>
  import Child from './Child.vue';
  export default {
    components: {
      Child,
    },
    data() {
      return {
        parentMsg: 'hello',
      }
    },
  }
</script>

<!-- 子组件 -->
<template>
  <div>
    <span>{{ message }}</span>
  </div>
</template>

<script>
  export default {
    props: ['message'],
  }
</script>

$emit/$on

子组件通过$emit触发一个自定义事件,父组件通过$on监听该自定义事件。

<!-- 父组件模板 -->
<template>
  <div>
    <child @my-event="eventHandler"></child>
  </div>
</template>

<!-- 父组件 -->
<script>
  import Child from './Child.vue';
  export default {
    components: {
      Child,
    },
    methods: {
      eventHandler(param) {
        console.log(param);
      },
    },
  }
</script>

<!-- 子组件 -->
<template>
  <div>
    <button @click="clickHandler"></button>
  </div>
</template>

<script>
  export default {
    methods: {
      clickHandler() {
        this.$emit('my-event', 'Hello from child!');
      },
    },
  }
</script>

$refs

Vue中的$refs可以让父组件直接访问子组件的DOM实例或者子组件实例,但是需要注意的是,$refs在子组件挂载之后才可以访问。

<!-- 父组件模板 -->
<template>
  <div>
    <child ref="child"></child>
  </div>
</template>

<!-- 父组件 -->
<script>
  import Child from './Child.vue';
  export default {
    components: {
      Child,
    },
    mounted() {
      console.log(this.$refs.child);
    },
  }
</script>

<!-- 子组件 -->
<template>
  <div>
    <span>hello from child</span>
  </div>
</template>

<script>
  export default {}
</script>

兄弟组件通信

在Vue中,兄弟组件不能直接相互通信,但是可以通过相同的父组件作为中转站来实现通信。

<!-- 父组件模板 -->
<template>
  <div>
    <child1 ref="child1"></child1>
    <child2 ref="child2"></child2>
  </div>
</template>

<!-- 父组件 -->
<script>
  import Child1 from './Child1.vue';
  import Child2 from './Child2.vue';
  export default {
    components: {
      Child1,
      Child2,
    },
    mounted() {
      this.$refs.child1.$on('my-event', param => {
        this.$refs.child2.receiveFromChild1(param);
      });
    }
  }
</script>

<!-- 子组件 -->
<template>
  <div>
    <button @click="clickHandler"></button>
  </div>
</template>

<script>
  export default {
    methods: {
      clickHandler() {
        this.$emit('my-event', 'Hello from child1!');
      },
    },
  }
</script>

祖先后代组件通信

祖先后代组件通信可以有多种方式,比如可以通过Vue自带的$parent/$children属性直接访问父组件/子组件,或者通过事件派发机制在组件树上派发事件。

$parent/$children

在Vue中,每个组件实例都拥有$parent和$children这两个属性,可以用来访问组件树上的父子组件,但需要注意的是,$parent/$children只会追溯到静态父子关系模板。

<!-- 父组件模板 -->
<template>
  <div>
    <child></child>
  </div>
</template>

<!-- 父组件 -->
<script>
  import Child from './Child.vue';
  export default {
    components: {
      Child,
    },
    methods: {
      logChildMethod() {
        console.log(this.$children[0].hello());
      },
    },
  }
</script>

<!-- 子组件 -->
<template>
  <div>
    <span>hello from child</span>
  </div>
</template>

<script>
  export default {
    methods: {
      hello() {
        return 'hello from child method';
      },
    },
  }
</script>

$attrs/$listeners

在Vue2.4.0之后,可以通过$attrs和$listeners实现组件之间更加灵活的通信,$attrs可以让组件在保留原本的属性之外接收额外的父级属性。$listeners可以让子组件直接将父组件时接收到的事件同时向自己的子孙传递。

<!-- 父组件模板 -->
<template>
  <div>
    <child attr1="I am attr1" @click="clickHandler" />
  </div>
</template>

<!-- 父组件 -->
<script>
  import Child from './Child.vue';
  export default {
    components: {
      Child,
    },
    methods: {
      clickHandler() {
        console.log('hello from parent event');
      },
    }
  }
</script>

<!-- 子组件 -->
<template>
  <div>
    <grand-child v-bind="$attrs" v-on="$listeners" />
  </div>
</template>

<script>
  import GrandChild from './GrandChild.vue';
  export default {
    components: {
      GrandChild,
    },
  }
</script>

<!-- 孙子组件 -->
<template>
  <button @click="$emit('click')">button text</button>
</template>

以上就是Vue组件间通信方法总结(父子组件、兄弟组件及祖先后代组件间)的完整攻略。

示例说明

接下来,给出一个具体的例子。

场景描述: 在一个VUE项目中,有一个页面,页面由多个组件构成,其中有一个筛选组件A,用户选择筛选条件后,其他组件根据筛选条件来实时展现数据。

首先,我们定义A组件:

<template>
  <div>
    <div class="form-group">
      <label>条件一</label>
      <input v-model="form.condition1" type="text">
    </div>
    <div class="form-group">
      <label>条件二</label>
      <select v-model="form.condition2">
        <option v-for="option in options2">{{ option.label }}</option>
      </select>
    </div>
    <button @click="search">搜索</button>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        form: {
          condition1: '',
          condition2: '',
        },
        options2: [
          { value: '1', label: '选项1' },
          { value: '2', label: '选项2' },
          { value: '3', label: '选项3' },
          { value: '4', label: '选项4' },
        ],
      }
    },
    methods: {
      search() {
        this.$emit('search', this.form);
      },
    },
  }
</script>

接着,在父组件中注册A组件,并监听它的search事件,触发自定义v-loading事件,把选择的筛选条件传递给子组件:

<template>
  <div>
    <A @search="onSearch"></A>
    <B :condition="condition" @v-loading="handleLoading"></B>
    <C :condition="condition"></C>
  </div>
</template>

<script>
  import A from './components/A.vue';
  import B from './components/B.vue';
  import C from './components/C.vue';
  export default {
    components: {
      A,
      B,
      C,
    },
    data() {
      return {
        condition: {},
      }
    },
    methods: {
      onSearch(condition) {
        this.condition = condition;
        this.$emit('v-loading', true);
      },
      handleLoading(loading) {
        this.$emit('v-loading', loading);
      },
    },
  }
</script>

在B组件中接收父组件传递进来的筛选条件,然后根据条件请求数据,获取到数据后,通过$emit方法传递给父组件。

<template>
  <div>
    <ul>
      <li v-for="item in list">{{ item.text }}</li>
    </ul>
  </div>
</template>

<script>
  export default {
    props: {
      condition: Object,
    },
    data() {
      return {
        list: [],
      }
    },
    mounted() {
      this.fetchData();
    },
    watch: {
      condition() {
        this.fetchData();
      },
    },
    methods: {
      fetchData() {
        getData(this.condition).then(response => {
          this.list = response.data;
          this.$emit('v-loading', false);
        });
      },
    },
  }
</script>

在C组件中接收父组件传递进来的筛选条件,然后根据条件展现数据:

<template>
  <div>
    <ul>
      <li v-for="item in list">{{ item.text }}</li>
    </ul>
  </div>
</template>

<script>
  export default {
    props: {
      condition: Object,
    },
    data() {
      return {
        list: [],
      }
    },
    mounted() {
      this.fetchData();
    },
    watch: {
      condition() {
        this.fetchData();
      },
    },
    methods: {
      fetchData() {
        getData(this.condition).then(response => {
          this.list = response.data;
        });
      },
    },
  }
</script>

通过以上代码,我们就实现了页面的数据实时筛选功能。

通过以上实例,可以看出vue的组件通信机制非常强大,能够很方便的解决我们在组件开发过程中遇到的各种通信问题。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue组件间通信方法总结(父子组件、兄弟组件及祖先后代组件间) - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • 对vue中v-if的常见使用方法详解

    下面是针对“对vue中v-if的常见使用方法详解”的完整攻略,包含两个示例说明。 对vue中v-if的常见使用方法详解 v-if的基本使用方法 在Vue.js中,v-if指令用于控制元素是否显示。如果v-if表达式的值为true,元素将被渲染;如果v-if表达式的值为false,元素将不会被渲染。 <template> <div> &…

    Vue 2023年5月27日
    00
  • Vue3父子通讯方式及Vue3插槽的使用方法详解

    让我来给大家详细讲解一下“Vue3父子通讯方式及Vue3插槽的使用方法详解”。 Vue3父子通讯方式 在Vue3中,父组件向子组件传递数据是通过props属性来实现的,子组件接收到数据后,可以通过触发事件将数据传递回父组件。 父组件向子组件传递数据 父组件使用props属性来向子组件传递数据,示例代码如下: <template> <div&…

    Vue 2023年5月28日
    00
  • Vue报错:TypeError: Cannot create property ‘xxxx‘ on的解决

    当 Vue 报出 “TypeError: Cannot create property ‘xxxx’ on” 类型的错误时,通常是由于在组件中调用了未定义的数据或方法。这种错误的解决方案可能有很多,我们可以从以下几个方面来处理: 检查组件的数据 首先,我们需要检查组件中使用的数据,确保其已在组件中初始化或定义。如果该数据是作为组件属性传入的,则需要确保传入的…

    Vue 2023年5月27日
    00
  • 关于vue中路由的跳转和参数传递,参数获取

    对于vue中的路由跳转和参数传递,可以通过vue-router这个插件来实现。下面我就一步步讲解使用vue-router实现路由跳转和参数传递的完整攻略。 路由跳转 安装和配置vue-router 首先需要安装vue-router插件,可以通过npm命令进行安装: npm install vue-router –save 安装完成后,在项目的入口文件中导入…

    Vue 2023年5月27日
    00
  • Vue响应式原理模拟实现原理探究

    Vue响应式原理模拟实现原理探究 什么是 Vue 响应式原理? Vue.js 是一个基于数据驱动的前端框架,主要利用观察者模式实现了 MVVM 模式。在 Vue 中,我们可以通过操作数据来动态改变视图,并且数据和视图是“响应式”的,即数据变化后,对应的视图也会发生变化。 Vue 响应式原理模拟实现 响应式对象 在 Vue 中,可以将一个对象设置为“响应式”的…

    Vue 2023年5月28日
    00
  • Springboot+Vue-Cropper实现头像剪切上传效果

    下面是“Springboot+Vue-Cropper实现头像剪切上传效果”的完整攻略。 前置知识 在学习本文之前,需要了解以下内容: Spring Boot框架 Vue.js框架 Vue-Cropper组件 环境准备 JDK 1.8 Maven Node.js Vue CLI 前端实现 创建Vue项目 在命令行中执行以下命令: vue create vue-…

    Vue 2023年5月28日
    00
  • vue项目用后端返回的文件流实现docx和pdf文件预览

    为了实现Vue项目中使用后端返回的文件流来实现docx和pdf文件预览,我们需要考虑以下几个步骤: 后端接口的开发,即后端如何将docx和pdf格式的文件以流的方式返回给前端; 前端的代码实现,即如何将后端返回的文件流渲染成文档预览界面; 在Vue项目中具体使用这种文件预览功能。 下面我会针对每个步骤详细讲解。 后端接口的开发 在后端开发的时候,我们需要做的…

    Vue 2023年5月28日
    00
  • vue-router跳转方式的区别解析

    下面是“vue-router跳转方式的区别解析”的完整攻略。 背景 Vue Router是Vue.js官方的路由管理器,它与Vue.js的核心深度集成,可以非常方便地构建单页Web应用程序。 在Vue Router中,有多种方式可以实现页面之间的跳转,包括<router-link>组件、$router.push方法、$router.replace…

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部