面试题:Vue 父子组件之间传值有哪些方式?

在 Vue 中,父子组件之间的数据传递是开发中非常常见的需求。以下是 Vue 中父子组件传值的几种主要方式:


1. Props(父组件向子组件传值)

  • 作用:父组件通过 props 向子组件传递数据。
  • 使用方法
    1. 在父组件中,通过属性绑定的方式传递数据。
    2. 在子组件中,通过 props 接收数据。
  • 示例
    <!-- 父组件 -->
    <template>
      <ChildComponent :message="parentMessage" />
    </template>
    
    <script>
    import ChildComponent from './ChildComponent.vue';
    
    export default {
      components: {
        ChildComponent
      },
      data() {
        return {
          parentMessage: 'Hello from Parent'
        };
      }
    };
    </script>
    
    <!-- 子组件 -->
    <template>
      <div>{{ message }}</div>
    </template>
    
    <script>
    export default {
      props: {
        message: {
          type: String,
          required: true
        }
      }
    };
    </script>
  • 特点
    • 单向数据流:父组件的数据变化会自动更新到子组件,但子组件不能直接修改 props
    • 支持类型检查和默认值。

2. 自定义事件(子组件向父组件传值)

  • 作用:子组件通过 $emit 触发自定义事件,向父组件传递数据。
  • 使用方法
    1. 在子组件中,使用 $emit 触发事件并传递数据。
    2. 在父组件中,监听子组件的事件并处理数据。
  • 示例
    <!-- 子组件 -->
    <template>
      <button @click="sendMessage">发送消息</button>
    </template>
    
    <script>
    export default {
      methods: {
        sendMessage() {
          this.$emit('message-from-child', 'Hello from Child');
        }
      }
    };
    </script>
    
    <!-- 父组件 -->
    <template>
      <ChildComponent @message-from-child="handleMessage" />
    </template>
    
    <script>
    import ChildComponent from './ChildComponent.vue';
    
    export default {
      components: {
        ChildComponent
      },
      methods: {
        handleMessage(message) {
          console.log(message); // 输出: Hello from Child
        }
      }
    };
    </script>
  • 特点
    • 子组件通过事件向父组件传递数据。
    • 父组件可以监听多个子组件事件。

3. v-model 和 model 选项

  • 作用:实现父子组件的双向绑定。
  • 使用方法
    1. 在父组件中使用 v-model 绑定数据。
    2. 在子组件中使用 model 选项定义 prop 和事件。
  • 示例
    <!-- 父组件 -->
    <template>
      <ChildComponent v-model="inputValue" />
    </template>
    
    <script>
    import ChildComponent from './ChildComponent.vue';
    
    export default {
      components: {
        ChildComponent
      },
      data() {
        return {
          inputValue: ''
        };
      }
    };
    </script>
    
    <!-- 子组件 -->
    <template>
      <input :value="value" @input="updateValue" />
    </template>
    
    <script>
    export default {
      props: {
        value: {
          type: String,
          required: true
        }
      },
      methods: {
        updateValue(event) {
          this.$emit('input', event.target.value);
        }
      }
    };
    </script>
  • 特点
    • 简化父子组件的双向绑定。
    • 默认使用 value 作为 propinput 作为事件。

4. ref 和 $refs

  • 作用:父组件通过 ref 获取子组件实例,直接访问子组件的数据或方法。
  • 使用方法
    1. 在父组件中,为子组件添加 ref 属性。
    2. 通过 this.$refs 访问子组件实例。
  • 示例
    <!-- 父组件 -->
    <template>
      <ChildComponent ref="child" />
      <button @click="getChildData">获取子组件数据</button>
    </template>
    
    <script>
    import ChildComponent from './ChildComponent.vue';
    
    export default {
      components: {
        ChildComponent
      },
      methods: {
        getChildData() {
          const childData = this.$refs.child.childData;
          console.log(childData); // 输出子组件的数据
        }
      }
    };
    </script>
    
    <!-- 子组件 -->
    <template>
      <div>子组件</div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          childData: 'Hello from Child'
        };
      }
    };
    </script>
  • 特点
    • 直接访问子组件的属性和方法。
    • 破坏了组件的封装性,应谨慎使用。

5. $parent 和 $children

  • 作用:通过 Vue 实例的 $parent 和 $children 属性访问父组件或子组件。
  • 使用方法
    • 在子组件中,通过 this.$parent 访问父组件。
    • 在父组件中,通过 this.$children 访问子组件。
  • 示例
    // 子组件
    export default {
      methods: {
        callParentMethod() {
          this.$parent.parentMethod();
        }
      }
    };
    
    // 父组件
    export default {
      methods: {
        parentMethod() {
          console.log('父组件方法被调用');
        }
      }
    };
  • 特点
    • 直接访问父子组件实例。
    • 破坏了组件的封装性,应谨慎使用。

6. Provide / Inject

  • 作用:祖先组件通过 provide 提供数据,后代组件通过 inject 注入数据。
  • 使用方法
    1. 在祖先组件中使用 provide 提供数据。
    2. 在后代组件中使用 inject 注入数据。
  • 示例
    // 祖先组件
    export default {
      provide() {
        return {
          message: 'Hello from Ancestor'
        };
      }
    };
    
    // 后代组件
    export default {
      inject: ['message'],
      mounted() {
        console.log(this.message); // 输出: Hello from Ancestor
      }
    };
  • 特点
    • 适合跨层级组件通信。
    • 数据流向不直观,应谨慎使用。

7. Vuex(状态管理)

  • 作用:通过 Vuex 集中管理组件之间的共享状态。
  • 使用方法
    1. 在 Vuex 中定义状态和操作。
    2. 在组件中通过 mapStatemapGettersmapActions 等访问或修改状态。
  • 示例
    // store.js
    export default new Vuex.Store({
      state: {
        message: 'Hello from Vuex'
      },
      mutations: {
        setMessage(state, payload) {
          state.message = payload;
        }
      }
    });
    
    // 组件
    export default {
      computed: {
        message() {
          return this.$store.state.message;
        }
      },
      methods: {
        updateMessage() {
          this.$store.commit('setMessage', 'New Message');
        }
      }
    };
  • 特点
    • 适合大型应用中复杂的组件通信。
    • 需要引入 Vuex,增加了项目的复杂度。

总结

Vue 父子组件之间传值的方式包括:

  1. Props:父组件向子组件传递数据。
  2. 自定义事件:子组件向父组件传递数据。
  3. v-model:实现父子组件的双向绑定。
  4. ref 和 $refs:父组件直接访问子组件实例。
  5. $parent 和 $children:访问父子组件实例(不推荐)。
  6. Provide / Inject:跨层级组件通信。
  7. Vuex:集中管理共享状态。
THE END
点赞12 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容