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>

如上,确实可以传参,就是比较麻烦。明天给大家写个比较简单的方法,我们要循序渐进。加油

兄弟组件传参的简便方式,想知道的赶紧点击

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3使用TypeScript获取动态组件component实例调用里面组件的方法,可以先通过 `ref` 获取动态组件的实例,再通过 `as` 关键字将其转换为具体的子组件类型,从而调用子组件的方法。 例如,假设有一个动态组件 `MyComponent`,其包含了一个子组件 `ChildComponent`,并且我们需要在父组件获取 `ChildComponent` 实例并调用其方法。可以使用如下代码: ```vue <template> <div> <component :is="selectedComponent" ref="myComponent"></component> <button @click="handleClick">Call Child's Method</button> </div> </template> <script lang="ts"> import { defineComponent, ref } from 'vue' import ChildComponent from './ChildComponent.vue' export default defineComponent({ components: { ChildComponent }, data() { return { selectedComponent: 'ChildComponent' } }, setup() { const myComponentRef = ref<MyComponent | null>(null) const handleClick = () => { const childComponent = myComponentRef.value?.$refs.child as ChildComponent if (childComponent) { childComponent.doSomething() } } return { myComponentRef, handleClick } } }) </script> ``` 在上面的代码,我们使用 `ref` 将动态组件 `MyComponent` 的实例绑定到 `myComponentRef` 变量上,并使用 `as` 关键字将其类型转换为 `MyComponent | null`。然后,在 `handleClick` 方法,我们通过 `myComponentRef.value?.$refs.child` 获取到子组件 `ChildComponent` 的实例,并将其类型转换为 `ChildComponent`。最后,我们就可以调用 `ChildComponent` 的方法了。 需要注意的是,在模板使用 `ref` 时,需要添加一个 `.value` 后缀来访问 `ref` 变量所引用的对象。例如,上面的代码,我们通过 `myComponentRef.value?.$refs.child` 来获取子组件 `ChildComponent` 的实例。 另外,如果子组件的方法需要访问子组件的数据或者方法,可以使用 `provide` 和 `inject` 方法来实现。具体使用方法可以参考 Vue3 官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值