Vue3的部分Composition API的简单使用( part 3 )

1,309 阅读1分钟

组合API

父子通讯

1.setup函数有两个参数,第一个参数为props,第二个参数为一个对象context
2.props为一个对象,内部包含了父组件传递过来的所有prop数据,context对象包含了attrs,slots, emit属性,其中的emit可以触发自定义事件的执行从而完成子传父

父传子

父组件

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

子组件

<template>
  <div>
    从父组件中接收的prop
    <p v-for="item in list" :key="item">
      {{item.name}}, {{item.id}}
    </p>
  </div>
</template>

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

<style>

</style>

image.png

子传父

子组件

<template>
  <div>
    从父组件中接收的prop
    <p v-for="item in list" :key="item">
      {{item.name}}, {{item.id}}
    </p>
  </div>
  <div>
    添加新公司
    <p>新公司:<input v-model="name"></p>
    <button @click="add">添加</button>
  </div>
</template>

<script>
import { ref } from 'vue'
export default {
  // 子组件接收父组件数据使用props即可
  props: {
    list: {
      type: Array,
      required:true,
      default:()=>[]
    }
  },
  setup(props, {emit}) {
    const name = ref('')
    const add = () => {
      console.log(name.value)
      emit('add-company', name.value)
    }
    return {
      name,
      add
    }
  }
}
</script>

父组件

<template>
  <h1>父组件</h1>
  <Son :list="list" @add-company="hAdd" />
</template>
<script>
import Son from './fatehrson.vue'
import { reactive } from 'vue'
export default {
  name: 'App',
  components: {
    Son
  },
  setup () {
    const list = reactive([{id:1, name: 'JD'}, {id:2, name: 'DiDi'}])
    const hAdd = (companyName) => {
      list.push({id: Date.now(), name: companyName})
    }
    return {
      list,
      hAdd
    }
  }
}
</script>

image.png

总结

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

祖先传后代

image.png

步骤

1.祖先组件提供数据:provide('数据名1', 数据名)
2.后代组件使用数据:inject('数据名1')

代码演示

Father.vue

<template>
  <div class="container">
    <h1>父组件 {{money}} <button @click="money=1000">发钱</button></h1>
    <hr>
    <Son />
  </div>
</template>
<script>
import { provide, ref } from 'vue'
import Son from './Son.vue'
export default {
  name: 'App',
  components: {
    Son
  },
  setup () {
    const money = ref(100)
    // 将数据提供给后代组件 provide
    provide('money', money)

    return { money }
  }
}
</script>

Son.vue

<template>
  <div class="container">
    <h2>子组件 {{money}}</h2>
    <hr>
    <GrandSon />
  </div>
</template>
<script>
import { inject } from 'vue'
import GrandSon from './GrandSon.vue'
export default {
  name: 'Son',
  components: {
    GrandSon
  },
  setup () {
    // 接收祖先组件提供的数据
    const money = inject('money')
    return { money }
  }
}
</script>

GrandSon.vue

<template>
  <div class="container">
    <h3>孙组件 {{money}}</h3>
  </div>
</template>
<script>
import { inject } from 'vue'
export default {
  name: 'GrandSon',
  setup () {
    const money = inject('money')

    return {money}
  }
}
</script>

image.png

总结

  • provide函数提供数据和函数给后代组件使用
  • inject函数给当前组件注入provide提供的数据和函数

后代改祖先

image.png

步骤

1.祖先组件中提供数据&操作数据的函数fprovide('函数f', 数据名)
2.后代组件中获取操作数据的函数f,并调用数据: inject('函数f')