vue2和vue3 依赖注入 provide inject

lxf2023-05-12 01:04:17

vue2

普通方式


// 祖先

export default {
    data () {
        obj: {
            url: []
        }
    },
    provide () {
       obj: this.obj
    }
}

然后 子组件 这么接

export default {
    inject: ['obj']
}

然后 子组件 就可以拿来用

<template>
    {{ obj }}
    
    {{ obj.url }}
</template>

那有的小伙伴说了,我改一下obj里面的url的值,子组件拿到的obj.url的值还是旧的值。

官方解释:provide 和 inject 绑定并不是可响应的。这里刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的property还是可响应的。

那么,到这里就要用到 响应式的处理方式了。

响应式 方法

这里用 传递 一个方法的办法

// 祖先

export default {
    data () {
        obj: {
            url: []
        }
    },
    provide () {
       getObj: () => this.obj
    }
}

然后 子组件 这么接

export default {
    inject: ['getObj'],
    computed: {
       obj () {
           return this.getObj()
       } 
    }
}

然后 子组件 就可以拿来用

<template>
    {{ obj }}
    
    {{ obj.url }}
</template>

obj.url值改了,子组件得到的就是新鲜出炉的。


问: 其他的地方也有用这个曾孙的组件,但是不传provide,会报错,这怎么解决?

没事,不是还有默认值吗

默认值

案例

不传provide,就用默认值inject,不会报错,有默认值顶着。

在 vue2 中,如果一个键在祖先提供者的provide中不存在,则会使用inject中这个键的默认值。

// 祖先组件提供的 `foo`

provide: {
    foo: 'bar'
}

// 子组件注入 'foo'

inject: {
    foo: {
        default: 'default'
    }
}

如果祖先不提供,就用子组件自己默认的。

provide 传参为方法 案例

// 祖先

export default {
    data () {
        obj: {
            url: []
        }
    },
    provide () {
       getObj: () => this.obj
    }
}

// 子组件inject的default的默认值这么写

就是一个返回对象{ url: [] }的函数


export default {
    inject: {
        getObj: {
            default: () => {
                return () => {
                    return {
                        url: []
                    }
                }
            }
        }
    },
    computed: {
       obj () {
           return this.getObj()
       } 
    }
}

上面的示例,就是vue2中provide inject 响应式 并且 不传也不会报错的(加了默认值)的例子

以此记录。


vue3 (这里讲组合式)

在vue3中,provide 和 inject 。与 vue2 不同的是,vue3 中的 provide 和 inject 默认使用了响应式的数据传递方式,这就意味着当provide中的数据发生变化是,所有使用inject注入的后代组件都能够接收到更新。

基本用法

// 祖先

<script>
    import { ref, provide } from 'vue'
    
    // 提供静态值
    provide('foo', 'bar')
    
    // 提供响应式的值
    const count = ref(0)
    provide('count', count)
</script>

// 子组件

<script>
    import { inject } from 'vue'
    
    // 注入值的默认方式
    const foo = inject('foo')
    
    // 注入值的响应式方式
    const count = inject('count')
    
    
    
    
    // 注入一个值,若为空则使用提供的默认值
    const foo = inject('foo', 'default')
</script>

提供函数 以及 接收函数 写法

// 祖先

<script>
    import { ref, provide } from 'vue'
    
    const getUser = () => {
        return {
            name: 'Jack',
            age: 35
        }
    }

    provide('getUser', getUser)
</script>

// 子组件

<script>
    import { reactive, inject } from 'vue'
     
    const getUser = inject(
        'getUser',
        () => ({})
    )
    
    const user = reactive(getUser())
    
</script>

总结

在 Vue 2 中,provideinject 提供的是一种非响应式的数据传递方式。

这意味着通过 provide 提供的数据在子组件中可以被访问和使用,但是如果在子组件中修改了这些数据,这些修改并不会反映到父组件中的数据上。

这是因为 Vue 2 中的 provideinject 使用的是普通的 JavaScript 对象来传递数据,并且这些对象不是响应式的。

相比之下,在 Vue 3 中,provideinject 默认使用响应式的数据传递方式。

这意味着通过 provide 提供的数据在子组件中可以被访问和使用,并且如果在子组件中修改了这些数据,这些修改会实时地反映到父组件中的数据上。

这是因为 Vue 3 中的 provideinject 使用的是响应式的数据结构来传递数据,例如 reactiveref

这个变化的主要原因是为了提供更好的性能和开发体验。

在 Vue 2 中,由于 provideinject 不是响应式的,所以如果需要在子组件中修改父组件中的数据,通常需要使用事件或回调函数等额外的逻辑来实现。

这样不仅增加了代码量,也可能导致性能问题。

而在 Vue 3 中,由于 provideinject 默认使用响应式的数据传递方式,这些问题都得到了有效的解决。

希望能有所帮助。

最好的学习是贡献和输出。

本文正在参加「」

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!