vue中父子组件传值常用方法

发布于:2025-06-18 ⋅ 阅读:(17) ⋅ 点赞:(0)

前端工程中多次使用父子组件,对于父子组件之间的传值整理一下,不过常用的方式就两种,详细的讲解一下

1. 父组件向子组件传值(props

父组件通过 props 向子组件传递数据子组件通过 props 接收父组件的数据。

适用于父组件传值给子组件展示,子组件不修改该值,如果子组件双向绑定传过来的值,会有问题,下面父子组件双向传值会讲。

示例代码   父组件 Parent.vue

<template>
  <div>
    <h2>父组件</h2>
    <my-child :childMessage="parentMessage" :childCount="parentCount" />
  </div>
</template>

<script>
import MyChild from './MyChild.vue';

export default {
  components: { MyChild },  //在父组件中引入子组件元素
  data() {
    return {
      parentMessage: 'Hello from Parent!',
      parentCount: 42
    };
  }
};
</script>

子组件 MyChild.vue

<template>
  <div>
    <h3>子组件</h3>
    <p>父组件传递的消息:{{ childMessage }}</p>
    <p>父组件传递的数字:{{ childCount }}</p>
  </div>
</template>

<script>
export default {
  props: {
    childMessage: String,  // 类型校验
    childCount: Number
  }
};
</script>

2. 子组件向父组件传值($emit

子组件通过 $emit 触发父组件的事件
父组件监听子组件的事件并处理数据。

示例代码      子组件 MyChild.vue
<template>
  <div>
    <h3>子组件</h3>
    <button @click="sendMessageToParent">点击传递数据给父组件</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendMessageToParent() {
      this.$emit('child-event', 'Hello from Child!');
    }
  }
};
</script>

父组件 Parent.vue

<template>
  <div>
    <h2>父组件</h2>
    <my-child @child-event="handleChildEvent" />
    <p>子组件传递的消息:{{ childMessage }}</p>
  </div>
</template>

<script>
import MyChild from './MyChild.vue';

export default {
  components: { MyChild },
  data() {
    return {
      childMessage: ''
    };
  },
  methods: {
    handleChildEvent(message) {
      this.childMessage = message;
    }
  }
};
</script>

3. 双向绑定(v-model 或 .sync

如果需要父子组件双向同步数据,可以使用 v-model.sync(Vue 2.x)。

子组件 MyChild.vue 

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

<script>
export default {
  props: ['childValue']
};
</script>

父组件 Parent.vue

v-bind:childValue="parentValue",v-on:update:childValue="val => parentValue = val"简化为

:childValue="parentValue" @update:childValue="val => parentValue = val"进一步简化为

:childValue.sync="parentValue"

<template>
  <my-child :childValue.sync="parentValue" />
</template>

<script>
import MyChild from './MyChild.vue';

export default {
  components: { MyChild },
  data() {
    return {
      parentValue: ''
    };
  }
};
</script>

注意:props 是只读的,所以子组件中无法直接用v-model双向绑定父组件传过来的值,子组件修改input输入之后,通知父组件更新,父组件更新后,子组件childValue再更新,绕了一圈

但是我现在就是想在子组件中用v-model进行双向绑定,此时需要修改如下:

子组件 MyChild.vue 

<template>
  <div>
    <input 
      v-model="childValueCopy" @input="childValueCopyChange"
    >
  </div>
</template>

<script>
export default {
  props: ['childValue']  //父组件传过来的值
  data(){
    return{
        childValueCopy:''
    }
  }

  //此处增加一个监听,监听父组件传过来的值是否变化,如果变化,则赋值给子组件childValueCopy
watch: {
        childValue: {
            deep: true,
            immediate: true,
            handler(newValue) {
                this.childValueCopy = newValue;
            }
        }
}
//需要增加一个方法,子组件如果变化了,通知父组件更新
methods:{
    childValueCopyChange(value){
        this.$emit('update:childValue',value);
//此处注意,需要用value,不能用this.childValueCopy,
//因为@change方法调用比双向绑定v-model更快,
//执行change方法时,childValueCopy还没有变化
    }
}
};
</script>

或者

<template>
  <input v-model="localValue" />
</template>

<script>
export default {
  props: ['value'],
  data() {
    return {
      localValue: this.value  // 初始化副本
    }
  },
  watch: {
    localValue(newVal) {
      this.$emit('input', newVal)  // 通知父组件
    },
    value(newVal) {
      this.localValue = newVal  // 同步父组件更新
    }
  }
}
</script>

4. $refs获取子组件的值

子组件中$emit是父组件被动更新,这样子组件每次键入一个字母就会通知父组件一次,会频繁的通知父组件。

父组件可以采用$refs主动获取子组件的值,父组件如下

<template>
  <my-child :childValue.sync="parentValue" ref="childComponentRef"/>
</template>

<script>
import MyChild from './MyChild.vue';

export default {
  components: { MyChild },
  data() {
    return {
      parentValue: ''
    };
  },
  methods:{
    getChildValue(){
        console.info("获取子组件值",this.$refs.childComponentRef.childValueCopy)
    }
  }
};
</script>

扩展知识:

methods: {
    childValueCopyChange(value) {
        this.$emit('update:childValue', value);
    }
}
与methods: {
    childValueCopyChange() {
        this.$emit('update:childValue', this.childValueCopy);
    }
}区别

代码版本 数据来源 实时性 优点
第一个代码

直接从 @input 事件对象获取

立即将最新输入值通过事件对象发出

更实时准确
  • 直接使用 @input 事件的原始值 (event.target.value)
  • 完全实时同步,没有中间状态
  • 避免可能的异步延迟问题
第二个代码 组件内部数据 可能有微小延迟
  • 通过 Vue 的响应式系统更新 childValueCopy 后再发出,可能有几毫秒延迟
  • 在快速连续输入时,可能偶尔不同步

网站公告

今日签到

点亮在社区的每一天
去签到