0%

收录一些常用的居中方式,包括水平居中和垂直居中。

虽然这是很老的知识了,但是想要做的事,什么时候都不算晚。

其实使用 flex 或者 grid 能够解决大部分布局情况,虽然我还不会使用 grid 就是了。

另外,flex 真的好用哈哈哈哈哈哈哈哈哈。

阅读全文 »

参考要写在最前面

如何处理移动端 1px 渲染成 2px 的问题

  • 局部处理

    • mate 标签中 viewport 属性,initial-scale 属性设置为 1
    • rem 按照设计稿标准走,外加利用 transform 的 scale(0.5) 缩小一半
  • 全局处理

    • mate 标签中 viewport 属性,initial-scale 属性设置为 0.5
    • rem 按照设计稿标准走

BFC - Box、Formatting Context - 块级格式化上下文

BFC 是一个独立的渲染区域,只有 Block-level box 参与,它规定了内部的 Block-level Box 如何布局,并且与这个区域外部毫不相干。

Box 是 CSS 布局的对象和基本单位,一个页面是由一个或多个 Box 组成。元素的类型和 display 属性决定了这个 Box 的类型。不同类型的 Box 会参与不同的 Formatting Context(一个决定如何选人文档的容器),因此 Box 内的元素会以不同的方式渲染。

  • 创建规则

    • 根元素
    • 浮动元素(float 不取值为 none)
    • 绝对定位元素(position 取值为 absolute 或 fixed)
    • display 取值为 inline-block、table-cell、flex、inline-flex 之一的元素
    • overflow 不取值为 visible 的元素
  • 作用

    • 可以包含浮动元素
    • 不被浮动元素覆盖
    • 阻止父子元素 margin 折叠

IE 盒模型、W3C 盒模型

  • W3C 盒模型:内容(content)、填充(padding)、边界(margin)、边框(border);

    • box-sizing: content-box
    • width = content width
  • IE 盒模型:IE 的 content 部分把 border 和 padding 计算进去了

    • box-sizing: border-box
    • width = border + padding + content width

居中

  • 水平居中方法

    • 元素为行内元素,设置父元素 text-align:center
    • 如果元素宽度固定,可以设置左右 margin 为 auto
    • 如果元素为绝对定位,设置父元素 position:relative,元素设 left:0;right:0;margin:auto
    • 使用 flex-box 布局,指定 justify-content 属性为 center
    • display 设置为 table-cell,与行内元素一致,也是需要设置 text-align:center,主要还是用来垂直居中
  • 垂直居中的方法

    • 将显示方式设置为表格,display:table-cell,同时设置 vertial-align:middle
    • 使用 flex 布局,设置 align-items: center
    • 绝对定位总设置 bottom:0;top:0;,并设置 margin:auto
    • 绝对定位中固定高度时,设置 top:50%;margin-top 值为高度一半的负值
    • 文本垂直居中设置 line-height 为 height 值

当一个 CSS 文件很大的时候,如果还没有下载完成,js 会不会执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en">
<head>
<title>css阻塞</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script>
console.log("before css");
var startDate = new Date();
function h() {
console.log(document.querySelectorAll("h1"));
}
setTimeout(h, 0);
</script>
<link
href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css?timestame=1"
rel="stylesheet"
/>
</head>
<body>
<h1>这是红色的</h1>
<script>
var endDate = new Date();
console.log("after css");
console.log("经过了" + (endDate - startDate) + "ms");
</script>
</body>
</html>

将网速调整至低速,执行以上代码,会发现能够控制台第一时间输出的是 before css 之后能够获取到 h1 标签,但是却没有渲染出来,也就说明 CSS 下载过程并不会阻塞 DOM 的解析,但是会阻塞 DOM 的渲染。隔了一段时间之后才能看到 after css 的字样,但这不能证明会阻塞,但是当我们去掉 link 标签之后,after css 会马上被打印出来,这样就能够证明 CSS 的下载会阻塞 js 的执行

附 webkit 流程一张

1ydsk1wex0.png

关于浏览器性能优化的需要重新开一个写

https://blog.csdn.net/y_programmer_ape/article/details/107307676

vue 面试题

  1. vue 中 data 为什么必须是一个函数?为什么需要 return 返回?

    vue 中 data 必须是一个函数的原因是为了保证组件的独立性和可复用性。data 是一个函数,组件实例化的时候这个函数将被调用,返回一个对象,计算机会给这个对象分配一个地址,实例化几次就分配几个地址,他们所在地址不同,所以每个组件中的数据互不干扰,改变一个组件的状态其他的不会发生改变。

    不使用 return 包裹的数据会在项目的全局可见,会造成污染。使用 return 包裹后数据中变量只会在当前的组件中生效,不会影响其他组件。

  2. 由于 js 的限制,直接给一个数组项赋值,vue 能不能检查到变化?

    不能,用索引直接设置一个数组项或者修改数组长度时,vue 不能检测到数组变化(引用地址不变)(栈上的值不变)

    为了解决这个问题,vue 提供了如下操作方法:

    1. Vue.set
    2. vm.$set (Vue.set 的别名)
    3. Array.prototype.splice
    4. vm.items.splice(修改数组长度)

    其实这些方法也是修改后改变引用地址吧?

  3. 父子传值问题

    父传子:子组件通过 prop 接受

    子传父:

    • 子组件绑定一个事件,通过 $emit 触发
    • 父组件通过 callback 函数,并把这个函数传给子组件,子组件通过 props 接收
    • 通过 parent 和 children 或者 $refs 访问组件的实例
    • 父组件通过 provide 提供变量,子组件通过 inject 注入变量
    • vuex
  4. vuex 的理解

    vuex 是 vue 的状态管理模式,每个 vuex 的核心就是 store(仓库),包含着应用中的大部分状态(state)。

    vuex 的存储是响应式的,当组件从 store 中获取状态时,当 state 里面的状态发生改变时,组件也会做出相应的更新。

    改变 store 里的状态的唯一方法是显式提交一个 mutation。

    主要包括几个模块:

    • state 单一数据源,定义应用状态的数据结构,设置初始状态。 mapState
    • getters 允许组件从 store 中获取数据,是 store 的计算属性。 mapGetters
    • mutations 是 store 的 methods,保存着更改数据的回调函数,是同步操作,第一个参数是 state,第二个参数是自定义参数。 mapMutations
    • actions 是异步的操作方法,第一个参数是 context,是一个与 store 具有相同的属性的对象,使用 commit 异步提交 mutations 里的的方法
    • modules 模块化,将 store 分割成模块,每个模块具有自己的 state、getters、mutations、actions

实际遇到的面试题汇总

  1. 在标准的 JavaScript 中, Ajax 异步执行调用基于下面哪一个机制才能实现?

    答案:Event 和 callback,以及 Deferral 和 promise。

    其中 Event 指的是 eventloop 而不是 DOM Event。Deferral 和 promise 是在 ES6 之后出现的,标准答案应该是 event 和 callback。

  2. 白屏时间(first paint) 和可交互时间(dom ready)的关系

    答案:先是白屏时间,然后才是可交互时间。

    白屏时间指的是用户从打开页面开始到页面开始有东西呈现为止;

    首屏时间指的是用户浏览器首屏内所有内容都呈现出来所花费的时间;

    用户可操作时间(dom interactive)指的是用户可以进行正常的点击、输入等操作;

    总下载时间指的是页面所有资源都加载完毕并呈现出来所花费的时间,即页面 onload 的时间;

  3. css 中不可以继承的属性

    几乎所有与当前元素轮廓相关的内容都不可以。

    display、margin、border、padding、background、height、min-height、max-height、width、min-width、max-width、overflow、position、top、right、bottom、left、z-index、float、clear、table-layout、vertical-align、page-break-after、page-break-before。

  4. 当页面中存在多个 <link href="main1.css" rel="stylesheet" /> 时,浏览器会同时开始加载,先加载完的优先解析,如果遇到相同的选择器规则,则后面的会将前面的覆盖。

隐约雷鸣,阴霾天空,但盼风雨来,能留你在此
隐约雷鸣,阴霾天空,即使天无雨,我亦留此地

设计模式真的是学了忘,忘了学,学了又忘,学的时候想着优化的地方还挺多,要用到的时候根本想不起来。

多学一点东西,多一种思考方式,虽然不一定用得到,但是积累到某个时刻一定会有回报的。

阅读全文 »

每个人的封装都有自己的风格在里边,所以有自己的风格没有问题。

这是一个关于 umi-request 通用请求的的封装,已实现的部分功能:

  • 默认注入 newHeaders.Authorization 减少调用时的 token 输入;
  • 根据 withToken 参数不校验 token;
  • 隐藏报错也可以使用 showError=false 实现;(尽量不用吧,性能问题)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { request as umiRequest } from 'umi';
import { RequestOptionsInit, RequestResponse } from 'umi-request';

interface extendedRequestOptions {
skipErrorHandler?: boolean;
withToken?: boolean;
showError?: boolean;
}

interface RequestOptions extends RequestOptionsInit, extendedRequestOptions {}

interface RequestOptionsWithResponse extends RequestOptionsInit, extendedRequestOptions {
getResponse: true;
}

interface RequestOptionsWithoutResponse extends RequestOptionsInit, extendedRequestOptions {
getResponse: false;
}

// 根据实际项目的基本返回外层定义
export interface ResponseResult<T> {
data: T;
code: string;
desc: string;
}

interface RequestMethod<R = false> {
<T = any>(url: string, options: RequestOptionsWithResponse): Promise<RequestResponse<ResponseResult<T>>>;
<T = any>(url: string, options: RequestOptionsWithoutResponse): Promise<ResponseResult<T>>;
<T = any>(url: string, options?: RequestOptions): R extends true
? Promise<RequestResponse<ResponseResult<T>>>
: Promise<ResponseResult<T>>;
}

// 这里的 options 其实是 umi-request 本来的 options 外加上自定义的一些属性。
// 可以把自定义的一些属性单独拿出来作为第三个属性,这样会不会比较好看一些
const request: RequestMethod = async (url: any, options: any = {}) => {
const { withToken = true, showError = true, headers, ...restOptions } = options as RequestOptions;
let newHeaders: Record<string, string> = {};
if (withToken) {
const token = getToken(); // 获取本地保存的 token
newHeaders['Authorization'] = `Bearer ${token}`;
}

const newOptions: RequestOptions = {
...restOptions,
headers: { ...headers, ...newHeaders },
};

return umiRequest(url, newOptions).catch(err => {
showError && console.error(err); // 至于这里的报错展示可以自定义展示
});
};

export default request;

使用方法:

1
2
3
4
5
6
7
8
9
const getTitle = (params) => {
return request('/api/bababa', {
method: 'get',
// ...
})
}

// 实际上会返回一个promise,该promise返回一个对象{code, data, success},但实际上还是要根据实际业务情况来
const {data} = getTitle(params)

有时候人们很喜欢造一些名字很吓人的名词,让人一听这个名词就觉得自己不可能学会,从而让人望而却步。但是其实这些名词背后所代表的东西其实很简单。—— 来自 React.js 小书

第一次遇到高阶函数是曾溪叫我们写 PHP 的时候教的,当初好像搞懂了,又好像没懂。

之后遇到 react 高阶组件就蒙了,才发现我根本没懂。

以此告诫自己,要多记笔记,多学习。

阅读全文 »

我必须羞耻地承认,我可以谈话的对象数量越来越少了。 —— 维特根斯坦

前面我们写过一篇 Promise 基础,这让我们知道了怎么用 Promise。
但是仅仅知道怎么用就够了嘛?我们还需要知道怎么自行封装一个 Promise。以及如何应付面试(●’◡’●)。

阅读全文 »