飞道的博客

自己动手 webpack 打包 vue 单文件组件

386人阅读  评论(0)

1. 为什么要了解这些

vue 的脚手架集成了 webpack,并进行了大量的默认配置

我们只需要按照框架的要求编写代码,打包就好了

慢慢的我们就成了傻瓜,不知道这其中到底发生了什么,一旦遇到问题,不知道该如何思考,因为你可能都不清楚它的运作原理

更何况,看尤大的思路,将来很可能使用脚手架创建项目时,打包工具不再是默认的,而是让你 webpack 和 vite 二选一

所以,我们就更需要对打包过程有一个大概的了解

下面我们就手动实现这一点

2. 动手实践

SPA 和组件化密不可分,组件化让SPA成为可能,SPA促使组件化编程的落地

vue 的单文件组件就是具体的体现

2.1 搭建目录结构

创建项目文件夹 webpack-demo

运行如下命令进行初始化

npm init -y

根目录下新建 src 目录

src 目录下新建 index.html,main.js

index.html 代码


  
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <div id="app"></div>
  11. <!-- 引入打包之后的文件,先不用理解 -->
  12. <script src="../dist/bundle.js"></script>
  13. </body>
  14. </html>
  • id=app 的div 是将来 vue 实例的挂载点
  • bundle.js 是打包生成的文件,先不同管它

src 目录下新建 Home.vue


  
  1. <template>
  2. <div class="home">
  3. <h1>{{ msg }} </h1>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. data: function () {
  9. return {
  10. msg: 'Home'
  11. }
  12. },
  13. methods: {
  14. },
  15. computed: {
  16. },
  17. watch: {
  18. }
  19. }
  20. </script>
  21. <style scoped>
  22. h1 {
  23. color: red;
  24. }
  25. </style>

当前目录结构如下

 

2.3 安装和配置webpack

安装 webpack

npm i webpack webpack-cli -D

根目录下新建 webpack.config.js,配置打包模式、入口和出口文件


  
  1. const path = require( 'path')
  2. module.exports = {
  3. mode: 'development',
  4. entry: path.join(__dirname, 'src', 'main.js'), // 打包的入口文件
  5. output: {
  6. path: path.join(__dirname, 'dist'),
  7. filename: 'bundle.js'
  8. }
  9. }

package.json 中添加打包命令

2.4 编写打包入口文件

在 src/main.js 中编写代码


  
  1. import Vue from 'vue'
  2. import Home from './Home.vue'
  3. let vm = new Vue({
  4. el: '#app', // 指定当前vue实例的挂载点,也就是将index.html 中的id=app 的dom作为挂载点
  5. // 将 Home 组件中的模板和样式渲染到 index.html 页面中,具体来说,
  6. // 就是用模板中的内容替换 index.html 中的 id=app 的元素,也会将 css 放到页面中
  7. render: h => h(Home)
  8. })

运行打包命令

npm run dev

报错

错误解决见下一节

2.5 安装相关加载器(loader)

上面错误原因在于 webpack 默认只能打包 js 文件,对于 .vue 文件不认识

所以需要安装能够处理 vue 文件的 loader

这个 loader 不能在 webpack 文档中找,因为 webpack 与 vue 本身是没有关系的

webpack 只是一个打包工具,默认可以处理 js 文件,并且提供了一些通用的 laoder,比如

  • css-loader 处理 css 文件的打包工作
  • url-loader 处理图片字体等静态资源文件的打包工作

所以,vue 官方提供了能够处理 vue 文件的加载器

https://vue-loader.vuejs.org/zh/

安装

npm install -D vue-loader vue-template-compiler

在webpack 中配置

 

 

错误信息

上面错误是因为组件中有 css 代码,需要对应的 loader

安装 loader

npm i style-loader css-loader -D

配置规则


  
  1. module: {
  2. rules: [
  3. { test: /\.vue$/, loader: 'vue-loader' },
  4. {
  5. test: /\.css$/,
  6. use: [
  7. 'style-loader',
  8. 'css-loader'
  9. ]
  10. }
  11. ]
  12. },

重新运行 

npm run dev

打包成功

运行 index.html

2.6 多组件如何切换

src 目录下新建 About.vue


  
  1. <template>
  2. <div class="about">
  3. <h2>关于我们 </h2>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. }
  9. </script>
  10. <style scoped>
  11. h2 {
  12. color: orange;
  13. }
  14. </style>

希望运行 index.html 的时候展示 About 组件的内容,怎么办?

可以修改 main.js

重新打包 

npm run dev

index.html

 

虽然实现了,但很显然,这种实现方案是不现实的

2.7 使用路由实现组件切换

其实,组件切换的逻辑应该是这样的

  • 首先,我们是一个 SPA 应用,只有一个 index.html 作为应用入口
  • 传统开发模式中的多页面,此时以多组件的方式实现。不严谨的说,就是传统模式下的一个页面对应这里的一个组件,当然我们这里组件的粒度更精细
  • 通过地址栏中的 hash 值的变化,寻找对应的组件在页面中显示

我们都知道,页面实际运行中,其实就是将 vue 实例中 render 属性指定的组件内容替换掉 index.html 中的 id=app 的元素

我们新建一个根组件,将根组件的内容显示到 index.html 中的 id=app 的元素上

当组件发生切换时,改变根组件中的内容,也就是将其他组件的内容显示到跟组件上,而根组件又渲染到 index.html 中,所以最终 html 页面也会变化

引入 vue 的官方路由 vue-router,来实现这一点

 

 

安装vue-router

npm install vue-router

 

创建根组件

src 目录下创建 App.vue


  
  1. <template>
  2. <div id="app">
  3. <!-- 路由出口 -->
  4. <!-- 路由匹配到的组件将渲染在这里 -->
  5. <router-view> </router-view>
  6. </div>
  7. </template>
  8. <script>
  9. export default {
  10. }
  11. </script>
  12. <style scoped>
  13. </style>

其中 router-view 作为匹配到路由规则的组件的展示区域

修改打包入口文件

main,js 中引入 vue-router,并编写路由规则,并向 vue 实例注册 router 实例

还要注意,上面 render 函数中将组件名称改成了 App 组件

重新打包

通过修改地址栏中的 hash 值,可以看到对应的组件内容

 

 

2.8 公共组件如何处理

我们不能要求用户通过修改地址栏来切换不同的组件

必须要提供一个导航

而且这个导航,无论 Home 还是 About 组件都需要

所以不能分别在两个组件中定义一份,否则随着项目的扩大,维护成本会越来越高

解决方案:提取一个公共导航

src 目录下新建 NavBar.vue


  
  1. <template>
  2. <nav>
  3. <ul>
  4. <li> <router-link to="/home">首页 </router-link> </li>
  5. <li> <router-link to="/about">关于我们 </router-link> </li>
  6. </ul>
  7. </nav>
  8. </template>
  9. <script>
  10. export default {
  11. }
  12. </script>
  13. <style scoped>
  14. ul {
  15. list-style-type: none;
  16. overflow: hidden;
  17. }
  18. li {
  19. float: left;
  20. padding: 10px;
  21. }
  22. a {
  23. text-decoration: none;
  24. }
  25. </style>

修改 App.vue,引入上面的组件,并在 router-view 上面使用

重新打包,然后运行 index.html

 

 

现在我们可以通过点击连接切换组件了

至此,一个简单的 SPA 应用就完成了

2.9 项目目录调整

随着项目变大,组件会越来越多,全部都放在 src 目录下,不便于管理

另外,随着组件的增多,路由规则也会越来越多,我们当前将所有路由规则写在 入口文件 main.js 中,会让文件越来越臃肿,另外入口文件的作用应该是告诉webpack 哪些文件应该打包,而不应该放路由处理这种逻辑代码,所以应该也提取出来

具体操作

  • 新建 views 目录,存放页面级组件,如 Home.vue,About.vue
  • 新建 components 目录,存放局部组件,如 NavBar.vue
  • 新建 router 目录,其下新建 index.js,将路由处理相关代码放在这里

router/index.js 中代码如下


  
  1. import Vue from 'vue'
  2. import VueRouter from 'vue-router'
  3. import Home from '../views/Home.vue'
  4. import About from '../views/About.vue'
  5. // 安装路由功能:
  6. Vue.use(VueRouter)
  7. /**
  8. * 创建路由规则
  9. * 当用户请求不同的hash值时,显示不同的组件(将不同的组件内容显示在 <router-view></router-view>)
  10. */
  11. const routes = [
  12. { path: '/home', component: Home },
  13. { path: '/about', component: About }
  14. ]
  15. // 创建 router 实例,然后传 `routes` 配置
  16. const router = new VueRouter({
  17. routes
  18. })
  19. export default router

 

main.js 中代码修改如下


  
  1. import Vue from 'vue'
  2. import router from './router' // 可以省略 index.js
  3. import App from './App.vue'
  4. let vm = new Vue({
  5. el: '#app', // 指定当前vue实例的挂载点,也就是将index.html 中的id=app 的dom作为挂载点
  6. // 将 Home 组件中的模板和样式渲染到 index.html 页面中,具体来说,
  7. // 就是用模板中的内容替换 index.html 中的 id=app 的元素,也会将 css 放到页面中
  8. render: h => h(App),
  9. router
  10. })

运行命令,重新打包,发现程序能够正常运行

npm run dev

3. 总结

经过一系列的步骤,我们手动创建的第一个单页面应用已经成功

仔细对比一下,发现与使用 vue 脚手架创建项目,目录结构基本一致了


转载:https://blog.csdn.net/mynewdays/article/details/114631386
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场