Vue3组件通讯(父子组件通讯)详解

1、父子通讯-父传子

前置知识:

setup函数有两个参数第一个参数为props,第二个参数为一个对象context

props为一个对象,内部包含了父组件传递过来的所有prop数据

context对象包含了attrs,slots, emit属性,其中的emit可以触发自定义事件的执行从而完成子传父

父传子:

代码示例:

父组件:app.vue

<template>
<div style="border:1px solid #ccc;margin:1em;padding:1em">

  <h1>父组件</h1>
  <p>父组件:{
   
   {list}}</p>
  <Son :list="list" />
</div>
</template>
<script>
import Son from './son.vue'
import { reactive } from 'vue'
export default {
  name: 'App',
  components: {
    Son
  },
  setup () {
    const list = reactive([{id:1, name: 'Vivian'}, {id:2, name: 'Lily'}])
    return {  
      list
    }
  }
}
</script>

子组件 son.vue

<template>
  <div style="border:1px solid #ccc;margin:1em;padding:1em">
    从父组件中接收的prop
    <p v-for="item in list" :key="item">
      公司名:{
   
   {item.name}}, ID:{
   
   {item.id}}
    </p>
  </div>
</template>

<script>
export default {
  // 子组件接收父组件数据使用props即可
  props: {
    list: {
      type: Array,
      required:true,
      default:()=>[]
    }
  },
  setup(props) {
    console.log(props.list.length)
  }
}
</script>

2、父子通讯-子传父

子传父:

子组件:

<template>
  <div>
    添加人名
    <p>新人名:<input v-model="name"></p>
    <button @click="add">添加</button>
  </div>
</template>

<script>
import { ref } from 'vue'
export default {
  setup(props, {emit}) {
    const name = ref('')
    const add = () => {
      console.log(name.value)
      emit('addUsers', name.value)
    }
    return {
      name,
      add
    }
  }
}
</script>

父组件:

<template>
  <h1>父组件</h1>
  <hr>
  <Son :list="list"  @addUsers="hAdd"/>
</template>
<script>
import Son from './UsersList.vue'
import { reactive } from 'vue'
export default {
  name: 'App',
  components: {
    Son
  },
  setup () {
    const list = reactive([{id:1, name: 'Vivian'}, {id:2, name: 'Lily'}])
    const hAdd = (userName) => {
      list.push({id: Date.now(), name: userName})
    }
    return {
      list,
      hAdd
    }
  }
}
</script>

总结:

父传子:在setup中使用props数据 setup (props) { //props 就是父组件数据 }

子传父:触发自定义事件的时候emit来自setup (props, {emit}) { //emit 就是触发事件函数 } 

3、vue3中的v-model语法糖

对比Vue2中的v-model

<Son v-model="msg" />
<!--vue2中 上面的写法等价于下边-->  
<Son :value="msg"  @input="val=>msg=val" />`

 在vue3.0中v-model语法糖有所调整:

<Son v-model="msg" />
<!--vue3中 上面的写法等价于下边-->  
<Son :modelValue="msg"  @update:modelValue="val=>msg=val"/>

父组件:

<template>
  <div class="container">
    <Son v-model="count" />
  </div>
</template>
<script>
import { ref } from 'vue'
import Son from './Son.vue'
export default {
  name: 'App',
  components: {
    Son
  },
  setup () {
    const count = ref(10)
    return { count }
  }
}
</script>

子组件:

<template>
  <div class="container">
    <h2>子组件 {
   
   {modelValue}} <button @click="fn">改变数据</button></h2>
  </div>
</template>
<script>
export default {
  name: 'Son',
  props: {
    modelValue: {
      type: Number,
      default: 0
    }
  },
  setup (props, {emit}) {
    const fn = () => {
      // 改变数据
      emit('update:modelValue', 100)
    }
    return { fn }
  }
}
</script>

总结 : 

在setup的两个参数中获取props和emit

父传子 props: :modelValue

子传父 emit @update : modelValue

猜你喜欢

转载自blog.csdn.net/qq_61006976/article/details/122342758