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

Tde*_*oij 8 vue.js vuejs3 vue-composition-api

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

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

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

但是,在记录父级时,它只是打印出未定义:

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
  }
};
Run Code Online (Sandbox Code Playgroud)

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

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
  }
};
Run Code Online (Sandbox Code Playgroud)

我对 JavaScript 中的代理有点陌生,但从我对它们的阅读来看,以及对 react() 返回的代理进行试验。我应该能够像通常使用对象一样访问该属性。关于我做错了什么的任何想法?

我创建了一个代码沙盒来重现问题

Hen*_*ker 8

You can use getCurrentInstance. Vue documentation.

Its as easy as:

import { getCurrentInstance } from "vue";
export default {
  setup(props) {
    const instance = getCurrentInstance();
    console.log("parent");
    console.log(instance.parent);
  }
}
Run Code Online (Sandbox Code Playgroud)

Also, probably worth noting that Vue composition api plugin exposes parent in the same way, but it is referenced as instance.$parent there.

  • 由于某种原因,新的 Vue wiki 没有关于“getCurrentInstance”的文章。但它仍然可以使用。 (3认同)

小智 7

我知道这并不能直接回答问题,但是使用provide/inject(https://v3.vuejs.org/guide/component-provide-inject.html)帮助我解决了同样的问题,我想得到一个从父节点获取 data 属性并将其传递给渲染组件,但从 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);

Run Code Online (Sandbox Code Playgroud)

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

我的组件.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>
Run Code Online (Sandbox Code Playgroud)

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

希望它对任何人都有帮助!