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 代码
-
<!DOCTYPE html>
-
<html lang="en">
-
-
<head>
-
<meta charset="UTF-8">
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
-
<title>Document</title>
-
</head>
-
-
<body>
-
<div id="app"></div>
-
<!-- 引入打包之后的文件,先不用理解 -->
-
<script src="../dist/bundle.js"></script>
-
</body>
-
-
</html>
- id=app 的div 是将来 vue 实例的挂载点
- bundle.js 是打包生成的文件,先不同管它
src 目录下新建 Home.vue
-
<template>
-
<div class="home">
-
<h1>{{ msg }}
</h1>
-
</div>
-
</template>
-
<script>
-
export
default {
-
data:
function () {
-
return {
-
msg:
'Home'
-
}
-
},
-
methods: {
-
-
},
-
computed: {
-
-
},
-
watch: {
-
-
}
-
}
-
</script>
-
<style scoped>
-
h1 {
-
color: red;
-
}
-
</style>
当前目录结构如下
2.3 安装和配置webpack
安装 webpack
npm i webpack webpack-cli -D
根目录下新建 webpack.config.js,配置打包模式、入口和出口文件
-
const path =
require(
'path')
-
module.exports = {
-
mode:
'development',
-
entry: path.join(__dirname,
'src',
'main.js'),
// 打包的入口文件
-
output: {
-
path: path.join(__dirname,
'dist'),
-
filename:
'bundle.js'
-
}
-
}
package.json 中添加打包命令
2.4 编写打包入口文件
在 src/main.js 中编写代码
-
import Vue
from
'vue'
-
import Home
from
'./Home.vue'
-
-
let vm =
new Vue({
-
el:
'#app',
// 指定当前vue实例的挂载点,也就是将index.html 中的id=app 的dom作为挂载点
-
// 将 Home 组件中的模板和样式渲染到 index.html 页面中,具体来说,
-
// 就是用模板中的内容替换 index.html 中的 id=app 的元素,也会将 css 放到页面中
-
render:
h => h(Home)
-
})
运行打包命令
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
配置规则
-
module: {
-
rules: [
-
{ test: /\.vue$/, loader:
'vue-loader' },
-
{
-
test: /\.css$/,
-
use: [
-
'style-loader',
-
'css-loader'
-
]
-
}
-
]
-
},
重新运行
npm run dev
打包成功
运行 index.html
2.6 多组件如何切换
src 目录下新建 About.vue
-
<template>
-
<div class="about">
-
<h2>关于我们
</h2>
-
</div>
-
</template>
-
<script>
-
export
default {
-
-
}
-
</script>
-
<style scoped>
-
h2 {
-
color: orange;
-
}
-
</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
-
<template>
-
<div id="app">
-
<!-- 路由出口 -->
-
<!-- 路由匹配到的组件将渲染在这里 -->
-
<router-view>
</router-view>
-
</div>
-
</template>
-
<script>
-
export
default {
-
-
}
-
</script>
-
<style scoped>
-
</style>
其中 router-view 作为匹配到路由规则的组件的展示区域
修改打包入口文件
main,js 中引入 vue-router,并编写路由规则,并向 vue 实例注册 router 实例
还要注意,上面 render 函数中将组件名称改成了 App 组件
重新打包
通过修改地址栏中的 hash 值,可以看到对应的组件内容
2.8 公共组件如何处理
我们不能要求用户通过修改地址栏来切换不同的组件
必须要提供一个导航
而且这个导航,无论 Home 还是 About 组件都需要
所以不能分别在两个组件中定义一份,否则随着项目的扩大,维护成本会越来越高
解决方案:提取一个公共导航
src 目录下新建 NavBar.vue
-
<template>
-
<nav>
-
<ul>
-
<li>
<router-link to="/home">首页
</router-link>
</li>
-
<li>
<router-link to="/about">关于我们
</router-link>
</li>
-
</ul>
-
</nav>
-
</template>
-
<script>
-
export
default {
-
-
}
-
</script>
-
<style scoped>
-
ul {
-
list-style-type: none;
-
overflow: hidden;
-
}
-
li {
-
float: left;
-
padding:
10px;
-
}
-
a {
-
text-decoration: none;
-
}
-
</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 中代码如下
-
import Vue
from
'vue'
-
import VueRouter
from
'vue-router'
-
import Home
from
'../views/Home.vue'
-
import About
from
'../views/About.vue'
-
-
// 安装路由功能:
-
Vue.use(VueRouter)
-
/**
-
* 创建路由规则
-
* 当用户请求不同的hash值时,显示不同的组件(将不同的组件内容显示在 <router-view></router-view>)
-
*/
-
const routes = [
-
{ path:
'/home', component: Home },
-
{ path:
'/about', component: About }
-
]
-
-
// 创建 router 实例,然后传 `routes` 配置
-
const router =
new VueRouter({
-
routes
-
})
-
export
default router
main.js 中代码修改如下
-
import Vue
from
'vue'
-
import router
from
'./router'
// 可以省略 index.js
-
import App
from
'./App.vue'
-
-
let vm =
new Vue({
-
el:
'#app',
// 指定当前vue实例的挂载点,也就是将index.html 中的id=app 的dom作为挂载点
-
// 将 Home 组件中的模板和样式渲染到 index.html 页面中,具体来说,
-
// 就是用模板中的内容替换 index.html 中的 id=app 的元素,也会将 css 放到页面中
-
render:
h => h(App),
-
router
-
})
运行命令,重新打包,发现程序能够正常运行
npm run dev
3. 总结
经过一系列的步骤,我们手动创建的第一个单页面应用已经成功
仔细对比一下,发现与使用 vue 脚手架创建项目,目录结构基本一致了
转载:https://blog.csdn.net/mynewdays/article/details/114631386