I was writing a plugin when I came across the problem...
This is my component:
<template>
<el-button type="danger" round @click="gotoRoot" class="clear-button">
Go to root
</el-button>
</template>
<script lang="ts" setup>
import { ElButton } from "element-plus";
import { useRouter, type Router } from 'vue-router';
const router = useRouter()
const gotoRoot = function (): void {
// eslint-disable-next-line vue/no-mutating-props
router.push({path: '/'})
}
</script>
<style scoped>
</style>
And this is my plugin index.ts:
import { h, render, type App, type VNode } from "vue"
import ToolList from "./tool-list.vue"
import GoToRootButton from "./go-to-root-button.vue"
export default {
install(app: App){
const children: VNode[] = []
const gotoRootVm = h(GoToRootButton)
// I try to give the vnode a appContext, but there is still the problem
gotoRootVm.appContext = app._context
// output: a non-undefined object
console.log(gotoRootVm.appContext);
children.push(gotoRootVm)
const vm = h(ToolList, children)
const container = document.createElement('div')
render(vm, container)
// add to DOM tree
document.body.appendChild(container.firstChild!)
}
}
last, this is my main.ts:
import { createApp } from 'vue'
import pinia from "./stores/index"
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import '@/styles/index.scss'
import VueCookies from 'vue-cookies'
import App from './App.vue'
import router from './router'
import devTools from './tools/devTools'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
app.use(pinia)
// relevant line
app.use(router)
app.use(ElementPlus)
app.use(VueCookies)
// relevant line
app.use(devTools)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.mount('#app')
How can I solve this? By the way, what is the mechanism behind the phenomenon?
I've tried to pass a app_context to the vnode of the component I want to render I think it should work, but it doesn't