You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在普通Web应用中使用Vue单文件组件并通过vue-loader编译实例化

在普通Web应用中使用Vue单文件组件并按需渲染指定组件

刚好做过类似的场景,我来一步步帮你搞定这个需求——在服务端生成的普通HTML页面里使用Vue单文件组件,而且只渲染指定的<ComponentA/>和<ComponentB/>,完全不改动页面里的其他原有内容。

1. 初始化项目并安装依赖

首先创建项目文件夹,初始化npm环境,然后安装必要的依赖包:

# 创建项目文件夹并进入
mkdir vue-sfc-in-legacy-html && cd vue-sfc-in-legacy-html

# 初始化npm
npm init -y

# 安装核心依赖和编译工具
npm install vue vue-loader vue-template-compiler webpack webpack-cli css-loader vue-style-loader --save-dev

2. 配置Webpack(核心编译规则)

创建webpack.config.js文件,配置vue-loader来编译单文件组件:

const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
  // 入口文件
  entry: './src/main.js',
  // 打包输出配置
  output: {
    filename: 'bundle.js',
    path: __dirname + '/dist'
  },
  module: {
    rules: [
      // 处理.vue单文件组件
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      // 处理组件内的CSS
      {
        test: /\.css$/,
        use: ['vue-style-loader', 'css-loader']
      }
    ]
  },
  plugins: [
    // 必须引入这个插件,确保vue-loader正常工作
    new VueLoaderPlugin()
  ]
}

3. 编写单文件组件

在src/components目录下创建三个组件文件:

App.vue(仅按需求创建,无需挂载)

因为我们不需要替换<App>容器里的所有内容,这个组件可以留空或作为占位:

<template>
  <div></div>
</template>

<script>
export default {
  name: 'App'
}
</script>

ComponentA.vue

<template>
  <div class="component-a">
    我是组件A的内容 {{ message }}
  </div>
</template>

<script>
export default {
  name: 'ComponentA',
  data() {
    return {
      message: '(来自Vue单文件组件)'
    }
  }
}
</script>

<style scoped>
.component-a {
  color: #2c3e50;
  padding: 10px;
  border: 1px solid #eee;
}
</style>

ComponentB.vue

<template>
  <div class="component-b">
    我是组件B的内容,计数:{{ count }}
  </div>
</template>

<script>
export default {
  name: 'ComponentB',
  data() {
    return {
      count: 0
    }
  },
  mounted() {
    // 模拟动态数据更新
    setInterval(() => this.count++, 1000)
  }
}
</script>

<style scoped>
.component-b {
  color: #e74c3c;
  padding: 10px;
  border: 1px solid #fcc;
  margin-top: 10px;
}
</style>

4. 编写入口文件(关键:按需挂载组件)

创建src/main.js,这里的核心逻辑是只挂载页面中指定的组件标签,不影响其他内容:

import Vue from 'vue'
import ComponentA from './components/ComponentA.vue'
import ComponentB from './components/ComponentB.vue'

// 等待DOM加载完成后再操作
document.addEventListener('DOMContentLoaded', () => {
  // 找到页面中的<ComponentA>标签并挂载组件
  const componentAEl = document.querySelector('ComponentA')
  if (componentAEl) {
    new Vue({
      el: componentAEl,
      render: h => h(ComponentA)
    })
  }

  // 找到页面中的<ComponentB>标签并挂载组件
  const componentBEl = document.querySelector('ComponentB')
  if (componentBEl) {
    new Vue({
      el: componentBEl,
      render: h => h(ComponentB)
    })
  }
})

这里的逻辑很简单:找到页面中已存在的<ComponentA>和<ComponentB>元素,分别挂载对应的Vue组件。Vue会自动把这些标签替换成组件渲染后的内容,但不会改动<App>容器里的其他服务端生成内容。

5. 编译打包并在服务端HTML中引入

在package.json的scripts里添加打包命令:

"scripts": {
  "build": "webpack --mode production"
}

运行打包命令:

npm run build

打包完成后,dist目录会生成bundle.js。接下来在服务端生成的HTML页面中引入这个脚本(建议放在body末尾,确保DOM已加载):

<html>
<body>
  <App>
    <!-- 以下是服务端生成的内容,不会被Vue修改 -->
    <h1>服务端渲染的页面标题</h1>
    <p>这是服务端生成的普通文本内容,保持原样</p>
    
    <!-- 这个标签会被Vue替换成ComponentA的内容 -->
    <ComponentA></ComponentA>
    
    <p>中间的其他服务端内容也不会被改动</p>
    
    <!-- 这个标签会被Vue替换成ComponentB的内容 -->
    <ComponentB></ComponentB>
  </App>

  <!-- 引入打包后的Vue脚本 -->
  <script src="/dist/bundle.js"></script>
</body>
</html>

额外技巧:接收服务端传递的参数

如果需要给组件传递服务端生成的参数,可以通过data-*属性实现:

<ComponentA data-title="来自服务端的标题"></ComponentA>

然后修改ComponentA的props并在挂载时传递:

<!-- ComponentA.vue的script部分 -->
<script>
export default {
  name: 'ComponentA',
  props: {
    title: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      message: '(来自Vue单文件组件)'
    }
  }
}
</script>
// main.js中挂载ComponentA的部分
new Vue({
  el: componentAEl,
  render: h => h(ComponentA, {
    props: {
      title: componentAEl.dataset.title
    }
  })
})

内容的提问来源于stack exchange,提问作者nourdine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:35:46