Vue2 子组件参数与父组件的双向绑定

在 Vue 2 中,通过props字段可以实现父组件向子组件的单向数据流,在父组件数据发生变化时,会实时地传递给子组件,而子组件无法修改父组件传递的数据。

以下提出的部分方法为网上收集整理资料得出,未经实践,如有错误欢迎指出。

1、不允许直接修改props

如果尝试直接修改props中的参数,会触发 Vue 的警告,并且不会更新父组件的数据。

若尝试修改props中的值,会触发以下警告:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "propName"

2、通过引用类型实现对父组件传入参数的修改

若传递的数据为引用类型(对象和数组),子组件可以访问和修改这些对象或数组的内部属性,但直接修改props本身是不被允许的。

3、通过v-model实现数据的双向绑定(Vue 2.2+版本)

从 Vue 2.2.0 开始,v-model的行为有所改进,允许在自定义组件中使用v-model进行双向绑定。v-model默认绑定的是value属性和input事件,但你可以通过model选项来自定义绑定的属性和事件。

实战中发现,部分Vue2.2+版本不支持这个方法,可能是我的配置有问题。

v-model本质上也是一个语法糖,代码部分为:

<input v-bind:value="propName" v-on:input="propName = $event.target.value" />
<input v-model = "propName" />

v-model使用示例:

父组件:

<template>
  <div>
    <ChildComponent v-model="parentValue" />
  </div>
</template>

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

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentValue: 'Hello from parent'
    };
  }
};
</script>

子组件:

<template>
  <div>
    <p>{{ value }}</p>
    <input v-model="value" @input="updateValue">Update Value</input>
  </div>
</template>

<script>
export default {
  name: 'ChildComponent',
  props: {
    value: String // 若设置了多个props的属性,且没有名为value的属性,那么可以通过model设定v-model绑定的值
  },
  model: {
    prop: 'value', // 指定 v-model 绑定的 prop名,若不写则默认为'value'
    event: 'input' // 指定 v-model 触发的事件,若不写则默认为'input'
  },
  methods: {
    updateValue() {
      this.$emit('input', this.value); // 触发 input 事件,更新父组件的数据
    }
  }
};
</script>

 4、.sync双向绑定(Vue2.3+版本)

从 Vue 2.3.0 开始,引入了".sync"修饰符,允许在自定义组件中实现双向绑定。".sync"修饰符实际上是一个语法糖,会在内部触发一个update:propName事件并完成数据的更新。

实际上,最原始的方法下,父子组件参数双向绑定的原理是:

1.子组件数据更新,用$emit函数触发名为update:propName的事件,传递更新后的值;

2.父组件定义@update:propName事件,并将更新后的值赋给传给子组件的参数。

.sync完成的是第二步的操作。

.sync修饰符使用示例: 

父组件:

<template>
  <div>
    <ChildComponent :value.sync="parentValue" />
  </div>
</template>

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

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentValue: 'Hello from parent'
    };
  }
};
</script>

子组件 :

<template>
  <div>
    <p>{{ value }}</p>
    <input v-model="value" @input="updateValue">Update Value</input>
  </div>
</template>

<script>
export default {
  name: 'ChildComponent',
  props: {
    value: String
  },
  methods: {
    updateValue() {
      this.$emit('update:value', this.value); // 触发 update:value 事件,更新父组件的数据
    }
  }
};
</script>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值