material-UI

clone 属性

!!响应式字体大小
[cc lang=”js”]const theme = createMuiTheme();

theme.typography.h1 = {
fontSize: ‘3rem’,
‘@media (min-width:600px)’: {
fontSize: ‘4.5rem’,
},
[theme.breakpoints.up(‘md’)]: {
fontSize: ‘6rem’,
},
};[/cc]

自定义变量
[cc lang=”js”]

import Checkbox from ‘@material-ui/core/Checkbox’;
import { createMuiTheme, withStyles } from ‘@material-ui/core/styles’;
import { ThemeProvider } from ‘@material-ui/styles’;
import { orange } from ‘@material-ui/core/colors’;

const styles = theme => ({
root: {
color: theme.status.danger,
‘&$checked’: {
color: theme.status.danger,
},
},
checked: {},
});

let CustomCheckbox = props => (

);

CustomCheckbox.propTypes = {
classes: PropTypes.object.isRequired,
};

CustomCheckbox = withStyles(styles)(CustomCheckbox);

const theme = createMuiTheme({
status: {
// My business variables
danger: orange[500],
},
});

function CustomStyles() {
return (



);
}

export default CustomStyles;[/cc]

****************
每个 material-ui 组件都有一个 class 类, theme 可以从写这个类,类的样式可以到组件详情里看到
当配置变量不够强大的时候,您可以使用theme的overrides来让Material-UI隐式地为您注入样式规则。 这是一个非常强大的特性。

[cc lang=”js”]const theme = createMuiTheme({
overrides: {
// Style sheet name ⚛️
MuiButton: {
// Name of the rule
text: {
// Some CSS
color: ‘white’,
},
},
},
});[/cc]
**************

css 进化史

  • 全局污染 – CSS的选择器是全局生效的,所以在class名称比较简单时,容易引起全局选择器冲突,导致样式互相影响。
  • 命名混乱 – 因为怕全局污染,所以日常起class名称时会尽量加长,这样不容易重复,但当项目由多人维护时,很容易导致命名风格不统一。
  • 样式重用困难 – 有时虽然知道项目上已有一些相似的样式,但因为怕互相影响,不敢重用。
  • 代码冗余 – 由于样式重用的困难性等问题,导致代码冗余。

 

在CSS的进化历史上,出现过各种各样的框架致力于解决以上的问题:

  • SASS, LESS – 提供了变量、简单函数、运算、继承等,扩展性、重用性都有了很大的提升,解决了一些样式重用冗余的问题,但是对于命名混乱问题的效果不大。
  • BEM (.block__element–modifier) – 比较流行的class命名规则,部分解决了命名混乱和全局污染的问题,但class定义起来还是不太方便,比较冗长,而且和第三方库的命名还是有可能冲突。
  • CSS Modules – 模块化CSS,将CSS文件以模块的形式引入到JavaScript里,基本上解决了全局污染、命名混乱、样式重用和冗余的问题,但CSS有嵌套结构的限制(只能一层),也无法方便的在CSS和JavaScript之间共享变量。(compose: classname 可以在里嵌套一层)

css Moduel例子了解

[cc ]
****/components
*********/Button
*************Button.js
*************styles.css

// styles.css
.red {
font-size: 25px;
background-color: red;
color: white;
}

// Button.js file
import React from ‘react’
import btn from ‘./styles.css’

export default class CoolButton extends React.Component {
render() {
return (

)
}
}
[/cc]

流行框架介绍

现在随着组件化概念的流行,对从组件层面维护CSS样式的需求日益增大,CSS-in-JS就是在组件内部使用JavaScript对CSS进行了抽象,可以对其声明和加以维护。这样不仅降低了编写CSS样式带来的风险,也让开发变得更加轻松。它和CSS Modules的区别是不再需要CSS样式文件。

先来看看下载量最高的styled-component的代码风格:

 

内容高度不够时,footer 依然显示到最下面

1. 用flex 解决
[cc]

html {
height: 100%;
}
$footer-height: 30px;
body {
min-height: 100%;
display: flex;
flex-direction: column;
}
#content {
flex: 1;
}

#footer {
line-height: $footer-height;
text-align: center;
}[/cc]
2 padding-bottom margin-top
[cc]
html, body {
height: 100%;
}
$footer-height: 30px;
#content {
min-height: 100%;
margin-bottom: -$footer-height;
padding-bottom: $footer-height;
// requires box-sizing: border-box;
// 下面的不需要 border-box
/*
&::after {
content: ”;
display: block;
height: $footer-height; // footer height
}
*/
}

#footer {
line-height: $footer-height;
text-align: center;
}
或者
#content {
min-height: 100%;
padding-bottom: $footer-height;
}

#footer {
height:$footer-height;
line-height: $footer-height;
text-align: center;
margin-top: -$footer-height;
}

[/cc]

performance 前端性能监控

Performance是一个做前端性能监控离不开的API,最好在页面完全加载完成之后再使用,因为很多值必须在页面完全加载之后才能得到。最简单的办法是在window.onload事件中读取各种数据。

按触发顺序排列所有属性:(更详细标准的解释请参看:W3C Editor’s Draft)
navigationStart:在同一个浏览器上下文中,前一个网页(与当前页面不一定同域)unload 的时间戳,如果无前一个网页 unload ,则与 fetchStart 值相等
unloadEventStart:前一个网页(与当前页面同域)unload 的时间戳,如果无前一个网页 unload 或者前一个网页与当前页面不同域,则值为 0
unloadEventEnd:和 unloadEventStart 相对应,返回前一个网页 unload 事件绑定的回调函数执行完毕的时间戳
redirectStart:第一个 HTTP 重定向发生时的时间。有跳转且是同域名内的重定向才算,否则值为 0
redirectEnd:最后一个 HTTP 重定向完成时的时间。有跳转且是同域名内的重定向才算,否则值为 0
fetchStart:浏览器准备好使用 HTTP 请求抓取文档的时间,这发生在检查本地缓存之前
domainLookupStart:DNS 域名查询开始的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 fetchStart 值相等
domainLookupEnd:DNS 域名查询完成的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 fetchStart 值相等
connectStart:HTTP(TCP) 开始建立连接的时间,如果是持久连接,则与 fetchStart 值相等,如果在传输层发生了错误且重新建立连接,则这里显示的是新建立的连接开始的时间
connectEnd:HTTP(TCP) 完成建立连接的时间(完成握手),如果是持久连接,则与 fetchStart 值相等,如果在传输层发生了错误且重新建立连接,则这里显示的是新建立的连接完成的时间

注意:这里握手结束,包括安全连接建立完成、SOCKS 授权通过

secureConnectionStart:HTTPS 连接开始的时间,如果不是安全连接,则值为 0
requestStart:HTTP 请求读取真实文档开始的时间(完成建立连接),包括从本地读取缓存,连接错误重连时,这里显示的也是新建立连接的时间
responseStart:HTTP 开始接收响应的时间(获取到第一个字节),包括从本地读取缓存
responseEnd:HTTP 响应全部接收完成的时间(获取到最后一个字节),包括从本地读取缓存
domLoading:开始解析渲染 DOM 树的时间,此时 Document.readyState 变为 loading,并将抛出 readystatechange 相关事件
domInteractive:完成解析 DOM 树的时间,Document.readyState 变为 interactive,并将抛出 readystatechange 相关事件

!!!只是 DOM 树解析完成,这时候并没有开始加载网页内的资源

domContentLoadedEventStart:DOM 解析完成后,网页内资源加载开始的时间,文档发生 DOMContentLoaded事件的时间
domContentLoadedEventEnd:DOM 解析完成后,网页内资源加载完成的时间(如 JS 脚本加载执行完毕),文档的DOMContentLoaded 事件的结束时间
domComplete:DOM 树解析完成,且资源也准备就绪的时间,Document.readyState 变为 complete,并将抛出 readystatechange 相关事件
loadEventStart:load 事件发送给文档,也即 load 回调函数开始执行的时间,如果没有绑定 load 事件,值为 0
loadEventEnd:load 事件的回调函数执行完毕的时间,如果没有绑定 load 事件,值为 0

常用计算:

DNS查询耗时 :domainLookupEnd – domainLookupStart
TCP链接耗时 :connectEnd – connectStart
request请求耗时 :responseEnd – responseStart
解析dom树耗时 : domComplete – domInteractive
白屏时间 :responseStart – navigationStart
domready时间(用户可操作时间节点) :domContentLoadedEventEnd – navigationStart
onload时间(总下载时间) :loadEventEnd – navigationStart

now()

performance.now()是当前时间与performance.timing.navigationStart的时间差,以微秒(百万分之一秒)为单位的时间,与 Date.now()-performance.timing.navigationStart的区别是不受系统程序执行阻塞的影响,因此更加精准

前端路由回退时,如果页面中还有资源在pending, 页面不会跟着立即跳转

资源型会 阻塞 回退, xhr fetch 不会阻塞;
解决
1. 通过replace 代替 回退
2. 路由变化时,
2.1watch:{
$route(to,from){
console.log(to.path);
}
},
2.2 window.addEventListener(‘popstate’, function() { // 监听回退按钮
console.log(‘我监听到了回退事件’); // 在回退时进行某种操作。
},false);

option 跨域 请求详解

什么情况下需要 CORS ?

跨域资源共享标准( cross-origin sharing standard )允许在下列场景中使用跨域 HTTP 请求:

功能概述

跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

CORS请求失败会产生错误,但是为了安全,在JavaScript代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。

简单请求

某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,请注意,该术语并不属于 Fetch (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:

预检请求 

与前述简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS   方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。”预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。 不属于简单请求都将有预检请求。

附带身份凭证的请求

Fetch 与 CORS 的一个有趣的特性是,可以基于  HTTP cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨域 XMLHttpRequest 或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息cookie,需要设置 XMLHttpRequest 的某个特殊标志位。 如 设置 withCredentials 标志设置为 true

附带身份凭证的请求与通配符

对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。

这是因为请求的首部中携带了 Cookie 信息,如果 Access-Control-Allow-Origin 的值为“*”,请求将会失败。而将 Access-Control-Allow-Origin 的值设置为 http://foo.example,则请求将成功执行。

另外,响应首部中也携带了 Set-Cookie 字段,尝试对 Cookie 进行修改。如果操作失败,将会抛出异常。