vue中父子组件传值

vue中的父子组件传值,值得注意的是要遵守单向数据流原则。所谓单向数据流原则,简单的说就是父组件的数据可以传递给子组件,子组件也可以正常获取并使用由父组件传过来的数据;但是,子组件中不能直接修改父组件传过来的数据,必须要向父组件传递一个事件来父组件需要修改数据,即通过子组件的操作,在父组件中修改数据;这就是单项数据流。

废话不多说,先看演示:

在这里插入图片描述

这里可以看到我在父组件中定义了一个msg属性,子组件也获取到msg的值显示到input中,并通过修改子组件中input中的value值,实现修改了父组件里的数据。(这里遵循了单项数据流原则)实现方式如下:

普通方式实现父子组件传值

普通方式即为父组件使用自定义属性向子组件传值,通过自定义事件接收事件;子组件通过props接收数据,子组件通过$emit 向父组件传递自定义事件。

实现代码如下:

子组件:

<template>
  <div>
    我是子组件:
    <input type="text" :value="msg" @input="changeValFn" />
  </div>
</template>

<script>
export default {
  name: 'child',
  props: ['msg'],
  methods: {
    changeValFn(e) {
      this.$emit('changeMsg', e.target.value)
    },
  },
}
</script>

父组件:

<template>
  <div class="parent">
    <h1>我是父组件:{{ msg }}</h1>
    <child :msg="msg" @changeMsg="changeMsgFn"></child>
  </div>
</template>

<script>
import child from './child'
export default {
  name: 'parent',
  components: {
    child,
  },
  data() {
    return {
      msg: 'hello!',
    }
  },
  methods: {
    changeMsgFn(value) {
      this.msg = value
    },
  },
}
</script>
v-model 实现父子组件传值

v-model是语法糖, v-model等价于 给一个input框提供了 :value属性以及 @input事件,但是如果每次使用input框,都需要提供value和input事件比较麻烦,所以使用v-model

实现代码:

子组件:

<template>
  <div>
    我是子组件:
    <input type="text" :value="value" @input="changeValFn" />
  </div>
</template>

<script>
export default {
  name: 'child',
  props: ['value'],
  methods: {
    changeValFn(e) {
      this.$emit('input', e.target.value)
    },
  },
}
</script>

父组件:

<template>
  <div class="parent">
    <h1>我是父组件:{{ msg }}</h1>
    <child v-model="msg"></child>
  </div>
</template>

<script>
import child from './child'
export default {
  name: 'parent',
  components: {
    child,
  },
  data() {
    return {
      msg: 'hello!',
    }
  },
}
</script>

注意:由于这里子组件里使用的是input type=‘text’ 的控件,所以定义组件的时候,子组件props接收的值叫value,子传父触发的事件名叫 input

这里如果像在子组件中自定义接收的数据名与事件名时,你需要在与props同级的地方配置model,具体实现如下:

<template>
  <div>
    我是子组件:
    <input type="text" :value="msg" @input="changeValFn" />
  </div>
</template>

<script>
export default {
  name: 'child',
  props: ['msg'],
  model: {
    prop: 'msg',
    event: 'changeMsg',
  },
  methods: {
    changeValFn(e) {
      this.$emit('changeMsg', e.target.value)
    },
  },
}
</script>

这样就可以把接收到的数据value替换成msg,把自定义事件input替换成changeMsg。

.sync 修饰符 实现父子组件传值

.sync 修饰符 是vue 2.3.0+ 新增的特性(但是在vue3.0中被废弃)

实现代码如下

子组件:(以 update:myPropName 的模式触发事件)

<template>
  <div>
    我是子组件:
    <input type="text" :value="msg" @input="changeValFn" />
  </div>
</template>

<script>
export default {
  name: 'child',
  props: ['msg'],
  methods: {
    changeValFn(e) {
      this.$emit('update:msg', e.target.value)
    },
  },
}
</script>

父组件:(以v-bind:msg.sync="msg"的模式传递/接收数据)

<template>
  <div class="parent">
    <h1>我是父组件:{{ msg }}</h1>
    <!-- <child v-bind:msg.sync="msg"></child> -->
    <child :msg.sync="msg"></child>
  </div>
</template>

<script>
import child from './child'
export default {
  name: 'parent',
  components: {
    child,
  },
  data() {
    return {
      msg: 'hello!',
    }
  },
}
</script>

注意:

  1. 带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:msg.sync=”msg + ‘!’” 是无效的)。取而代之的是,你只能提供你想要绑定的 property 名,类似 v-model

  2. v-bind.sync 用在一个字面量的对象上,例如 v-bind.sync=”{ msg: msg }”,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。

vue3.0中父子组件传值

vue3.0中废弃了 .sync ,并把所有使用 .sync 的部分并将其替换为 v-model:

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

<!-- 替换为 -->

<ChildComponent v-model:title="pageTitle" />

实现代码如下:

子组件:

<template>
  <label>我是子组件:</label>
  <input type="text" :value="msg" @input="changeValFn" />
</template>

<script>
export default {
  name: 'child',
  props: ['msg'],
  methods: {
    changeValFn(e) {
      this.$emit('update:msg', e.target.value)
    },
  },
}
</script>

父组件:

<template>
  <h1>我是父组件:{{ msg }}</h1>
  <child v-model:msg="msg"></child>
</template>

<script>
import child from './components/child'
export default {
  name: 'App',
  components: {
    child,
  },
  data() {
    return {
      msg: 'hello!',
    }
  },
}
</script>

注意:

子组件中对于所有不带参数的 v-model,请确保分别将 prop 和 event 命名更改为 modelValueupdate:modelValue

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐