接上一篇:Laravel5与前端(一)快速上手
单页 vs 多页
熟悉前端的同学也许听过 SPA
(single page web application,单页Web应用),它究竟是个什么东西呢?
前段路由
app.js
(入口) 文件只有一个,页面间的路由放在前端完成。而多页应用需要每个页面对应一个app.js,路由是放在后端来实现的。
更少的HTTP请求
不用像多页应用那样,每一个页面都需要HTTP请求,单页应用由于后端路由只有一个,所以HTTP请求较少。而多页应用的页面和页面内的资源文件每次都需要重新请求,这样对HTTP压力较大(缓存压力也大)。
更快的响应
在SPA中进行页面切换时,没有白屏期,用户使用更加流畅。
更注重分离
后端只需提供数据即可,无需计算页面展示逻辑和合成页面,这样以来后端更加专注数据处理,前端更加注重交互处理。
vue-router
vue-router可以轻松的实现前端路由功能,它是配合vue一起使用的。
安装
使用npm安装:
npm install vue-router -S
在 app.js
中引入:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
开始使用
html:
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
app.js:
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
const router = new VueRouter({
routes // (缩写)相当于 routes: routes
})
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
router
}).$mount('#app')
上述代码定义了2个前端路由页面,各行代码的作用如下:
1-2行:定义了两个页面 Foo
和 Bar
4-7行:配置这俩页面到路由 /foo
和 /bar
上
9-11行:实例化VueRouter对象
15-17行:实例化Vue对象并挂载到 #app
元素上,同时注入router
在线演示:https://codepen.io/JerryCheese/pen/xWrebL
关于更多vue-router使用方法,参见官方教程:https://router.vuejs.org/zh-cn/
模块化 vs 组件化
多页应用中的 页
实际上指的就是一个个 .html
文件,在单页应用中不同的内容称为 模块
对应一个一个 .vue
文件。例如下面两个模块,表示两个不同的管理页面:
modules/User.vue 文件:
<template>
<div>
<h3>用户管理</h3>
</div>
</template>
modules/Course.vue 文件:
<template>
<div>
<h3>课程管理</h3>
</div>
</template>
app.js 文件:
import Vue from 'vue'
import VueRouter from 'vue-router'
import UserPage from './modules/User'
import CoursePage from './modules/Course'
Vue.use(VueRouter)
const routes = [
{ path: '/user', component: UserPage },
{ path: '/course', component: CoursePage }
]
const router = new VueRouter({
routes // (缩写)相当于 routes: routes
})
const app = new Vue({
el: '#app',
router
});
html:
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/user">用户管理</router-link>
<router-link to="/course">课程管理</router-link>
</p>
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>
这样一来,每个模块(或者说页面)对应到了一个 .vue
文件。从代码本质上来说,他们都是vue组件,只是为了便于区分而取了名字而已。
懒加载
现在我们知道了,单页应用通过js调用来显示不同的页面内容,也叫做模块。
现在的问题是,当页面数量很多时,它们会被打包进一个app.js文件中,这会导致这个文件非常大,那么在用户首次访问时会占用大量HTTP资源。
用户也许只看其中的一两个模块而已,有没有方法可以让模块按需加载而不是一次性都加载呢?答案就是懒加载。
所幸vue-router支持懒加载功能,所以我们不必自己基于Webpack的代码分割功能来自己实现了。
懒加载一个模块
我们看这段代码:
...
import UserPage from './modules/User'
import CoursePage from './modules/Course'
...
const routes = [
{ path: '/user', component: UserPage },
{ path: '/course', component: CoursePage }
]
...
它引入了两个模块,并且直接配置到了routes的component中,如果要懒加载,怎么做呢?改成下面这样就行:
...
//import UserPage from './modules/User'
//import CoursePage from './modules/Course'
const UserPage = () => import('./modules/User')
const CoursePage = () => import('./modules/Course')
...
const routes = [
{ path: '/user', component: UserPage },
{ path: '/course', component: CoursePage }
]
...
如果报错的话,那是因为babel不能正确解析异步语法 () => import
,需要安装syntax-dynamic-import:
npm install --save-dev babel-plugin-syntax-dynamic-import
并且在webpack.mix.js同目录处新建文件 .babelrc
,输入以下配置信息:
{
"plugins": ["syntax-dynamic-import"]
}
完成之后,打开页面,访问路由,发现:
这俩文件其实就是前边定义的俩模块对应的js,在访问到它们时,它们的js才会被加载,也就是所谓的懒加载啦。
更改懒加载文件目录
默认情况下,上述的 0.js
、1.js
是在根目录的,这样对目录结构很不友好,我们希望把它们放在一个特定的目录去,在 webpack.mix.js
中添加:
mix.webpackConfig({
output: {
publicPath: "/",
chunkFilename: 'js/lazy/[name].[chunkhash].js'
},
})
这样的话,懒加载的js文件会放到 /js/lazy
目录中去,而不是在 /
中。
总结
单页应用写起来非常爽(私以为)