provide和inject在vue3+ts中用法,以及我们修改孙子组件的值,所有组件的值都变化,兄弟组件传参复杂方式
provide和inject在vue3+ts中用法,以及我们修改孙子组件的值,所有组件的值都变化,兄弟组件传参复杂方式
·
1、在vue中,我们经常用到的组件传参方式,就是父传子,使用props接受。子传父,使用$emit。
provide可以在祖先组件中指定我们要传给后代组件的值或者方法,在后代任何组件中我们都可以使用inject来接受祖先组件的值。
①首先我们看下app.vue根组件我们定义一个provide
<template>
<!-- 路由出口 -->
我是根组件
<RouterView />
</template>
<script setup lang="ts">
// 导入 RouterView
import { provide, ref } from 'vue'
import { RouterView } from "vue-router";
import A from "@/components/A.vue"
provide('flag', ref(false))
</script>
<style lang="scss">
html,
body,
#app {
height: 100%;
width: 100%;
background: black;
color: #fff;
}
</style>
②子组件
<template>
<div class="a_main">
我是A组件{{ data }}
<B></B>
</div>
</template>
<script lang='ts' setup>
import { inject } from 'vue'
import B from '@/components/B.vue'
let data = inject('flag')
</script>
<style scoped lang="scss">
.a_main {
width: 800px;
height: 800px;
background: red;
color: #fff;
margin-top: 200px;
}
</style>
③孙子组件,我们在这个组件中修改值,所有组件的值都变化
<template>
<div class="b_main">
我是B组件{{ data }}
<button @click="changeProvide">修改值</button>
<C></C>
</div>
</template>
<script lang='ts' setup>
import { inject, Ref, ref } from 'vue'
import C from '@/components/C.vue'
let data = inject<Ref<boolean>>('flag', ref(false))
const changeProvide = () => {
data.value = !data.value
}
</script>
<style scoped lang="scss">
.b_main {
width: 300px;
height: 300px;
background: blue;
margin-top: 200px;
}
</style>
④重孙子组件
<template>
<div class="c_main">
我是C组件{{ data }}
</div>
</template>
<script lang='ts' setup>
import { inject } from 'vue'
let data = inject('flag');
</script>
<style scoped lang="scss">
.c_main {
width: 300px;
height: 300px;
background: green;
margin-top: 200px;
}
</style>
2、 兄弟组件传参。
可能我们了解的方式比较少的时候我们可能会用子组件传给父组件,然后父组件再传给子组件这种方式,不是不可以,就是麻烦。
先举例子,如下麻烦的方法
注意工作中千万别这么用哈下面的这个方法。
同级组件A给B传参,麻烦的方法如下:
A组件
<template>
<div class="a_main">
我是A组件
<button @click="changeEmit">修改值</button>
</div>
</template>
<script lang='ts' setup>
import { defineEmits, ref } from 'vue'
let emit = defineEmits(['on-click'])
let flag = false
const changeEmit = () => {
flag = !flag
emit('on-click', flag)
}
</script>
<style scoped lang="scss">
.a_main {
width: 100%;
height: 200px;
background: red;
color: #fff;
}
</style>
父组件
<template>
<div class="home_main">
<A @on-click="clickEmit"></A>
<B :flag="Flag"></B>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, defineEmits } from "vue"
import A from "@/components/A.vue"
import B from '@/components/B.vue'
let Flag = ref(false);
const clickEmit = (params: boolean) => {
Flag.value = params
}
</script>
<style lang="scss">
.home_main {
width: 100%;
height: 100vh;
background: green;
font-size: 18px;
.move_info {
transition: all 1s;
}
.content {
display: flex;
flex-wrap: wrap;
text-align: center;
width: calc(50px * 10 + 9px);
box-sizing: border-box;
padding: 10px 19px;
border: 1px solid red;
margin: 30px auto;
box-sizing: border-box;
.box {
font-size: 50px;
height: 50px;
width: 50px;
border: 1px solid #ddd;
}
}
.ap_from {
width: 0;
height: 0;
transform: rotate(360deg);
}
.ap_active {
transition: all 1.5s ease;
}
.ap_to {
width: 200px;
height: 200px;
}
.el-from {
width: 0;
height: 0;
transform: rotate(360deg);
}
.fade-enter-active {
transition: all 1.5s ease;
}
.fade-enter-to {
width: 200px;
height: 200px;
}
.el-from {
width: 200px;
height: 200px;
transform: rotate(-360deg);
}
.fade-leave-active {
transition: all 5s ease;
}
.fade-leave-to {
width: 0;
height: 0;
}
}
</style>
B组件
<template>
<div class="b_main">
我是B组件{{ flag }}
</div>
</template>
<script lang='ts' setup>
import { defineProps, ref } from 'vue'
import C from '@/components/C.vue'
type Props = {
flag: boolean
}
defineProps<Props>()
</script>
<style scoped lang="scss">
.b_main {
width: 300px;
height: 300px;
background: blue;
}
</style>
如上,确实可以传参,就是比较麻烦。明天给大家写个比较简单的方法,我们要循序渐进。加油
更多推荐
已为社区贡献3条内容
所有评论(0)