arco-design / arco-design-vue

A Vue.js 3 UI Library based on Arco Design
https://arco.design/vue
MIT License
2.59k stars 500 forks source link

When Drawer.open is called in a functional style, the custom component loses appContext. #3176

Closed Tracy-xu closed 3 weeks ago

Tracy-xu commented 3 weeks ago

When calling Drawer.open by function style, and the content option is a custom component rendered with the h function, the following issues occur within the custom component:

Note: When the Content component is rendered directly in the template, these issues do not occur.

Demo,stackblitz

// main.js
import { createApp } from 'vue';
import ArcoVue from '@arco-design/web-vue';
import App from './App.vue';
import '@arco-design/web-vue/dist/arco.css';
import './style.css';

const permission = (Vue) => {
  return Vue.directive('permission', {
    mounted(el, binding) {},
    updated(el, binding) {},
  });
};

const app = createApp(App);
app.use(ArcoVue);
app.use(permission);
app.mount('#app');
<!-- App.vue -->
<template>
  <a-button type="primary" @click="handleClick">Open Drawer</a-button>
  <HRenderFuncComp />
</template>

<script setup lang="jsx">
import { ref, h } from 'vue';
import { Drawer } from '@arco-design/web-vue';
import Content from './Content.vue';

const handleClick = () => {
  Drawer.open({
    title: 'Title',
    content: () => h(Content), // error
  });
};

const HRenderFuncComp = () => {
  return h(Content); // success
};
</script>
<!-- Content.vue -->
<template>
  <!-- Failed to resolve directive: permission -->
  <div v-permission="['admin']">Content</div>
</template>

<script setup>
import { getCurrentInstance } from 'vue';

const { appContext } = getCurrentInstance();
console.log(appContext, '>>>> Content'); // appContext.app is null
</script>
Tracy-xu commented 3 weeks ago

I found the explanation in the official documentation.

当通过 import 方式使用时,组件没有办法获取当前的 Vue Context,如 i18n 或 route 等注入在 AppContext 上的内容无法在内部使用,需要在调用时手动传入 AppContext,或者为组件全局指定 AppContext