Vue3 组件通讯 组件传值

vue3 组件通讯

父子通讯

父传子
  1. 父组件向子组件传递数据:自定义属性 props
  2. 子组件向父组件传递数据 : 自定义事件 $emit()
  3. 子组件模板中直接可以获取props中的属性值
  4. js代码中需要通过setup函数的第一个形参props获取属性值

父组件:

<template>
  <div>
    <div>父子组件的交互</div>
    <button @click='money=200'>修改</button>
    <hr>
    <Child :money='money' />
  </div>
</template>

<script>
import Child from './Child.vue'
import { ref } from 'vue'

export default {
  name: 'App',
  components: { Child },
  setup () {
    const money = ref(100)
    return { money }
  }
}
</script>

子组件:

<template>
  <div>
    子组件 {{money}}
  </div>
  <button @click='getMoney'>点击</button>
</template>
<script>
export default {
  name: 'Child',
  props: {
    money: {
      type: Number,
      default: 0
    }
  },
  setup (props) {
    // Vue3中,使用形参props获取所有父组件传递的数据
    // props的数据是只读的,不可以在子组件直接修改
    const getMoney = () => {
      console.log(props.money)
    }
    return { getMoney }
  }
}
</script>

子传父
  1. 通过setup函数的参数二context.emit方法触发自定义事件 context.emit('send-money', 50)
  2. 子组件触发的自定义事件需要在emits选项中进行声明(直观的看到本组件触发了那些自定义事件)

父组件:

<template>
  <div>
    <div>父子组件的交互</div>
    <button @click='money=200'>修改</button>
    <hr>
+    <Child :money='money' @send-money='getMoney' />
  </div>
</template>

<script>
import Child from './Child.vue'
import { ref } from 'vue'

export default {
  name: 'App',
  components: { Child },
  setup () {
    const money = ref(100)
+    const getMoney = (value) => {
+      // value就是子组件传递回来的钱
+      money.value = money.value - value
+    }
+    return { money, getMoney }
  }
}
</script>

子组件:

<template>
  <div>
    子组件 {{money}}
  </div>
  <button @click='getMoney'>点击</button>
</template>
<script>
export default {
  name: 'Child',
+  // 子组件触发的自定义事件需要在emits选项中进行声明(直观的看到本组件触发了那些自定义事件)
+  emits: ['send-money'],
  props: {
    money: {
      type: Number,
      default: 0
    }
  },
  setup (props, context) {
    // Vue3中,使用形参props获取所有父组件传递的数据
    // props的数据是只读的,不可以在子组件直接修改
    const getMoney = () => {
      console.log(props.money)
      // this.$emit('send-money', 50)
      // 向父组件传递数据50
+      context.emit('send-money', 50)
    }
    return { getMoney }
  }
}
</script>

后代元素的传值 依赖注入 provide inject

使用场景:有一个父组件,里头有子组件,有孙组件,有很多后代组件,共享父组件数据。

父向后代传值
  1. 父传子孙数据:provide
  2. 子孙得到数据:inject

父组件:

<template>
  <div>
    <div>父子组件的交互</div>
    <button @click='money=200'>修改</button>
    <hr>
    <Child :money='money' @send-money='getMoney' />
  </div>
</template>

<script>
import Child from './Child.vue'
+ import { ref, provide } from 'vue'

export default {
  name: 'App',
  components: { Child },
  setup () {
+    // 直接把数据传递出去
+    provide('moneyInfo', 1000)
    const money = ref(100)
    const getMoney = (value) => {
      // value就是子组件传递回来的钱
      money.value = money.value - value
    }
    return { money, getMoney }
  }
}
</script>

孙组件:

<template>
  <div>
+    孙子组件:{{moneyInfo}}
  </div>
</template>
<script>
+ import { inject } from 'vue'

export default {
  name: 'GrandSon',
  setup () {
+    const moneyInfo = inject('moneyInfo')
+    return { moneyInfo }
  }
}
</script>

子组件:

<template>
  <div>
+    子组件 {{money}} --- {{moneyInfo}}
  </div>
  <button @click='getMoney'>点击</button>
  <GrandSon />
</template>
<script>
import GrandSon from '@/GrandSon'
import { inject } from 'vue'
export default {
  name: 'Child',
  components: { GrandSon },
  // 子组件触发的自定义事件需要在emits选项中进行声明(直观的看到本组件触发了那些自定义事件)
  emits: ['send-money'],
  props: {
    money: {
      type: Number,
      default: 0
    }
  },
  setup (props, context) {
+    const moneyInfo = inject('moneyInfo')
    // Vue3中,使用形参props获取所有父组件传递的数据
    // props的数据是只读的,不可以在子组件直接修改
    const getMoney = () => {
      console.log(props.money)
      // this.$emit('send-money', 50)
      // 向父组件传递数据50
      context.emit('send-money', 50)
    }
+    return { getMoney, moneyInfo }
  }
}
</script>
后代向父(祖先传值)

子组件传递数据给爷爷组件,需要通过provide一个函数的方式实现

  1. 爷爷组件传递一个函数,后续通过函数的形参获取数据
  2. 孙子组获取并调用该函数传递数据

父组件:

<template>
  <div>
    <div>父子组件的交互</div>
    <button @click='money=200'>修改</button>
    <hr>
    <Child :money='money' @send-money='getMoney' />
  </div>
</template>

<script>
import Child from './Child.vue'
import { ref, provide } from 'vue'

export default {
  name: 'App',
  components: { Child },
  setup () {
    // 直接把数据传递出去
    provide('moneyInfo', 1000)
    // 把一个函数传递给孙子
+    const handleMoney = (value) => {
+      console.log('孙子传递的数据:', value)
+    }
+    provide('handleMoney', handleMoney)
    const money = ref(100)
    const getMoney = (value) => {
      // value就是子组件传递回来的钱
      money.value = money.value - value
    }
    return { money, getMoney }
  }
}
</script>

孙子组件:

<template>
  <div>
    孙子组件:{{moneyInfo}}
  </div>
+  <button @click='handleSend'>点击给爷爷数据</button>
</template>
<script>
import { inject } from 'vue'

export default {
  name: 'GrandSon',
  setup () {
    const moneyInfo = inject('moneyInfo')
+    const handleMoney = inject('handleMoney')
+    const handleSend = () => {
+      // 调用爷爷传递函数
+      handleMoney(200)
+    }
    return { moneyInfo, handleSend }
  }
}
</script>

vue3中的v-model

取代了.sync修饰符

  1. Vue2的规则
    1. Vue2中v-model默认绑定的属性是value
    2. Vue2中v-model默认绑定的事件是@input
  2. Vue3的规则
    1. Vue3中v-model默认绑定的属性是modelValue
    2. Vue3中v-model默认绑定的事件是@update:modelValue

父组件:

<template>
  <div>
    <div>v-model指令用法-Vue3</div>
    <hr>
    <div>{{info}}</div>
    <div>{{msg}}</div>
    <!-- v-model提供了一种双向绑定机制(在组件上-父子之间的数据交互) -->
    <!-- .sync修饰符已经被废弃,替代方案是v-model -->
    <!-- <TestEvent v-model='info' :msg.sync='msg' /> -->
    <TestEvent v-model:modelValue='info' v-model:msg='msg' />
    <!-- <TestEvent :modelValue='info' @update:modelValue='info=$event' /> -->
  </div>
</template>
<script>
import TestEvent from './TextEvent.vue'
import { ref } from 'vue'

export default {
  name: 'App',
  components: { TestEvent },
  setup () {
    const info = ref('hello')
    const msg = ref('hi')

    return { info, msg }
  }
}
</script>

子组件:

<template>
  <div>
    子组件 {{modelValue}}
  </div>
  <button @click='handleEdit'>点击</button>
</template>
<script>
export default {
  name: 'TestEvent',
  props: {
    // Vue3中,v-model默认绑定的属性名称是modelValue
    modelValue: {
      type: String,
      default: ''
    },
    msg: {
      type: String,
      default: ''
    }
  },
  setup (props, context) {
    const handleEdit = () => {
      // props.modelValue = 'nihao'
      // 通知父组件修改数据
      // .sync修饰符:update:绑定的属性名称
      context.emit('update:modelValue', 'nihao')
      context.emit('update:msg', 'coniqiwa')
    }
    return { handleEdit }
  }
}
</script>

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值