props
实现了父组件给子组件传值
- 父组件
<template>
<div class="box">
<h1>父组件</h1>
<hr>
<Child info="测试" :momeny="momeny"></Child>
</div>
</template>
<script setup lang="ts">
import {ref} from 'vue'
const momeny=ref(100)
import Child from './Child.vue';
</script>
<style lang="scss" scoped>
.box{
width: 100vw;
height: 400px;
background-color: aquamarine;
}
</style>
- 子组件
<template>
<div class="te">
子组件
<br>
{{ info }}
<br>
{{ momeny }}
</div>
</template>
<script setup lang="ts">
import { PropType } from "vue";
// 需要使用到defineProps方法去接受父组件传递过来的数据
// PropType 校验数据类型
//
const props = defineProps({
info: {
// required 字段是否必传
required: true,
type: String as PropType<String>,
default: "",
},
momeny: {
required: true,
type: Number as PropType<Number>,
default:0,
},
IsA: {
required: false,
type: Boolean as PropType<Boolean>,
default:true,
}
});
</script>
<style lang="scss" scoped>
.te{
width: 400px;
height: 200px;
background-color: rgb(218, 195, 26);
}
</style>
自定义事件
实现了 子组件给父组件传值
- 父组件
<template>
<div class="box">
<h1>父组件</h1>
<hr>
<EventChile @handle="handle" @click="handleClick"/>
</div>
</template>
<script setup lang="ts">
import EventChile from './EventChile.vue'
const handle=(parms1,parm2)=>{
console.log(parms1,parm2)
}
const handleClick=(parms1,parm2)=>{
console.log(parms1,parm2)
}
</script>
<style lang="scss" scoped>
.box{
width: 100vw;
height: 400px;
background-color: aquamarine;
}
</style>
- 子组件
<template>
子组件
<br>
<button @click="handleClick">点击触发自定义事件</button>
<button @click="$emit('click','测试1',100)">点击触发</button>
</template>
<script setup lang="ts">
// 利用defineEmits 方法返回函数触发自定义事件
const $emit=defineEmits(['handle','click'])
const handleClick=()=>{
// 第一个参数事件类型,第二个 或者N个 参数为注入参数
$emit('handle','测试',100)
}
</script>
<style lang="scss" scoped></style>
全局事件总线
实现跨组件传值
- 添加mitt
cnpm i mitt
- 添加mitt
import mitt from 'mitt';
const $bus=mitt();
export default $bus;
- 父组件
<template>
<div class="box">
<h1>父组件</h1>
<hr>
<div class="box-child">
<EventChild/>
<EventChild1/>
</div>
</div>
</template>
<script setup lang="ts">
import EventChild from './EventChild.vue'
import EventChild1 from './EventChild1.vue'
</script>
<style lang="scss" scoped>
.box{
width: 100vw;
height: 400px;
background-color: aquamarine;
.box-child{
display: flex;
justify-content: space-between;
}
}
</style>
- 子组件1
<template>
<div class="child">
子组件
<br>
接受到的元素
{{ text }}
{{ memeny }}
</div>
</template>
<script setup lang="ts">
import $bus from '../../bus';
import {ref} from 'vue'
const text=ref('')
const memeny=ref(0)
$bus.on('car',(car)=>{
text.value=car.text
memeny.value=car.memeny
})
</script>
<style lang="scss" scoped>
.child{
width: 300px;
height: 300px;
background-color: yellow;
}
</style>
- 子组件2
<template>
<div class="child">
子组件
<br>
<button @click="handleClick">点击给另一个子组件传值</button>
</div>
</template>
<script setup lang="ts">
import $bus from '../../bus';
const handleClick=()=>{
$bus.emit('car',{
text:'测试',
memeny:100
})
}
</script>
<style lang="scss" scoped>
.child{
width: 300px;
height: 300px;
background-color: yellowgreen;
}
</style>
v-model
- 父组件
<template>
<div class="box">
<h1>父组件{{ momeny }}</h1>
<hr>
<ModelChild v-model:momeny="momeny" ></ModelChild>
</div>
</template>
<script setup lang="ts">
import {ref} from 'vue'
const momeny=ref(100)
import ModelChild from './ModelChild.vue';
</script>
<style lang="scss" scoped>
.box{
width: 100vw;
height: 400px;
background-color: aquamarine;
}
</style>
- 子组件
<template>
子组件
<br />
{{ momeny }}
<button @click="handleAdd">添加</button>
</template>
<script setup lang="ts">
import { PropType } from "vue";
const $emit = defineEmits(["update:momeny"]);
const props = defineProps({
momeny: {
required: true,
type: Number as PropType<Number>,
default: 0,
},
});
const handleAdd = () => {
$emit("update:momeny", props.momeny + 100);
};
</script>
<style lang="scss" scoped></style>
useAttrs
-父组件
<template>
<div class="box">
<h1>父组件</h1>
<hr>
<Child info="测试" :momeny="momeny" @click="handle"></Child>
</div>
</template>
<script setup lang="ts">
import {ref} from 'vue'
const momeny=ref(100)
import Child from './Child.vue';
const handle=()=>{
console.log(111)
}
</script>
<style lang="scss" scoped>
.box{
width: 100vw;
height: 400px;
background-color: aquamarine;
}
</style>
- 子组件
<template>
子组件
{{ atts.info }}
{{ atts.momeny }}
</template>
<script setup lang="ts">
import { useAttrs } from 'vue';
const atts= useAttrs()
console.log(atts)
</script>
<style lang="scss" scoped></style>
provide 和inject
- 父组件
<template>
<div class="box">
<h1>父组件 {{ car }}</h1>
<hr>
<Child></Child>
</div>
</template>
<script setup lang="ts">
import {ref,provide} from 'vue'
import Child from './Child.vue';
const car=ref('汽车')
// vue3 提供了provide(提供) 与inject(注入),可以实现隔辈组件传递数据
// 两个参数 :
// 1.第一个参数就是提供的数据的key
// 2.第二个参数就是需要提供的数据
provide("TOKEN",car)
</script>
<style lang="scss" scoped>
.box{
width: 100vw;
height: 400px;
background-color: aquamarine;
}
</style>
- 子组件
<template>
<div class="box2">
子组件
<hr>
<Grandson />
</div>
</template>
<script setup lang="ts">
import Grandson from './Grandson.vue';
</script>
<style lang="scss" scoped>
.box2 {
width: 100vw;
height: 300px;
background-color: rgb(24, 15, 195);
color: #FFF;
}
</style>
- 孙子组件
<template>
<div class="box1">
孙子组件
{{ car }}
</div>
</template>
<script setup lang="ts">
// 注入祖先组件提供数据
import {inject} from 'vue'
// 需要参数: 提供者的数据的Key
const car=inject('TOKEN')
</script>
<style lang="scss" scoped>
.box1{
width: 100vw;
height: 100px;
background-color: rgb(213, 5, 137);
}
</style>
ref和$parent
- 父组件
<template>
<div class="box">
<h1>父组件:{{ money }}</h1>
<button @click="handleClcik">找子组件借钱</button>
<hr>
<div class="box_child">
<Son ref="son"/>
<Do/>
</div>
</div>
</template>
<script setup lang="ts">
// ref:可以获取真实的DOM节点,可以获取到子组件实例VC
// $parent:可以在子组件内部获取到父组件的实例
import {ref} from 'vue'
import Son from './Son.vue'
import Do from './Do.vue'
const money=ref(1000)
const son= ref()
const handleClcik=()=>{
money.value+=10
son.value.money-=10
son.value.handleCL()
}
// 组件内部数据对外关闭的,别人不能访问
// 如果想让外部访问需要通过defineExpose方法对外暴露
defineExpose({
money,
})
</script>
<style lang="scss" scoped>
.box{
width: 100vw;
height: 400px;
background-color: aquamarine;
.box_child{
display: flex;
}
}
</style>
- 子组件1
<template>
<div class="box1">
<h1>子组件:{{ money }}</h1>
</div>
</template>
<script setup lang="ts">
import {ref} from 'vue'
const money=ref(500)
const handleCL=()=>{
console.log('子组件方法')
}
// 组件内部数据对外关闭的,别人不能访问
// 如果想让外部访问需要通过defineExpose方法对外暴露
defineExpose({
money,
handleCL
})
</script>
<style lang="scss" scoped>
.box1{
width: 100vw;
height: 300px;
background-color: rgb(12, 107, 185);
}
</style>
- 子组件2
<template>
<div class="box1">
<h1>子组件:{{ money }}</h1>
<button @click="handleClickD($parent)">想父组件借钱</button>
</div>
</template>
<script setup lang="ts">
import {ref} from 'vue'
const money=ref(200)
const handleClickD=($parent)=>{
console.log(parent)
money.value+=20
$parent.money-=20
}
</script>
<style lang="scss" scoped>
.box1{
width: 100vw;
height: 300px;
background-color: rgb(150, 16, 128);
}
</style>