vue 的脚手架集成了 webpack,并进行了大量的默认配置
我们只需要按照框架的要求编写代码,打包就好了
慢慢的我们就成了傻瓜,不知道这其中到底发生了什么,一旦遇到问题,不知道该如何思考,因为你可能都不清楚它的运作原理
更何况,看尤大的思路,将来很可能使用脚手架创建项目时,打包工具不再是默认的,而是让你 webpack 和 vite 二选一
所以,我们就更需要对打包过程有一个大概的了解
下面我们就手动实现这一点
SPA 和组件化密不可分,组件化让SPA成为可能,SPA促使组件化编程的落地
vue 的单文件组件就是具体的体现
创建项目文件夹 webpack-demo
运行如下命令进行初始化
npm init -y
根目录下新建 src 目录
src 目录下新建 index.html,main.js
index.html 代码
Document
src 目录下新建 Home.vue
{
{ msg }}
当前目录结构如下
安装 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 中添加打包命令
在 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
报错
错误解决见下一节
上面错误原因在于 webpack 默认只能打包 js 文件,对于 .vue 文件不认识
所以需要安装能够处理 vue 文件的 loader
这个 loader 不能在 webpack 文档中找,因为 webpack 与 vue 本身是没有关系的
webpack 只是一个打包工具,默认可以处理 js 文件,并且提供了一些通用的 laoder,比如
所以,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
src 目录下新建 About.vue
关于我们
希望运行 index.html 的时候展示 About 组件的内容,怎么办?
可以修改 main.js
重新打包
npm run dev
index.html
虽然实现了,但很显然,这种实现方案是不现实的
其实,组件切换的逻辑应该是这样的
我们都知道,页面实际运行中,其实就是将 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
其中 router-view 作为匹配到路由规则的组件的展示区域
修改打包入口文件
main,js 中引入 vue-router,并编写路由规则,并向 vue 实例注册 router 实例
还要注意,上面 render 函数中将组件名称改成了 App 组件
重新打包
通过修改地址栏中的 hash 值,可以看到对应的组件内容
我们不能要求用户通过修改地址栏来切换不同的组件
必须要提供一个导航
而且这个导航,无论 Home 还是 About 组件都需要
所以不能分别在两个组件中定义一份,否则随着项目的扩大,维护成本会越来越高
解决方案:提取一个公共导航
src 目录下新建 NavBar.vue
修改 App.vue,引入上面的组件,并在 router-view 上面使用
重新打包,然后运行 index.html
现在我们可以通过点击连接切换组件了
至此,一个简单的 SPA 应用就完成了
随着项目变大,组件会越来越多,全部都放在 src 目录下,不便于管理
另外,随着组件的增多,路由规则也会越来越多,我们当前将所有路由规则写在 入口文件 main.js 中,会让文件越来越臃肿,另外入口文件的作用应该是告诉webpack 哪些文件应该打包,而不应该放路由处理这种逻辑代码,所以应该也提取出来
具体操作
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值时,显示不同的组件(将不同的组件内容显示在 )
*/
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
经过一系列的步骤,我们手动创建的第一个单页面应用已经成功
仔细对比一下,发现与使用 vue 脚手架创建项目,目录结构基本一致了