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中axios设置timeout超时的操作

    当使用axios在Vue中进行数据请求时,可能会遇到服务器响应非常缓慢或者出现网络问题等情况,由此导致前端请求一直在等待响应,造成用户体验不佳。为了解决这类问题,我们可以通过设置axios的timeout超时时间来规定前端在等待响应的最大时间,如果超过这个时间则取消请求,并且返回一个错误提示。 下面是设置axios timeout的完整攻略和两条示例说明: …

    Vue 2023年5月29日
    00
  • vuex存储复杂参数(如对象数组等)刷新数据丢失的解决方法

    问题描述: 在使用 vuex 进行数据管理时,如果存储了复杂参数例如对象数组等,当页面刷新时会发现数据丢失,这是因为 vuex 存储在内存中,刷新页面时内存被清空导致的。 解决方法: 我们可以通过以下步骤将 vuex 中的数据存储到本地存储中,以便在刷新页面后能够恢复数据。 安装 vuex-persistedstate shell npm install v…

    Vue 2023年5月28日
    00
  • 浅谈Vue的组件间传值(包括Vuex)

    下面就为您详细讲解“浅谈Vue的组件间传值(包括Vuex)”的完整攻略: 一、组件间传值 在Vue中,父组件可以通过属性(prop)的方式向子组件传递数据,而子组件则可以通过事件($emit)的方式向父组件发送数据,从而实现组件间的数据传递。 1.1 父组件向子组件传值 在父组件中,通过在子组件标签上添加属性来向子组件传递数据,例如: <templat…

    Vue 2023年5月28日
    00
  • Vue路由vue-router详细讲解指南

    Vue路由vue-router详细讲解指南 什么是Vue路由 Vue路由(vue-router)是Vue.js官方提供的客户端路由工具,它实现了基于组件的页面切换和参数传递。使用Vue路由可以实现单页应用(SPA,Single Page Application)的路由功能。 Vue路由可以通过切换地址栏中的url路径来加载组件并更新页面内容,同时可以传递参数…

    Vue 2023年5月27日
    00
  • 浅谈vue使用axios的回调函数中this不指向vue实例,为undefined

    在Vue项目中,我们通常使用 axios 来进行 HTTP 请求。但是,在 axios 的回调函数中, this 的指向经常会出现问题,指向的不是 Vue 实例,而是 undefined。这种情况通常发生在箭头函数、回调函数嵌套等场景中。 为了解决这个问题,我们可以采取以下两种方法: 方法一:使用箭头函数 ES6 的箭头函数可以继承上下文中的 this,因此…

    Vue 2023年5月28日
    00
  • vue使用pdfjs显示PDF可复制的实现方法

    下面我将详细讲解“vue使用pdfjs显示PDF可复制的实现方法”的完整攻略。 1. 确认使用pdfjs 首先,我们需要确认使用的是pdfjs库。pdfjs是一款功能强大的开源JavaScript库,它可以实现在网页上显示PDF文档。 在Vue项目中,可以使用npm安装pdfjs,命令如下: npm install pdfjs-dist@2.0.943 –…

    Vue 2023年5月28日
    00
  • vue中实现拖拽排序功能的详细教程

    为了详细讲解“Vue中实现拖拽排序功能的详细教程”,下面我将提供以下步骤: 步骤一:使用插件 Vue中实现拖拽排序功能,可以使用一些优秀的插件,例如vuedraggable和sortablejs,我们选择使用vuedraggable插件。 npm install vuedraggable –save 步骤二:加载插件并设置参数 在需要实现拖拽排序功能的组件…

    Vue 2023年5月27日
    00
  • vue中数据不响应的问题及解决

    当使用Vue来开发网页应用时,经常会遇到组件无法响应数据(data)变化的问题,这是因为Vue的数据绑定特性需要满足一定的条件才能生效。接下来我们将介绍如何解决这个问题。 问题分析 在Vue中,如果数据绑定不生效,这通常是因为以下几个原因: 数据未被正确地注入到Vue实例中。 未使用正确的数据绑定方式。 数据变化没有触发Vue的重新渲染。 下面一一对这些原因…

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