请注意,本文编写于 2058 天前,最后修改于 1667 天前,其中某些信息可能已经过时。
如何在html(非单页vue项目)中直接引入vue文件组件
最近需要把一个自己封装好的 vue 日历组件引入到一个比较早的 vue 项目里,打开后发现这个项目是 非单页 的,即在 html 中引入 vue 的 lib 文件, 每个 html 文件对应的 js 文件都有一个独立的 Vue实例 。在网上找到了一种方法,使用 jquery 的 load 方法和 vue 的 extend 方法 ,稍微有点麻烦,最后把样式也提取到 html 的整体了才加载出来。后来又搜到一个插件 http-vue-loader,发现用起来挺方便,所以记录下
下面为插件使用的简单demo:
my-component.vue
<template>
<div class="hello">Hello {{who}}</div>
</template>
<script>
module.exports = {
data: function() {
return {
who: 'world'
}
}
}
</script>
<style>
.hello {
background-color: #ffe;
}
</style>
注意: vue 文件里使用的是 module.exports
index.html
使用 httpVueLoader 加载 vue 文件,并将其注册到 vue 的 component
<!doctype html>
<html lang="en">
<head>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/http-vue-loader"></script>
</head>
<body>
<div id="my-app">
<my-component></my-component>
</div>
<script type="text/javascript">
new Vue({
el: '#my-app',
components: {
'my-component': httpVueLoader('my-component.vue')
}
});
</script>
</body>
</html>
另外,这个插件还支持 sass ,更多具体用法可以查看作者的 github 地址
http-vue-loader
插件是如何实现的,有兴趣的话可以再研究下源码
1. 通过http请求加载文件
2. 将vue文件放在文档片段的容器对象,内存中
3. 处理vue文件的每一部分(template 页面文件,script js文件 和style样式 )
4. httpVueLoader('my-component.vue') 返回一个promise,成为异步组件
5. vue编译这个组件,并将其缓存
tips: 作者又开发了一个插件也支持加载 vue 文件哦,同时支持 vue2 和 vue3 ,大家有兴趣也可以研究下 vue3-sfc-loader
特性:
- Supports Vue 3 and Vue 2
- Only requires Vue runtime-only build
- Focuses on component compilation. Network, styles injection and cache are up to you
- Embedded ES6 modules support ( including import() )
- SFC Custom Blocks support
- JSX support
- Support custom CSS, HTML and Script language, see pug and stylus examples
- Properly reports template, style or script errors through the log callback
- You can build your own version and easily customize browsers you need to support
51 条评论
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
2025年10月新盘 做第一批吃螃蟹的人
独特的构思和新颖的观点,让这篇文章在众多作品中脱颖而出。
文章已具雏形,需进一步聚焦核心问题。
意象选取精妙,营造出空灵意境。
哈哈哈,写的太好了https://www.lawjida.com/
真好呢
看的我热血沸腾啊https://www.ea55.com/
博主真是太厉害了!!!
首先, 我先想说下, 整个方法都没有偶说你是怎么引入这个组件的, 我就没有看见你使用import或者require 以及script来引入这个组件, 那你是怎么使用的, 这是个问题? 而且这些demo不就是npm上面的demo吗, 我真想问下你们有真的实践过吗
可能这种场景你还没接触过,引入组件是使用`httpVueLoader`的
```
'my-component': httpVueLoader('my-component.vue')
```
最近的确一直忙,不好意思,没有回复大家,非常感谢热心开发者@wenxin667的耐心回复

vue文件里的
引入了less.js 试了发现不起作用,也不报错,页面加载不出来
vue 文件引用 less.js 干嘛? less.js 不应该在外部引入,附加到 httpVueLoader上用来解析 less 的吗?
你看看的我的 demo呢!http://wx-tpl.513902.xyz/admin
为什么 我都打不开你们的demo
OωO
我的原始demo都删了 httpVueLoader 其实很好用 很简单的
https://juzimi.online/admin/ 试试这个吧 仅供参考
style lang=“less” 这个样式
你查看我的demo 打开 控制台 看看加载的 .vue 文件啊 里面就有 style lang="less",而且生效了的
你的文章也帮到了我
html引入vue文件 vue文件不能使用import引入js文件么
我试了一下,可以使用啊!但是记得你import的js文件得是 esm 模块
调用子组件方法报错怎么回事呢
this.$refs.configFee[i].init();
init是子组件方法
用了settimeout
报错:Cannot read property 'init' of undefined
你没有具体示例 我也不好回答,不过我这个 demo 调用没问题
https://wx-tpl.513902.xyz/admin 你可以点击按钮试试
嗯嗯 上面那个是我自己的问题 找到原因了
现在报这个错 Failed to mount component: template or render function not defined.
不知道要怎么解决(╯‵□′)╯︵┴─┴
报错已经很清楚啦 模板(template)或者 渲染函数(render)没定义
你应该尽可能把demo暴露出来,才好找问题
我在本地demo上用
components: {
// 将组建加入组建库
// 'configfee': 'url: /static/configfee/views/fee/index.vue',
},
是可以运行vue组件的
迁移到项目里就不行了 (╯‵□′)╯︵┴─┴
我没有尝试过 url: 这种方式,我是将 httpVueloader 当作 import 函数用的
components: {
com: httpVueLoader('@/test.vue'),
}
另外demo能用 那就自己的问题了,我没有你的项目 分析不出你的问题
你这种 后面路径是怎么取得呢
(ノ°ο°)ノ httpVueloader 可以自定义请求方式的,参考 https://github.com/huanshiwushuang/wx-tpl/blob/admin/public/static/admin/init.js 319行
我能加你微信么ヾ(≧∇≦*)ゝ
搜 huanshiwushuang
http-vue-loader 确实不错,不过实测,less的 @import (reference) 会多次加载相同的文件,也是没办法的事。
最新的 vue3-sfc-loader 由于依赖的库 编译 less 是 使用的 syncimport ,但是貌似 less 中如果有 @import 是不支持 syncImport 的。
所以我最终还是使用了 http-vue-loader。
demo可见:http://wx-tpl.513902.xyz/admin
.vue文件里面有引用子组件,httpvueLoader好像不行
hi,我更新了下面这条评论的demo,本地可以运行成功,你可以先试下~
好的谢谢!
不客气,后面有问题的话可以继续交流
我验证了,是可以的
在组件中使用 this.$emit("test") 然后html使用httpvueloader调用组件 这个@test不触发,有解决办法么?
hi,我写了个简单的demo,可以实现事件监听,方便的话你可以贴下你的代码片段
const Foo = { template: 'foo' } const Bar = { template: 'bar' } const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ] const router = new VueRouter({ routes }) new Vue({ el: '#my-app', router, components: { 'App': httpVueLoader('App.vue'), }, template: '' });```
index.html
```
```
App.vue
module.exports = { name: "App", data() { return {}; }, components: { 'my-component': httpVueLoader('my-component.vue') }, created() {}, methods: { handleTest(event) { console.log('test', event) } } };
```
```
Hello {{who}}my-component.vue
module.exports = { data: function() { return { who: 'world' } }, components: { 'sub-component': httpVueLoader('sub-component.vue') }, created() { this.init() }, methods: { init() { setTimeout(_ => { this.$emit('test', {a: 1}) }, 2000) } } } .hello { background-color: #ffe; }
```
```
sub-component.vue
Hello {{who}} module.exports = { name: "sub-component", data: function() { return { who: 'sub component' } }, created() { }, methods: { } } .hello { background-color: #ffe; }```
我看了你的代码试过了, 如果子组件用emit('ontest') ,然后父组件@ontest 是可以的.但是如果用onTest ,就没法获取
嗯,这个就是 `vue` 内部事件传递名称的约定了
httpVueLoader如何配合vue路由router使用呢?如果您有解决办法,可否发我邮箱?十分感谢!!!
你好,评论时的邮箱填正确的地址是直接可以收到回复的
你好,直接httpVueLoader加载vue文件是可以的
const Foo = { template: 'foo' } const Bar = { template: 'bar' } const routes = [ { path: '/foo', component: httpVueLoader('my-component.vue') }, { path: '/bar', component: Bar } ] const router = new VueRouter({ routes }) new Vue({ el: '#my-app', router, components: { // 'my-component': httpVueLoader('my-component.vue') } });```
```
然后通过打开 `index.html#/foo` 访问就可以
Access to XMLHttpRequest at 'file:///C:/Users/64984/source/repos/WindowsFormsApp1/WindowsFormsApp1/bin/Debug/web/index.vue' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https. 本地文件跨域?
直接点击 `index.html `是不可以的(使用的是 `file:///` 协议),解决方法就是需要运行 `index.html` ,比如你用 `webstorm` 的话,可以右键 `run` 或者 `open` ,或者本地开一个简单的 `node` 服务,之后访问
感谢博主解答,我按博主截图示例已经成功运行了代码。
由此看出了我代码的问题,我把路由代码JS单独抽出到router.js(js目录下),再通过module方式导入index.html(根目录下),结果使用httpVueLoader加载单文件组件时,路径是根据router.js的相对路径找的,路径多了个.,应该根据index.html的相对路径去加载单文件组件。
为啥我评论发不了图片啊?
不客气~,目前使用的这个博客的框架允许了评论使用 `img标签`的方式添加图片(需要把图片传到类似图床- -。),也支持 `markdown语法`
```
```