setup是一个组件选项,在组件被创建之前,props 被解析之后执行。它是组合式 API 的入口。
他接受两个参数:

{Data} props
{SetupContext} context

通常情况下,我们用props把数据传递给子组件,子组件通过emit把数据传递给父组件。但是当层级比较多的时候,比如祖先组件和重孙组件需要传递数据,而中间的那些组件不需要,用propsemit就显得有些繁琐了,这时候我们可以用provideinjectprovide提供一个具有名字的变量传递给子孙组件,子孙组件用inject接收同名变量,就能够使用了。
区别于选项模式,在setup中,我们要手动引入provideinject,话不多说,直接上示例。

父组件index.vue

<script lang="ts">
import { ref,provide } from "vue"
import InjectTest from './injectTest.vue'
export default {
    components:{InjectTest},
    setup(){
    	//创建hello变量
        const hello = ref<string>("hello world")
        //传递给子组件的变量message,值是hello变量
        //这里也可以直接传递一个值,比如provide("message","hello wrold")
        provide("message",hello)
        //一个用来修改hello变量的函数
        const changeProvide = (val:string)=>{
            hello.value = val
        }
        //把修改hello变量的函数,传递给子组件
        provide("changeProvide",changeProvide)
        //在父组件中修改hello变量,2秒后可以看到页面上子组件的数据也发生了变化。
        setTimeout(()=>{
            hello.value = "你好,世界"
        },2000)
        return {
        }
    },
}
</script>
<template>
    <div>
        <InjectTest></InjectTest>
    </div>
</template>

子组件injectTest.vue

<script lang="ts">
import { inject } from 'vue'
export default {
    setup(){
    	//接收父组件变量message
        const injectMessage = inject("message")
        //接收父组件修改message的函数changeProvide,可以在子组件修改父组件provide变量
        const changeProvide = inject("changeProvide")
        //其实对于响应式变量和对象来说,子组件也可以直接修改父组件的变量,
       //但是建议不要这样修改,如果这个provide有很多子组件在用,
       //那么通过子组件修改变量的值,会让维护变得异常麻烦。
        const changeMessage = ()=>{
            injectMessage.value = '66666666666'
        }
        return {
            injectMessage,
            changeProvide,
            changeMessage
        }
    }
}
</script>
<template>
<div>{{injectMessage}}</div>
<button @click="changeProvide('子孙组件修改数据')">inject</button>
<button @click="changeMessage">按钮</button>
</template>

通过子组件的注释,咱们了解到,尽量不要用子组件直接修改provide的值,如果从父组件出发就想禁止子组件修改的话,咱们可以引入readonly,修改父组件index.vue的两行代码:

import { ref,provide,readonly } from "vue"
provide("message",readonly(hello))

这个时候,provide的值对于子组件来说,就是只读的,子组件不能直接修改provide变量,但是可以通过父组件传递给子组件的方法去修改,例如上边的子组件,changeProvide方法可以修改,但是changeMessage方法不能修改。

下边是setup语法糖的inject代码,provide同理,因为都是引入的provideinject,语法糖和setup选项没有什么不同,除了不用return函数或者变量。

语法糖子组件injectTest.vue

<script setup lang="ts">
import { inject } from 'vue'
const injectMessage = inject("message")
const changeProvide = inject("changeProvide")
const changeMessage = ()=>{
	//injectMessage.value如果红线报错的话,可以这样写
    (injectMessage as any).value = '66666666666'
}
</script>
<template>
<div>{{injectMessage}}</div>
<button @click="changeProvide('子孙组件修改数据')">inject</button>
<button @click="changeMessage">按钮</button>
</template>

有帮助的话,点个赞呗!关于vue3的一切疑问,大家可以在评论区留言提问。

上一篇:vue3 setup如何使用props?
下一篇:vue3 setup如何使用computed?

Logo

前往低代码交流专区

更多推荐