## 父、子组件通过provide/inject传递数据
在父组件中放入子组件均会用到的变量。这种做法的好处是无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。
<script lang='ts'>
import { ref, provide } from 'vue'
export default {
setup(){
const asideVisible = ref(false)
provide('to_child',asideVisible)
}
}
</script>
在子组件中获取,return出来就可以在组件中使用了。
<script lang='ts'>
import { Ref, inject } from 'vue'
export default {
setup(){
const asideVisible = inject<Ref<boolean>>('to_child')
return { asideVisible }
}
}
</script>
子组件内部数据的传递
通过在组件中使用ref定义数据的初始状态和修改数据的方法来实现,注意读取ref的值时要使用checked.value。
<template>
<button @click="toggle" :class="{checked}">
//如果checked为真,class加上checked
<span></span>
</button>
</template>
<script lang="ts">
import { ref } from 'vue'
export default {
setup(){
const checked = ref(false)
const toggle = ()=>{ checked.value = !checked.value }
return {checked, toggle}
}
}
</script>
父子组件通信
在父组件中的子组件上添加事件,控制子组件的状态。
<template>
<div> <Child :value='y' @input='y = $event' />
//v-bind:value = 'y' </div>
</template>
<script lang='ts'>
import Child from '@/lib/Child.vue'
export default{
components:{ Child },
setup(){ const y = ref(true)
return { y }
}
}
</script>
在子组件中,使用props来获取value。但是不能直接使用props.value来修改,只能通过setup的第二个参数context的方法emit来修改数据。
<button @click="toggle" :class="{checked:value}">
...
...
export default {
props:{ value:Boolean //直接就可以展示在子组件的template中,与setup无关。 },
setup(props,context){
const toggle = ()=>{
context.emit('input',!props.value)
//通过context.emit 触发input事件 实现父子组件通信 }
return { toggle }
}
}
内部数据 vs 父子数据
子组件中使用ref定义数据的初始状态并创建修改数据的方法。这种方法简单,但不能与外部交流。
父子间的数据传递:如上例,父组件在使用的子组件上添加:value = 'y'(初始状态) 以及 @input = 'y = $event'。子组件通过props.value来获得数据的初始值,通过自定义方法,通过设定context.emit触发input事件来修改。父组件通过@input = 'y = $event'来拿到emit触发事件的结果,即props.value = !props.value。将value的值变为!value。从而实现组件通信。
input只是为了好理解,真正的事件名字与value有关,叫做update:value。
父组件上应该这样写:
<Child :value='y' @update:value='y = $event' />
//而这种写法可以写成
<Child v-model:value='y' />
同时子组件也应该把input改为update:value
setup(props,context){
const toggle = ()=>{
context.emit('update:value',!props.value) //通过context.emit 触发update:value事件 实现父子组件通信
}
return { toggle }
}
如果写成
<Child v-model='y' />
相当于传modelValue给props而非自定义的propsName。