Vue.js 中子组件向父组件传值的方法

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Vue.js 中子组件向父组件传值的方法

Vue.js 是一款流行的 JavaScript 前端框架,它提供了一套完整的工具和 API,使得开发者可以更加高效地构建交互式的 Web 应用程序。其中,组件化是 Vue.js 的一个核心概念,通过组件化可以将一个复杂的应用程序拆分成多个独立的部分,每个部分都有自己的状态和行为,从而方便开发和维护。

本篇博客将介绍 Vue.js 组件化的基础知识,包括组件的定义、组件的通信、组件的生命周期等内容。我们将从头到尾地讲解这些内容,并提供详细的代码示例,帮助读者更好地理解和掌握 Vue.js 组件化的技术。

一、组件的定义

在 Vue.js 中,组件是可复用的 Vue 实例,它们可以接收相同的选项对象(例如 datamethodscomputed 等),并且可以像普通元素一样在模板中使用。组件可以嵌套使用,也可以在不同的 Vue 实例中共享。

1. 全局组件

全局组件是在 Vue 根实例中注册的组件,可以在任何 Vue 实例中使用。全局组件的注册方法是使用 Vue.component 方法,该方法接收两个参数:组件的名称和选项对象。

<template>
  <div>
    <my-component></my-component>
  </div>
</template>
<script>
Vue.component('my-component', {
  template: '<div>这是一个全局组件</div>'
});
</script>

在上述代码中,我们定义了一个名为 my-component 的全局组件,并在模板中使用了该组件。当渲染组件时,Vue.js 会将组件的选项对象实例化成一个 Vue 实例,并将其挂载到模板中。

2. 局部组件

局部组件是在某个 Vue 实例中注册的组件,只能在该实例及其子组件中使用。局部组件的注册方法是在 Vue 实例的 components 选项中定义组件的名称和选项对象。

<template>
  <div>
    <my-component></my-component>
  </div>
</template>
<script>
import MyComponent from './MyComponent.vue';
export default {
  components: {
    'my-component': MyComponent
  }
}
</script>

在上述代码中,我们定义了一个名为 MyComponent 的局部组件,并在父组件中使用了该组件。当渲染组件时,Vue.js 会将组件的选项对象实例化成一个 Vue 实例,并将其挂载到模板中。

二、组件的通信

在 Vue.js 中,组件之间的通信是非常重要的一个功能。通信可以分为父子组件通信和兄弟组件通信两种类型。下面我们将分别介绍这两种类型的通信方式。

1. 父子组件通信

父子组件通信是指一个组件向它的直接父组件传递数据或事件,或者从它的直接父组件接收数据或事件。在 Vue.js 中,父子组件通信可以通过 props 和自定义事件两种方式实现。

props

props 是父组件向子组件传递数据的一种方式,类似于 React 中的 props。子组件通过在选项对象中定义 props 属性来声明需要接收的数据,父组件则通过在子组件标签上使用属性的方式传递数据。

<!-- 子组件 -->
<template>
  <div>
    <p>姓名:{{ name }}</p>
    <p>年龄:{{ age }}</p>
  </div>
</template>
<script>
export default {
  props: {
    name: String,
    age: Number
  }
}
</script>
<!-- 父组件 -->
<template>
  <div>
    <child-component :name="name" :age="age"></child-component>
  </div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      name: '张三',
      age: 18
    };
  }
}
</script>

在上述代码中,子组件中通过 props 属性声明了需要接收的 nameage 数据。父组件中通过在子组件标签上使用属性的方式传递数据,并且数据类型需要和子组件中声明的类型一致。

自定义事件

自定义事件是子组件向父组件传递数据或事件的一种方式。子组件通过 $emit 方法触发一个自定义事件,并传递需要传递的数据,父组件则通过 v-on 指令监听该事件,并在事件处理函数中接收子组件传递的数据。

<!-- 子组件 -->
<template>
  <div>
    <button @click="handleClick">点击我</button>
  </div>
</template>
<script>
export default {
  methods: {
    handleClick() {
      const data = { name: '张三', age: 18 };
      this.$emit('my-event', data);
    }
  }
}
</script>
<!-- 父组件 -->
<template>
  <div>
    <child-component @my-event="handleEvent"></child-component>
    <p>接收到的数据:{{ eventData }}</p>
  </div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      eventData: null
    };
  },
  methods: {
    handleEvent(data) {
      this.eventData = data;
    }
  }
}
</script>

在上述代码中,子组件中的 handleClick 方法触发了一个名为 my-event 的自定义事件,并传递了一个数据对象。父组件中使用 v-on 指令监听了该事件,并在事件处理函数中接收了子组件传递的数据,并将其赋值给 eventData 变量。最后,在父组件的模板中使用插值语法显示接收到的数据。

2. 兄弟组件通信

兄弟组件通信是指两个没有直接父子关系的组件之间进行数据或事件的传递。在 Vue.js 中,兄弟组件通信可以通过一个共同的父组件来实现,具体步骤如下:

  1. 在共同的父组件中定义一个数据对象,并将其作为 props 分别传递给两个兄弟组件。
<!-- 父组件 -->
   <template>
     <div>
       <child-component-1 :data="sharedData"></child-component-1>
       <child-component-2 :data="sharedData"></child-component-2>
     </div>
   </template>
   
   <script>
   import ChildComponent1 from './ChildComponent1.vue';
   import ChildComponent2 from './ChildComponent2.vue';
   
   export default {
     components: {
       ChildComponent1,
       ChildComponent2
     },
     data() {
       return {
         sharedData: { name: '张三', age: 18 }
       };
     }
   }
   </script>
  1. 在兄弟组件中分别通过 props 接收父组件传递的数据,并在需要修改数据时触发一个自定义事件。
<!-- 兄弟组件 1 -->
   <template>
     <div>
       <p>姓名:{{ data.name }}</p>
       <p>年龄:{{ data.age }}</p>
       <button @click="handleChange">修改姓名</button>
     </div>
   </template>
   
   <script>
   export default {
     props: {
       data: Object
     },
     methods: {
       handleChange() {
         this.$emit('change-name', '李四');
       }
     }
   }
   </script>
   
   <!-- 兄弟组件 2 -->
   <template>
     <div>
       <p>姓名:{{ data.name }}</p>
       <p>年龄:{{ data.age }}</p>
     </div>
   </template>
   
   <script>
   export default {
     props: {
       data: Object
     },
     mounted() {
       this.$parent.$on('change-name', name => {
         this.data.name = name;
       });
     }
   }
   </script>

在上述代码中,父组件中定义了一个名为 sharedData 的数据对象,并将其作为 props 分别传递给了两个兄弟组件。兄弟组件 1 中通过 $emit 方法触发了一个名为 change-name 的自定义事件,并传递了一个新的姓名值。兄弟组件 2 中通过 mounted 钩子函数监听了父组件中触发的 change-name 事件,并在事件处理函数中修改了 data 对象中的姓名值。

三、组件的生命周期

在 Vue.js 中,每个组件都有自己的生命周期,包括创建、挂载、更新和销毁等阶段。组件的生命周期可以通过一些钩子函数来控制和管理,这些钩子函数可以在组件的选项对象中定义。

1. 创建阶段

创建阶段是指组件实例被创建出来后的一系列操作,包括实例化、数据初始化、模板编译等过程。在创建阶段中,Vue.js 会依次调用以下钩子函数:

beforeCreate

该钩子函数在组件实例被创建之前被调用,此时组件的选项对象已经被解析,但是组件实例还没有被创建。

<template>
  <div>{{ message }}</div>
</template>
<script>
export default {
  beforeCreate() {
    console.log('beforeCreate');
  },
  data() {
    return {
      message: 'Hello, Vue!'
    };
  }
}
</script>

在上述代码中,我们在组件选项对象中定义了一个 beforeCreate 钩子函数,并在该函数中输出了一条日志信息。当组件实例被创建之前,该钩子函数会被调用并输出日志信息。

created

该钩子函数在组件实例被创建之后被调用,此时组件实例已经被创建,但是还没有被挂载到页面中。

<template>
  <div>{{ message }}</div>
</template>
<script>
export default {
  created() {
    console.log('created');
  },
  data() {
    return {
      message: 'Hello, Vue!'
    };
  }
}
</script>

在上述代码中,我们在组件选项对象中定义了一个 created 钩子函数,并在该函数中输出了一条日志信息。当组件实例被创建之后,该钩子函数会被调用并输出日志信息。

2. 挂载阶段

挂载阶段是指组件实例被创建后,将其挂载到页面中的过程。在挂载阶段中,Vue.js 会依次调用以下钩子函数:

beforeMount

该钩子函数在组件实例被挂载到页面之前被调用,此时组件实例已经被创建,但是还没有被挂载到页面中。

<template>
  <div>{{ message }}</div>
</template>
<script>
export default {
  beforeMount() {
    console.log('beforeMount');
  },
  data() {
    return {
      message: 'Hello, Vue!'
    };
  }
}
</script>

在上述代码中,我们在组件选项对象中定义了一个 beforeMount 钩子函数,并在该函数中输出了一条日志信息。当组件实例被挂载到页面之前,该钩子函数会被调用并输出日志信息。

mounted

该钩子函数在组件实例被挂载到页面之后被调用,此时组件实例已经被挂载到页面中。

<template>
  <div>{{ message }}</div>
</template>
<script>
export default {
  mounted() {
    console.log('mounted');
  },
  data() {
    return {
      message: 'Hello, Vue!'
    };
  }
}
</script>

在上述代码中,我们在组件选项对象中定义了一个 mounted 钩子函数,并在该函数中输出了一条日志信息。当组件实例被挂载到页面之后,该钩子函数会被调用并输出日志信息。

3. 更新阶段

更新阶段是指组件实例的数据发生变化后,将其重新渲染到页面中的过程。在更新阶段中,Vue.js 会依次调用以下钩子函数:

beforeUpdate

该钩子函数在组件实例的数据发生变化后,重新渲染之前被调用。

<template>
  <div>{{ message }}</div>
  <button @click="handleClick">点击我</button>
</template>
<script>
export default {
  beforeUpdate() {
    console.log('beforeUpdate');
  },
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  methods: {
    handleClick() {
      this.message = 'Hello, World!';
    }
  }
}
</script>

在上述代码中,我们在组件选项对象中定义了一个 beforeUpdate 钩子函数,并在该函数中输出了一条日志信息。当组件实例的数据发生变化后,重新渲染之前,该钩子函数会被调用并输出日志信息。

updated

该钩子函数在组件实例的数据发生变化后,重新渲染之后被调用。

<template>
  <div>{{ message }}</div>
  <button @click="handleClick">点击我</button>
</template>
<script>
export default {
  updated() {
    console.log('updated');
  },
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  methods: {
    handleClick() {
      this.message = 'Hello, World!';
    }
  }
}

在上述代码中,我们在组件选项对象中定义了一个 updated 钩子函数,并在该函数中输出了一条日志信息。当组件实例的数据发生变化后,重新渲染之后,该钩子函数会被调用并输出日志信息。

4. 销毁阶段

销毁阶段是指组件实例被销毁的过程,包括从页面中移除、解绑事件、销毁子组件等操作。在销毁阶段中,Vue.js 会依次调用以下钩子函数:

beforeDestroy

该钩子函数在组件实例被销毁之前被调用。

<template>
  <div>{{ message }}</div>
  <button @click="handleClick">点击我</button>
</template>
<script>
export default {
  beforeDestroy() {
    console.log('beforeDestroy');
  },
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  methods: {
    handleClick() {
      this.$destroy();
    }
  }
}
</script>

在上述代码中,我们在组件选项对象中定义了一个 beforeDestroy 钩子函数,并在该函数中输出了一条日志信息。当组件实例被销毁之前,该钩子函数会被调用并输出日志信息。

destroyed

该钩子函数在组件实例被销毁之后被调用。

<template>
  <div>{{ message }}</div>
  <button @click="handleClick">点击我</button>
</template>
<script>
export default {
  destroyed() {
    console.log('destroyed');
  },
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  methods: {
    handleClick() {
      this.$destroy();
    }
  }
}
</script>

在上述代码中,我们在组件选项对象中定义了一个 destroyed钩子函数,并在该函数中输出了一条日志信息。当组件实例被销毁之后,该钩子函数会被调用并输出日志信息。

生命周期图示

下面是 Vue.js 组件生命周期的图示:

从图中可以看出,Vue.js 组件生命周期包括以下几个阶段:

  1. 创建阶段:包括 beforeCreatecreatedbeforeMountmounted 四个钩子函数。
  2. 更新阶段:包括 beforeUpdateupdated 两个钩子函数。
  3. 销毁阶段:包括 beforeDestroydestroyed 两个钩子函数。

其中,创建阶段和销毁阶段只会在组件实例创建和销毁时触发一次;而更新阶段会在组件实例数据发生变化时被触发多次。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
7天前
|
JavaScript
在 Vue 中处理组件选项与 Mixin 选项冲突的详细解决方案
【10月更文挑战第18天】通过以上的分析和探讨,相信你对在 Vue 中使用 Mixin 时遇到组件选项与 Mixin 选项冲突的解决方法有了更深入的理解。在实际开发中,要根据具体情况灵活选择合适的解决方案,以确保代码的质量和可维护性。
39 7
|
7天前
|
缓存 监控 前端开发
JavaScript 实现大文件上传的方法
【10月更文挑战第17天】通过以上步骤和方法,我们可以实现较为可靠和高效的大文件上传功能。当然,具体的实现方式还需要根据实际的应用场景和服务器要求进行调整和优化。
|
6天前
|
缓存 JavaScript UED
Vue 的动态组件与 keep-alive
【10月更文挑战第19天】总的来说,动态组件和 `keep-alive` 是 Vue.js 中非常实用的特性,它们为我们提供了更灵活和高效的组件管理方式,使我们能够更好地构建复杂的应用界面。深入理解和掌握它们,以便在实际开发中能够充分发挥它们的优势,提升我们的开发效率和应用性能。
34 18
|
1天前
|
缓存 JavaScript UED
Vue 中实现组件的懒加载
【10月更文挑战第23天】组件的懒加载是 Vue 应用中提高性能的重要手段之一。通过合理运用动态导入、路由配置等方式,可以实现组件的按需加载,减少资源浪费,提高应用的响应速度和用户体验。在实际应用中,需要根据具体情况选择合适的懒加载方式,并结合性能优化的其他措施,以打造更高效、更优质的 Vue 应用。
|
5天前
|
前端开发 UED
vue3知识点:Suspense组件
vue3知识点:Suspense组件
17 4
|
4天前
|
JavaScript 前端开发 测试技术
组件化开发:创建可重用的Vue组件
【10月更文挑战第21天】组件化开发:创建可重用的Vue组件
9 1
|
5天前
|
JavaScript 前端开发 Java
《vue3第五章》新的组件,包含:Fragment、Teleport、Suspense
《vue3第五章》新的组件,包含:Fragment、Teleport、Suspense
16 2
|
5天前
|
Java
vue3知识点:Teleport组件
vue3知识点:Teleport组件
16 1
|
8天前
|
存储 JavaScript
Vue 组件间通信的方式有哪些?
Vue组件间通信主要通过Props、Events、Provide/Inject、Vuex(状态管理)、Ref、Event Bus等实现,支持父子组件及跨级组件间的高效数据传递与状态共享。
|
6天前
|
JavaScript 前端开发
vue全局公共组件自动引入并注册,开发效率直接起飞!
vue全局公共组件自动引入并注册,开发效率直接起飞!
27 1