Vue 3 组合 API,如何在 setup() 函数中获取上下文父属性?

Posted

技术标签:

【中文标题】Vue 3 组合 API,如何在 setup() 函数中获取上下文父属性?【英文标题】:Vue 3 composition API, how to get context parent property in the setup() function? 【发布时间】:2020-06-01 21:04:17 【问题描述】:

我遇到了 Vue 3 (alpha 4) 的问题:

setup() 函数中,我试图读取父组件。根据https://vue-composition-api-rfc.netlify.com/api.html#setup 上的文档,它应该通过context 参数公开父级,或者作为context.attrs 的属性或直接作为父级(参见'typing' 下的SetupContext 位)。我没有发现文档很清楚是否应该直接从SetupContext 或通过SetupContext.attrs 访问parent,所以我尝试了两种方式,但无济于事。

这是我的问题,我可以在登录 SetupContextSetupContext.attrs(这是一个代理)时访问它们。 SetupContext.attrs 公开了通常的代理属性([[Handler]][[Target]][[IsRevoked]]),并且在检查 [[Target]] 时,它清楚地显示了父级 property。

但是,当记录父级时,它只是打印出 undefined:

export default 
  setup(props, context) 
    console.log(context);
    // Output: attrs: Proxy, slots: Proxy, emit: ƒ
    console.log(context.attrs);
    // Output: Proxy vnode: …, parent: …, appContext: …, type: …, root: …, …
    console.log(context.attrs.parent);
    // Output: undefined
  
;

传播上下文会产生相同的结果:

export default 
  setup(props,  attrs, parent ) 
    console.log(attrs);
    // Output: Proxy vnode: …, parent: …, appContext: …, type: …, root: …, …
    console.log(attrs.parent);
    // Output: undefined
    console.log(parent);
    // Output: undefined
  
;

我对 javascript 中的代理有点陌生,但从我读过的关于它们的内容来看,以及尝试使用 reactive() 返回的代理。我应该能够像通常使用对象一样访问该属性。关于我做错了什么有什么想法吗?

我创建了一个codesandbox 来重现问题

【问题讨论】:

如果您在attrs 中看到parent 属性但attrs.parent 未定义,那么这是因为attrs 在您登录后被填充。您可以尝试将代码放入 onMounted 挂钩中。 好建议@Paleo,我刚刚尝试过,但即使在 onMounted() 中,不幸的是两者都未定义。 我这里也有同样的问题,无法在我的App组件中访问Proxy对象的目标github.com/blacksonic/todomvc-vue-composition-api/blob/master/… 看看here和here 【参考方案1】:

您可以使用getCurrentInstance。 Vue documentation.

就这么简单:

import  getCurrentInstance  from "vue";
export default 
  setup(props) 
    const instance = getCurrentInstance();
    console.log("parent");
    console.log(instance.parent);
  

另外,可能值得注意的是,Vue composition api plugin 以相同的方式公开父级,但它在此处被引用为 instance.$parent

【讨论】:

【参考方案2】:

我知道这不能直接回答问题,但是使用提供/注入 (https://v3.vuejs.org/guide/component-provide-inject.html) 帮助我解决了同样的问题,我想从父节点获取数据属性并将其传递给渲染组件,但从 Vue2 升级到 Vue3 后无法再访问父组件。我没有尝试公开父组件,而是将其数据集中的 prop 向下传递给渲染组件。

在创建应用程序时,我执行了以下操作。

main.js

import  createApp  from "vue";
import MyComponent from './components/MyComponent.vue';

const section = document.getElementById('some-element'); // this element contains a data-attribute which I need to use within the app. In my case, I can't get the data from the component created/mounted function as the section with the data attribute is loaded onto the page multiple times with different attributes each time.

const app = createApp(MyComponent);
    app.provide('dataset', section.dataset.id); // section.dataset.id contains some kind of id, let's say 'abc123' for the sake of this example
    app.use(store); //not relevant for this answer
    app.mount(section);

然后,在组件内部,我可以通过执行以下操作来访问“数据集”。

MyComponent.vue

<template>
    <div>Normal template stuff here</div>
</template>
<script>
export default 
    name: 'MyComponent',
    inject: ['dataset'], // the magic
    created() 
        console.log(this.dataset); // will log 'abc123'
    

</script>

这是非常精简的,但我想很好地展示了我的情况。在任何情况下,如果您尝试做类似的事情并希望通过父数据属性获取数据,您可以查看提供/注入。

希望对大家有所帮助!

【讨论】:

以上是关于Vue 3 组合 API,如何在 setup() 函数中获取上下文父属性?的主要内容,如果未能解决你的问题,请参考以下文章

Vue3 组合式 API 的基础 —— setup

熬夜讲解vue3组合API中setup refreactive的用法

组合式api

组合 API - setup() 中的 Axios 请求

Vue 3 组合 API,未定义变量,生命周期

vue3组合式API之setup()介绍与reactive()函数的使用