本文中使用到的组合式Api写法方式,可以参考vue3文档:ts与组合式Api
?子组件接收到的值仅仅只是可读的,不可以修改
? ? ? ?用法步骤为:
1.父组件中准备一个a,值为1,标签内把a这个值传给子组件
2.子组件通过defineProps方法接收(setup语法糖写法)
? ? ? ? 相关代码如下:
? ? ? ? 父组件:
<template>
<div>
<h1>向子组件传递a的值</h1>
<son :A="a"/>
</div>
</template>
<script setup lang="ts">
import{ref} from "vue";
import Son from "@/components/son.vue";
const a=ref(10);
</script>
<style scoped>
</style>
? ? ? ?子组件:
<template>
<div>
a的值是:{{ value }}
</div>
</template>
<script setup lang="ts">
import {ref} from "vue";
const props = defineProps<{
A: number
}>()
const value = ref<number>(props.A)
</script>
<style scoped>
</style>
? 本质是让子组件区触发父组件的函数
?父组件值能接收过来并使用或者修改,但无法改变子组件中该属性的值
? ? ? ? 用法步骤为:
? ? ? ? 1.在父组件中定义函数,该函数用于接收子组件通过emits传过来的值以及修改父组件页面中的值
? ? ? ? 2.在子组件标签内部把该函数传递给子组件
? ? ? ? 3.子组件通过emits方式接收
? ? ? ? 4.子组件通过某种方式触发该emits
代码如下:
父组件:
<template>
<div>
<div>a:{{a}}</div>
<son @changeA="triggerEvent"/>
</div>
</template>
<script setup lang="ts">
import{ref} from "vue";
import Son from "@/components/son.vue";
const a=ref(0);
//这里的X是子组件通过emit传递过来的
const triggerEvent=(X:number)=>{
a.value=X
}
</script>
<style scoped>
</style>
子组件:
<template>
<div>
<button @click="emits('changeA',20)">修改父组件A的值</button>
</div>
</template>
<script setup lang="ts">
const emits=defineEmits<{
(e:'changeA',value:number):void
}>()
</script>
<style scoped>
</style>
????????父子组件都可以修改传递的值
? ? ? ? 该方式本质其实就是emits的语法糖形式,用法步骤为
1.父组件在子组件的标签内传递信息(需要使用v-model)
2.子组件通过defineProps方式与defineEmits接收(setup语法糖写法)
(第二步需要注意,对于defineEmits的方法名称有要求,不可以随便起名,接下来的代码会展示到)? ??
? ? ? ? 父组件:
? ? ? ? ? ? ? ?在模板中定义了a的值,并且通过v-model传递给了子组件 v-model:A=“a”,这里的大写A是给a的命名(在子组件中使用)
<template>
<div>
a的值是:{{a}}
<button @click="a++">父组件+1</button>
<son v-model:A="a" />
</div>
</template>
<script setup lang="ts">
import{ref} from "vue";
import Son from "@/components/son.vue";
const a=ref(0);
</script>
? ? ? ? 子组件:
? ? ? ? 这里用props与emits分别接收,注意,这里的emits的事件名称值要写为 “update:x”,这里的x是可以更改的。(setup语法糖写法,可以参考vue3文档 ts与组合式Api)
<template>
<div>
<button @click="add">子组件+1</button>
</div>
</template>
<script setup lang="ts">
import {watchEffect} from "vue";
const props = defineProps<{
A:number
}>()
const emits=defineEmits<{
(e:'update:A',value:number):void
}>()
watchEffect(()=>{
console.log(props.A)
})
const add=()=>{
emits('update:A',props.A+1)
}
</script>
这样一来无论点击父组件或者是子组件的按钮,a的值都会+1,并且二者共享父组件a的值。(父子组件都可以修改A的值)
? ? ? ? 父孙组件共享该数据,二者都可以对其进行修改
无论是在孙组件还是父组件中让a值+1,双方共享的a的值都会+1(与v-model通信方式类似)
?用法步骤:
1.在父组件中准备一个值a
2.父组件通过provide传递该值给孙组件
3.孙组件通过inject接收
?相关代码:
父组件:
<template>
<div>
<h1>父组件</h1>
父组件的a值:{{a}}
<button @click="add">a值+1</button>
<hr>
<son/>
</div>
</template>
<script setup lang="ts">
import{ref,provide} from "vue";
import Son from "@/components/son.vue";
const a=ref<number>(0);
provide('A',a);
const add=()=>{
a.value++;
}
</script>
<style scoped>
</style>
子组件:这里注意inject的写法,标注好a的类型(具体写法可以参考顶部的文档)
<template>
<div>
<h1>孙组件</h1>
孙组件的a值:{{ a }}
<button @click="add">a值+1</button>
</div>
</template>
<script setup lang="ts">
import {inject, Ref} from "vue";
const a = inject<Ref<number>>('A')
const add = () => {
if (a) {
a.value++
}
}
</script>
<style scoped>
</style>