vue组件传值的多种方式

在Vue组件通信中,灵活选择合适的方式能大幅提升开发效率。以下是常用的组件传值方式,按场景分类整理:

---

### 一、父子组件通信

1. **Props(父 → 子)** 

  父组件通过属性传递数据,子组件用`props`接收。 

  ```vue

  <!-- 父组件 -->

  <Child :message="parentMsg" />

  <!-- 子组件 -->

  <script>

  export default { props: ['message'] }

  </script>

  ```

2. **$emit(子 → 父)** 

  子组件触发自定义事件,父组件监听。 

  ```vue

  <!-- 子组件 -->

  <button @click="$emit('notify', data)">通知父组件</button>

  <!-- 父组件 -->

  <Child @notify="handleNotify" />

  ```

3. **.sync修饰符(双向绑定)** 

  Vue 2.3+ 提供,简化双向绑定语法。 

  ```vue

  <!-- 父组件 -->

  <Child :title.sync="pageTitle" />

  <!-- 子组件 -->

  <script>

  this.$emit('update:title', newTitle)

  </script>

  ```

4. **v-model(表单/自定义组件)** 

  语法糖,默认监听`input`事件和绑定`value`属性。 

  ```vue

  <!-- 父组件 -->

  <Child v-model="inputValue" />

  <!-- 子组件 -->

  <input :value="value" @input="$emit('input', $event.target.value)" />

  ```

---

### 二、跨层级通信

5. **$attrs 和 $listeners(透传属性/事件)** 

  `$attrs`传递未在`props`中声明的属性,`$listeners`传递所有事件监听器。 

  ```vue

  <!-- 中间组件 -->

  <Grandchild v-bind="$attrs" v-on="$listeners" />

  ```

6. **provide/inject(依赖注入)** 

  祖先组件提供数据,后代组件注入使用。 

  ```vue

  <!-- 祖先组件 -->

  <script>

  export default { provide() { return { theme: 'dark' } } }

  </script>

  <!-- 后代组件 -->

  <script>

  export default { inject: ['theme'] }

  </script>

  ```

---

### 三、全局/跨组件通信

7. **Event Bus(事件总线)** 

  创建一个全局Vue实例作为事件中心。 

  ```js

  // bus.js

  import Vue from 'vue'

  export const bus = new Vue()

  // 组件A发送事件

  bus.$emit('event-name', data)

  // 组件B监听事件

  bus.$on('event-name', data => { ... })

  ```

8. **Vuex(状态管理)** 

  集中式状态管理,适合中大型应用。 

  ```js

  // store.js

  export default new Vuex.Store({ state: { count: 0 } })

  // 组件中访问

  this.$store.state.count

  ```

---

### 四、直接访问组件实例

9. **$parent / $children** 

  通过父子实例直接访问,但耦合性高。 

  ```js

  // 子组件访问父组件

  this.$parent.parentMethod()

  // 父组件访问第一个子组件

  this.$children[0].childMethod()

  ```

10. **$refs** 

    通过`ref`属性标记,直接调用子组件方法。 

    ```vue

    <!-- 父组件 -->

    <Child ref="childRef" />

    <script>

    this.$refs.childRef.doSomething()

    </script>

    ```

---

### 五、特殊场景通信

11. **作用域插槽(子 → 父传递数据)** 

    子组件通过插槽暴露数据,父组件接收使用。 

    ```vue

    <!-- 子组件 -->

    <slot :user="userData"></slot>

    <!-- 父组件 -->

    <Child>

      <template v-slot:default="slotProps">{{ slotProps.user }}</template>

    </Child>

    ```

12. **路由参数(URL传参)** 

    通过路由配置传递参数。 

    ```js

    // 路由配置

    { path: '/user/:id', component: User }

    // 组件中获取

    this.$route.params.id

    ```

---

### 选择建议

- **简单父子通信**:`props` + `$emit` 

- **跨层级/复杂场景**:`provide/inject`、`Event Bus`、`Vuex` 

- **快速原型开发**:`$refs`或`.sync` 

- **状态共享**:优先考虑`Vuex`或`Pinia`(Vue 3) 

根据项目规模和需求选择最合适的方式,避免过度设计。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容