之前分享过在使用Vue-cli的时候怎么构建多页应用,如今随着Vite这样一个轻量级易用的构建工具的出现,越来越多的人也去尝试Vite了。在Vue-cli迁移到Vite的过程中,多多少少会有一些问题,多页应用的配置就是其中之一。
1,认识Vite项目中页面加载和根组件挂载过程
事实上,Vite项目中根组件加载过程和Vue-cli是差不多的,只不过目录结构有点小变化。
上述目录和文件:
- 1.vscode项目配置
- 2.nodejs项目依赖库文件,平时需要加入
.gitignore
- 3.公共文件夹
- 4.源码文件夹
- 4.1.存放静态资源例如图片、音频等等
- 4.2.存放Vue组件
- 4.3.Vue根组件,这个大家应该很熟悉
- 4.4. 入口文件,大家也耳熟能详了
- 5. Git忽略文件
- 6. 主页面模板文件
- 7. 依赖配置文件,里面记录了依赖库
- 8.
README
文件 - 9. Vite项目的配置文件,和Vue-cli中的
vue.config.js
是一个作用
可见,对比起Vue-cli项目,最大的不同就是原先在public
文件夹中的index.html
,现在是在项目根目录了!
(1) Vite项目中路径和网站访问路径的对应关系
首先我们要引入一个概念:根路径。在Vite工程中,默认情况下根路径就是我们的项目目录,即src
文件夹所在的那个目录(注意是所在),在Vite中用/
表示根路径。因此在这里/
开头的路径就是绝对路径。
通过在配置文件中指定root
配置项的值可以自定义根路径的位置,不过平时可以不用修改。
那么在Vite中,我们的根组件又是如何被加载的呢?
在Vite工程中,当我们访问网站根路径的时候,事实上会访问到我们项目根路径上的index.html
文件。
没错,在Vite工程中,预览网页时访问网站的网址路径和我们工程路径是对应的。
我们的Vite工程启动后,访问http://localhost:3000/
,也就是访问我们的网址根路径的时候,Vite就会去项目中寻找/index.html
并返回,也就是说我们会访问到我们项目中的/index.html
上。
同样地:
- 访问
http://localhost:3000/test/
,Vite就会去项目目录中寻找/test/index.html
并返回,即我们访问到的是/test/index.html
文件 - 访问
http://localhost:3000/test/page/
,Vite就会去项目目录中寻找/test/page/index.html
并返回,即我们访问到的是/test/page/index.html
文件
可见,我们访问网页路径的时候,和项目路径是一一对应的,这和大多数静态服务器一样。
同样地,在Vite中还有base
配置项,这个配置项其实就和Vue-cli的publicPath
是一个意思,就是开发或生产环境服务的公共基础路径,其默认值是/
。
通俗地讲,这个配置项表示我们外部访问的根路径是什么,也就是说我们在外部通过网址访问时访问什么路径,Vite就会去根路径寻找index.html
。
其默认值是/
,也就是说正如上面讲的一样,我们访问网站根路径的时候,Vite就会让我们访问到项目根路径的index.html
上面。
以此类推就很简单了,如果我们配置base
值为/path
,那当我们访问http://localhost:3000/path/
的时候,Vite才会去项目根路径找到index.html
并返回。
当我们配置base
值为/path
时,同样地:
- 访问
http://localhost:3000/path/test/
,Vite就会去项目目录中寻找/test/index.html
并返回,即我们访问到的是/test/index.html
文件 - 访问
http://localhost:3000/path/test/page/
,Vite就会去项目目录中寻找/test/page/index.html
并返回,即我们访问到的是/test/page/index.html
文件
(2) 根组件挂载
根组件的挂载和Vue-cli项目几乎一模一样,我们还是来看一下入口文件/src/main.js
文件:
import { createApp } from'vue'; // 引入根组件importAppfrom'./App.vue'; // 创建根组件实例并挂载至html文件中createApp(App).mount('#app');
重点仍然在于createApp
这个函数,先是引入组件模板,然后通过createApp
函数,会返回一个提供应用上下文的应用实例,可以链式调用。
通俗地讲,先开始只是引入了Vue模板,但是仅仅引入模板,是不能将它和我们的html
联系起来的。
通过createApp
,我们才创建了一个可以供上下文使用的实例,也就是说只有这个函数,才能创建一个可以显示渲染的实例。
同样地,
createApp
函数后面也可以链式调用use
函数引入其它插件。
最后通过mount
函数,把这个实例内容,即App.vue
文件的内容挂载至网页某个节点上,这样才能显示。
那为什么要挂载到id
为app
的节点上呢?可以打开/index.html
文件看看:
可见当我们访问网页根路径时,我们就访问了index.html
这个网页,这时main.js
被执行,其中createApp
函数执行,并将App.vue
的内容挂载(填充)至这个html
的id
为app
的div
中。
这里App.vue
的内容如下:
访问网页,查看f12看看渲染结果:
可见通过main.js
,把App.vue
中的内容挂载到了html
文件中id
为app
的节点下。
相信大家现在知道了Vite项目中,访问路径与项目路径的对应关系,以及一个页面的加载过程,知道了这些,配置出一个多页应用也是很简单的。
2,多页应用配置
同样地,多页应用中每一个页面也需要有它自己的html
文件和入口js
文件。
假设我这里要配置两个子页面,我们可以先在项目根目录下创建两个文件夹存放两个子页面的html
文件和入口js
文件。我这里创建两个文件夹pageone
和pagetwo
,并将/index.html
和/src/main.js
各复制一份到这两个文件夹:
每个子页面的入口js
文件可以改名,但是html
就不要改名了!保持index.html
即可,否则访问时会导致找不到文件。
可见我这里子页面1对应的入口文件是/pageone/pageone.js
,对应的html
是/pageone/index.html
;子页面2对应的入口文件是/pagetwo/pagetwo.js
,对应的html
是/pagetwo/index.html
。
然后我们在src
文件夹中新建page
文件夹专门用于存放所有子页面的vue
根组件及其子组件文件,在page
中给每个页面创建个文件夹,并在文件夹中创建每个页面的根组件文件,如下:
可见每个子页面的组件都放在/src/page
中的一个文件夹中,便于管理。
上述子页面1和子页面2的根组件分别是PageOne.vue
和PageTwo.vue
,两个文件内容如下:
不过这里为什么要把vue
文件和入口文件与html
文件分开放呢?放一起不更方便吗?
这里我觉得:
- Vite项目中
src
目录基本上存放的绝大多数都是vue
组件文件,两者分开会使得结构清晰 - 若把
html
和入口文件也放在src
中,访问子页面的时候路径会很长,打包后也很难对应
当然,这里也只是我的看法,大家可以根据自己的习惯进行组织,多页应用的配置的目录并非是死的,毕竟知道了页面加载的方式,我们也很容易配置多页应用了!
好了,现在修改每个页面的html
文件和入口文件,这里先修改子页面1的html
文件,打开/pageone/index.html
文件,找到script
标签,把里面的src
属性值改成子页面1对应的入口文件路径,也就是说让子页面1的html
文件链接上其入口文件:
注意这里src
必须使用绝对路径!也就是/
开头的路径,使用相对路径会导致无法加载。
然后修改子页面1的入口文件,打开/pageone/pageone.js
文件,import
组件的部分改成引入子页面1对应的Vue组件文件的路径:
好了,到此页面1就配置完成了!页面2也是同理。
然后就可以访问我们的多页应用了!
启动项目,访问http://localhost:3000/
,如下:
访问http://localhost:3000/pageone/
,如下:
访问http://localhost:3000/pagetwo/
,如下:
注意在这里预览页面时,网址路径末尾必须以/
结尾!否则也会导致找不到页面。
可见配置多页应用还是很简单的,如果仅仅是开发预览时配置多页应用,连配置文件都不用改。
3,多页应用打包
上述配置好多页应用之后,如果你这时执行打包构建命令,你会发现子页面文件并没有被包含到打包的结果中,因此我们还需要在配置文件中,配置一下打包解析,把每个子页面的html
文件添加到打包解析中。
打开Vite配置文件vite.config.js
,在其中进行打包解析配置。
先在配置文件中import
一下resolve
函数:
import { resolve } from'path';
然后加入以下配置内容:
build: { rollupOptions: { input: { // 配置所有页面路径,使得所有页面都会被打包main: resolve(__dirname, 'index.html'), pageone: resolve(__dirname, 'pageone/index.html'), pagetwo: resolve(__dirname, 'pagetwo/index.html') } } }
最终配置文件如下:
可见在上述的input
中,配置一下每个页面的html
文件解析路径即可!其中input
对象里面,属性名可以自定义,属性值则是要解析的页面路径,通过resolve
函数。
resolve
函数的参数是填入多个路径,最终这个函数会把路径拼接起来。__dirname
表示的是vite.config.js
这个文件所在的路径。
在这里vite.config.js
位于/
,因此__dirname
的值就是/
,对于上述resolve(__dirname, 'pagetwo/index.html')
,最终拼接出来的路径就是/pagetwo/index.html
,这样就成功地找到了子页面2的html
文件,打包的时候就会被包含。
需要注意的是,__dirname
表示的是vite.config.js
这个文件本身所在的路径而不是根路径! 因此即使你修改了配置项root
为别的值,即你修改了根路径位置,这个__dirname
的值仍然是vite.config.js
这个文件所在的路径,这里需要注意一下。
再次执行打包命令npm run build
,发现所有页面都被包含了:
同样地,如果配置了多页应用,就不能够把base
配置为相对路径./
了!否则会出现问题。
4,配置打包后页面文件到后端服务器
dist
文件夹中的内容就可以放到后端服务器中去了!这里以Spring Boot为例,我们把dist
文件夹中所有内容放到Spring Boot工程的src/main/resources/static
目录下,即Spring Boot项目默认的静态资源目录下:
Spring Boot默认端口是8080
,启动项目,访问http://127.0.0.1:8080/index.html
,如下:
访问http://127.0.0.1:8080/pageone/index.html
,如下:
访问http://127.0.0.1:8080/pagetwo/index.html
,如下:
可见打包后配置到后端访问路径是和Vite开发预览时的是不一样的,这里注意即可,后端配置打包后的静态页面,访问路径就必须指定到具体的html
文件上。
同样地,如果觉得访问路径太长或者不好看,也可以在Spring Boot中自定义Controller类进行自定义路由,这都是Spring Boot方面的内容了!这里就不再过多赘述,相信后端同学都能够信手拈来。
参考: