网友回复
好的,这是一个非常实际且有用的需求,尤其是在不使用构建工具(如Vite、Webpack)的纯CDN环境中。
我们将通过Vue 3的 defineAsyncComponent 函数和一个自定义的加载器来实现这个功能。这种方法可以将您的应用模块化,保持主HTML文件的整洁,并按需加载组件。
核心思路
创建组件文件: 每个Vue组件将被写在一个独立的 .js 文件中。这个文件只包含组件的选项对象({ template: '...', data() {...} })。
全局注册: 为了让主应用能找到加载后的组件,每个组件文件在定义完自己后,会把自己注册到一个全局对象上(例如 window.VUE_COMPONENTS)。
自定义加载器: 我们会编写一个通用的JavaScript函数,该函数负责通过动态创建<script>标签来加载组件的URL。它会返回一个Promise,在脚本加载成功并找到注册的组件后,Promise会resolve。
defineAsyncComponent: 在主Vue应用中,我们使用 defineAsyncComponent 来包裹我们的自定义加载器。当Vue需要渲染这个组件时,它会自动调用我们的加载器,等待组件加载完成,然后渲染它。
项目文件结构
为了演示,你需要创建一个简单的项目结构,并使用一个本地服务器来运行它(因为浏览器安全策略限制直接从file://协议加载文件)。
/my-vue-app/ |-- index.html (主HTML文件) |-- /components/ | |-- Header.js (页头组件) | |-- UserProfile.js (用户资料组件) | |-- LoadingSpinner.js (加载中组件)
第1步:创建各个组件文件
/components/Header.js
这是一个简单的页头组件。
// /components/Header.js
// 确保全局组件对象存在
window.VUE_COMPONENTS = window.VUE_COMPONENTS || {};
// 定义组件并注册到全局对象
window.VUE_COMPONENTS['AppHeader'] = {
template: `
<header class="bg-white shadow-md">
<nav class="max-w-4xl mx-auto px-4 py-3 flex justify-between items-center">
<h1 class="text-xl font-bold text-indigo-600">动态组件加载系统</h1>
<p class="text-sm text-gray-500">Vue 3 CDN 版</p>
</nav>
</header>
`
}; /components/UserProfile.js
这是一个稍微复杂一点的组件,它接收props。
// /components/UserProfile.js
window.VUE_COMPONENTS = window.VUE_COMPONENTS || {};
window.VUE_COMPONENTS['UserProfile'] = {
props: ['userId'],
template: `
<div class="bg-white p-6 rounded-lg shadow-lg border-l-4 border-emerald-500">
<div v-if="loading" class="text-gray-500">正在加载用户 {{ userId }} 的信息...</div>
<div v-else>
<div class="flex items-center space-x-4">
<img :src="user.avatar" class="h-16 w-16 rounded-full">
<div>
<h2 class="text-2xl font-bold text-gray-800">{{ user.name }}</h2>
<p class="text-gray-600">{{ user.email }}</p>
</div>
</div>
</div>
</div>
`,
data() {
return {
loading: true,
user: null
}
},
created() {
// 模拟API请求
setTimeout(() => {
this.user = {
name: '爱丽丝',
email: 'alice@example.com',
avatar: `https://i.pravatar.cc/150?u=${this.userId}`
};
this.loading = false;
}, 1000);
}
};点击查看剩余70%


