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

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语法和标签的入门使用教程

    下面是“Vue语法和标签的入门使用教程”完整攻略: Vue语法和标签的入门使用教程 什么是Vue.js? Vue.js是一套构建用户界面的渐进式框架,核心库只关注视图层,易于上手并且便于与其它第三方库或已有项目集成。 Vue.js的基本概念 实例和挂载 Vue.js通过创建一个Vue实例来使用其提供的功能,例如数据绑定、指令等。我们可以使用new Vue()…

    Vue 2023年5月27日
    00
  • Vue.js对象转换实例

    Vue.js对象转换实例的攻略如下: 1. 什么是Vue.js对象转换实例? 在Vue.js中,我们可以将JavaScript对象转换成Vue实例,即将一个普通的JavaScript对象传递给Vue构造器,创建一个Vue实例,从而可以在模板中使用。 2. Vue.js对象转换实例的使用方法 Step 1. 引入Vue.js <script src=&q…

    Vue 2023年5月28日
    00
  • vue项目接口管理,所有接口都在apis文件夹中统一管理操作

    当我们在开发Vue项目时,通常需要与后端进行交互,而后端接口的管理十分重要。为了更好的管理接口,一种比较好的方式是采用apis文件夹来统一管理操作所有接口。 实现该功能需要遵循以下几步骤: 创建apis文件夹 在Vue项目下面src目录下创建一个apis文件夹。这个文件夹将存放与后端接口相关的文件。 定义接口文件 在apis文件夹下创建一个user.js的文…

    Vue 2023年5月28日
    00
  • vsCode中vue文件无法提示html标签的操作方法

    针对vsCode中vue文件无法提示html标签的情况,可以按照以下步骤进行操作: 安装Vetur插件 Vetur是一款vsCode的插件,主要提供语法高亮、格式化、代码片段和错误提示等功能,适用于Vue.js开发。因此,在使用vsCode编辑Vue文件时,我们需要安装并启用Vetur插件,这样就能够解决无法提示html标签的问题。 具体操作如下: 在vsC…

    Vue 2023年5月28日
    00
  • vue-jsonp的使用及说明

    一、vue-jsonp的说明 vue-jsonp是一个Vue.js插件,它允许我们使用JSONP方法向API服务器请求数据。JSONP是一种跨域访问数据的方法,它通过动态添加标签来实现异步加载,一般使用起来比较简单。在Vue.js中,我们可以借助vue-jsonp这个插件,使用方式也是非常简单的。 二、安装vue-jsonp 如果想使用vue-jsonp,首…

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

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

    Vue 2023年5月28日
    00
  • 教你60行代码实现一个迷你响应式系统vue

    如何用60行代码实现迷你响应式系统Vue 简介 Vue是一款流行的JavaScript框架,其拥有强大的响应式系统,可以方便地实现数据绑定及视图更新。本文将介绍如何用60行代码实现一个迷你的Vue响应式系统,以更好地理解Vue原理。 响应式系统的实现 响应对象Reactive 我们首先需要实现一个响应对象Reactive,用于监听对象的变化并触发更新。该响应…

    Vue 2023年5月27日
    00
  • Vue列表渲染v-for的使用案例详解

    下面是“Vue列表渲染v-for的使用案例详解”的完整攻略。 什么是Vue列表渲染 Vue.js是一个数据驱动的JavaScript框架,该框架可以将数据和DOM元素绑定在一起,实现视图和数据的同步更新。这使得数据的展示和渲染非常容易实现,使网页的开发变得更高效和简洁。 Vue中的列表渲染就是一种数据渲染方式,它可以根据一个数组自动创建一些DOM元素,以此来…

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