Vue.js组件缺少模板或渲染函数问题解决

Vue.js组件缺少模板或渲染函数问题解决

技术背景

在使用Vue 3和Vue Router构建单页面应用时,开发者可能会遇到 “Component is missing template or render function” 错误。这个错误通常表示Vue组件没有正确定义模板或渲染函数,导致Vue无法渲染该组件。

实现步骤

1. 问题示例

在Vue 3中,创建了如下的Home组件、FooBar组件,并将它们传递给vue-router

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<div id="app">
<ul>
<li><router-link to="/">Home</router-link></li>
<li><router-link to="/foo">Foo</router-link></li>
<li><router-link to="/bar">Bar</router-link></li>
</ul>
<home></home>
<router-view></router-view>
</div>

<script>
const { createRouter, createWebHistory, createWebHashHistory } = VueRouter
const { createApp } = Vue
const app = createApp({})

var Home = app.component('home', {
template: '<div>home</div>',
})

const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar },
],
})

app.use(router)
app.mount('#app')
</script>

上述代码中,Home组件导致了 “Component is missing template or render function” 错误。

2. 解决方法

方法一:正确获取组件定义

当使用app.component(...)提供定义对象时,它返回的是应用实例。要获取组件定义,应省略定义对象,仅提供名称:

1
2
3
4
5
6
7
8
9
app.component('home', { template: '<div>home</div>' })
const Home = app.component('home')

const router = createRouter({
routes: [
{ path: '/', component: Home },
//...
]
})

方法二:vue-cli vue 3 项目中添加渲染函数

main.js中,使用createApp函数设置应用时,需要包含渲染函数:

1
2
3
4
5
6
7
8
import { createApp, h } from 'vue'
import App from './App.vue'

const app = createApp({
render: () => h(App)
})

app.mount("#app")

也可以直接将App传递给createAppcreateApp(App)

方法三:确保组件模板不为空

如果创建了一个空组件,需要填充模板和简单的HTML文本代码。

方法四:升级vue-loader

vue-loader升级到版本16.8.1。

方法五:处理时序问题

添加v-if指令,在页面挂载时创建组件:

1
2
3
4
5
6
7
8
9
10
<review-info
v-if="initDone"
:review-info="reviewInfo"
/>

<script>
onMounted(() => {
initDone = true
})
</script>

方法六:正确导入组件

<script setup>中,确保正确导入组件,避免将响应式状态名与组件名冲突:

1
2
3
4
5
6
7
8
9
<template>
<confirmation-modal></confirmation-modal>
</template>

<script setup>
import ConfirmationModal from "./ConfirmationModal.vue";

const confirmationModal = ref({});
</script>

方法七:扩展组件时添加setup选项

在扩展Quasar组件时,在组件选项中添加setup: QInput.setup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { defineComponent } from 'vue'
import { QInput } from 'quasar'

const { props } = QInput

export default defineComponent({
props: {
...props,
outlined: {
type: Boolean,
default: true
},
dense: {
type: Boolean,
default: true
},
uppercase: {
type: Boolean,
default: false
}
},
watch: {
modelValue (v) {
this.uppercase && this.$emit('update:modelValue', v.toUpperCase())
}
},
setup: QInput.setup
})

方法八:创建单独的渲染组件

创建App.vue组件进行渲染:

1
2
3
4
5
6
<!-- ./views/App.vue -->
<template>
<main>
<router-view></router-view>
</main>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// router.js
import { createRouter, createWebHistory } from 'vue-router'
import ExampleComponent from './components/ExampleComponent.vue';

const routes = [
{
path: '/',
name: 'home',
meta: {
title: "Home",
},
component: ExampleComponent
}
];

export default createRouter({
history: createWebHistory(),
routes
})
1
2
3
4
5
6
7
8
9
// app.js (OR main.js)
require('./bootstrap');

import { createApp } from 'vue';
import router from './router'
import App from "./views/App.vue";

createApp(App)
.use(router).mount('#app');

方法九:处理类型导入问题

在使用verbatimModuleSyntax@typescript-eslint/consistent-type-imports规则时,要确保Vue能解析组件导入。可以在导入前添加注释// eslint-disable-next-line @typescript-eslint/consistent-type-imports,或者将组件作为参数传递给ref

1
2
import type SomeDialog from '@foo/SomeDialog.vue';
const someDialog = ref(SomeDialog);

最佳实践

  • 在创建组件时,确保正确定义模板或渲染函数。
  • 遵循Vue和Vue Router的官方文档进行组件和路由的配置。
  • 对于复杂的组件,使用单独的.vue文件进行管理,提高代码的可维护性。

常见问题

  • 组件未正确导入:确保在使用组件前正确导入,避免因导入错误导致组件无法渲染。
  • 组件定义对象返回问题:使用app.component时,注意其返回值是应用实例,需要正确获取组件定义。
  • 时序问题:在异步加载组件或处理响应式状态时,要注意组件创建的时机,避免在数据未准备好时渲染组件。

Vue.js组件缺少模板或渲染函数问题解决
https://119291.xyz/posts/2025-04-14.vuejs-component-missing-template-or-render-function-solve/
作者
ww
发布于
2025年4月14日
许可协议