1、cssjavascript
一、Flex 布局css
参考:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.htmlhtml
1)
vueflex-direction
属性决定主轴的方向(即项目的排列方向)
它可能有4个值。java
row
(默认值):主轴为水平方向,起点在左端。row-reverse
:主轴为水平方向,起点在右端。column
:主轴为垂直方向,起点在上沿。column-reverse
:主轴为垂直方向,起点在下沿。
.top-banner { text-align: center; display: flex; flex-direction: column; justify-content: center; }
2)flex-grow
属性定义项目的放大比例,默认为0
,即若是存在剩余空间,也不放大。node
若是全部项目的flex-grow
属性都为1,则它们将等分剩余空间(若是有的话)。若是一个项目的flex-grow
属性为2,其余项目都为1,则前者占据的剩余空间将比其余项多一倍。react
3)flex-shrink
属性定义了项目的缩小比例,默认为1,即若是空间不足,该项目将缩小。webpack
若是全部项目的flex-shrink
属性都为1,当空间不足时,都将等比例缩小。若是一个项目的flex-shrink
属性为0,其余项目都为1,则空间不足时,前者不缩小。es6
4)flex-basis
属性定义了在分配多余空间以前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即项目的原本大小。web
5)flex
规定了弹性元素如何伸长或缩短以适应flex容器中的可用空间。这是一个简写属性,用来设置 flex-grow
, flex-shrink
与 flex-basis,默认值为
。0 1 auto
默认状况下,元素不会缩短至小于内容框尺寸,若想改变这一情况,请设置元素的min-width
与 min-height
属性。
flex
属性能够指定1个,2个或3个值。
单值语法: 值必须为如下其中之一:
<number>
): 它会被看成<flex-grow>的值。
width
)值: 它会被看成 <flex-basis>的值。
none
,auto
或initial
.双值语法: 第一个值必须为一个无单位数,而且它会被看成 <flex-grow>
的值。第二个值必须为如下之一:
<flex-shrink>
的值。<flex-basis>
的值。三值语法:
<flex-grow>
的值。<flex-shrink>
的值。<flex-basis>
的值。
2、js
一、Promise 对象
参考:http://es6.ruanyifeng.com/#docs/promise
Promise.reject(reason)
方法也会返回一个新的 Promise 实例,该实例的状态为rejected
。
const p = Promise.reject('出错了'); // 等同于 const p = new Promise((resolve, reject) => reject('出错了')) p.then(null, function (s) { console.log(s) }); // 出错了
Promise 实例具备then
方法,也就是说,then
方法是定义在原型对象Promise.prototype
上的。它的做用是为 Promise 实例添加状态改变时的回调函数。前面说过,then
方法的第一个参数是resolved
状态的回调函数,第二个参数(可选)是rejected
状态的回调函数。then
方法返回的是一个新的Promise
实例(注意,不是原来那个Promise
实例)。所以能够采用链式写法,即then
方法后面再调用另外一个then
方法。Promise.prototype.catch
方法是.then(null, rejection)
或.then(undefined, rejection)
的别名,用于指定发生错误时的回调函数。
getJSON('/posts.json').then(function(posts) { // ... }).catch(function(error) { // 处理 getJSON 和 前一个回调函数运行时发生的错误 console.log('发生错误!', error); });
上面代码中,getJSON
方法返回一个 Promise 对象,若是该对象状态变为resolved
,则会调用then
方法指定的回调函数;若是异步操做抛出错误,状态就会变为rejected
,就会调用catch
方法指定的回调函数,处理这个错误。另外,then
方法指定的回调函数,若是运行中抛出错误,也会被catch
方法捕获。通常来讲,不要在then
方法里面定义 Reject 状态的回调函数(即then
的第二个参数),老是使用catch
方法。
// bad promise .then(function(data) { // success }, function(err) { // error }); // good promise .then(function(data) { //cb // success }) .catch(function(err) { // error });
上面代码中,第二种写法要好于第一种写法,理由是第二种写法能够捕获前面then
方法执行中的错误,也更接近同步的写法(try/catch
)。所以,建议老是使用catch
方法,而不使用then
方法的第二个参数。通常老是建议,Promise 对象后面要跟catch
方法,这样能够处理 Promise 内部发生的错误。catch
方法返回的仍是一个 Promise 对象,所以后面还能够接着调用then
方法。
3、webpack
一、代码分离
参考:https://webpack.docschina.org/guides/code-splitting/
https://router.vuejs.org/zh/guide/advanced/lazy-loading.html
代码分离是 webpack 中最引人注目的特性之一。此特性可以把代码分离到不一样的 bundle 中,而后能够按需加载或并行加载这些文件。代码分离能够用于获取更小的 bundle,以及控制资源加载优先级,若是使用合理,会极大影响加载时间。
1)入口起点
这是迄今为止最简单、最直观的分离代码的方式。不过,这种方式手动配置较多,并有一些隐患。
// webpack.config.js module.exports = { entry: { index: './src/index.js', another: './src/another-module.js' } };
隐患:若是入口 chunk 之间包含一些重复的模块,那些重复模块都会被引入到各个 bundle 中;这种方法不够灵活,而且不能动态地将核心应用程序逻辑中的代码拆分出来。
分离 app(应用程序) 和 vendor(第三方库) 入口:在 webpack < 4 的版本中,一般将 vendor 做为单独的入口起点添加到 entry 选项中,以将其编译为单独的文件(与 CommonsChunkPlugin
结合使用)。而在 webpack 4 中不鼓励这样作。而是使用 optimization.splitChunks
选项,将 vendor 和 app(应用程序) 模块分开,并为其建立一个单独的文件。不要 为 vendor 或其余不是执行起点建立 entry。
2)防止重复
SplitChunksPlugin
插件能够将公共的依赖模块提取到已有的 entry chunk 中,或者提取到一个新生成的 chunk。
3)动态导入
当涉及到动态代码拆分时,webpack 提供了两个相似的技术。第一种,也是推荐选择的方式是,使用符合 ECMAScript 提案 的 import()
语法 来实现动态导入。
动态地加载模块。调用 import()
之处,被做为分离的模块起点,意思是,被请求的模块和它引用的全部子模块,会分离到一个单独的 chunk 中。
// 在注释中咱们提供了 webpackChunkName。这样会将拆分出来的 bundle 命名为如mainPage.xxxx.js export default new Router({ mode: process.env.VUE_APP_ROUTE_MODE, base: process.env.BASE_URL, routes: [ { path: '/', redirect: '/main' }, { path: '/main', component: AppMain, redirect: '/main/index', children: [{ path: 'index', name: 'index', component: () => import(/* webpackChunkName: "mainPage" */ './views/Index'), // 首页 meta: { title: '首页' } }, { path: 'prdRank', name: 'prdRank', component: () => import(/* webpackChunkName: "mainPage" */ './views/PrdRank'), // 游戏库 meta: { title: '游戏库' } }, { path: 'orderList', name: 'orderList', component: () => import(/* webpackChunkName: "mainPage" */ './views/OrderList'), // 个人订单 meta: { title: '个人订单' } }] }, { path: '/prdList', name: 'prdList', component: () => import(/* webpackChunkName: "prdPage" */ './views/PrdList') // 商品列表 }, { path: '/prdDetail', name: 'prdDetail', component: () => import(/* webpackChunkName: "prdPage" */ './views/PrdDetail'), // 商品详情 meta: { title: '商品详情' } } ] })
webpackChunkName
:新 chunk 的名称。
当打包构建应用时,JavaScript 包会变得很是大,影响页面加载。若是咱们能把不一样路由对应的组件分割成不一样的代码块,而后当路由被访问的时候才加载对应组件,这样就更加高效了。结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。
把组件按组分块:有时候咱们想把某个路由下的全部组件都打包在同个异步块 (chunk) 中。只须要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (须要 Webpack > 2.4)。Webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。
4)预取/预加载模块
在声明 import 时,使用下面这些内置指令,可让 webpack 输出 "resource hint(资源提示)",来告知浏览器:
与 prefetch 指令相比,preload 指令有许多不一样之处:
二、缓存
咱们使用 webpack 来打包模块化的应用程序,webpack 会生成一个可部署的 /dist
目录,而后把打包后的内容放置在此目录中。只要 /dist
目录中的内容部署到 server 上,client(一般是浏览器)就可以访问网站此 server 的网站及其资源。而最后一步获取资源是比较耗费时间的,这就是为何浏览器使用一种名为 缓存 的技术。能够经过命中缓存,以下降网络流量,使网站加载速度更快,然而,若是咱们在部署新版本时不更改资源的文件名,浏览器可能会认为它没有被更新,就会使用它的缓存版本。经过必要的配置,以确保 webpack 编译生成的文件可以被客户端缓存,而在文件内容变化后,可以请求到新的文件。webpack 提供了一种使用称为 substitution(可替换模板字符串) 的方式,经过带括号字符串来模板化文件名。其中,[contenthash]
substitution 将根据资源内容建立出惟一 hash。当资源内容发生变化时,[contenthash]
也会发生变化。
将第三方库(library)(例如 lodash
或 react
)提取到单独的 vendor
chunk 文件中,是比较推荐的作法,这是由于,它们不多像本地的源代码那样频繁修改。所以经过实现以上步骤,利用 client 的长效缓存机制,命中缓存来消除请求,并减小向 server 获取资源,同时还能保证 client 代码和 server 代码版本一致。
// webpack.config.js optimization: { splitChunks: { cacheGroups: { vendors: { name: 'chunk-vendors', test: /[\\\/]node_modules[\\\/]/, priority: -10, chunks: 'initial' } }
} }
而 vendor
hash 发生变化是咱们要修复的。幸运的是,可使用两个插件来解决这个问题。第一个插件是 NamedModulesPlugin
,将使用模块的路径,而不是一个数字 identifier。虽然此插件有助于在开发环境下产生更加可读的输出结果,然而其执行时间会有些长。第二个选择是使用 HashedModuleIdsPlugin
,推荐用于生产环境构建。