Skip to content

前端笔记

HTML

行内元素、块级元素、空元素有哪些

  • 行内元素:span、i、img、input
  • 块级元素:div、p、h1~6、header、section、footer
  • 空元素:br、hr

元素之间的转换

  • 行内元素:inline
  • 行内块元素:inline-block
  • 块级元素:block

导入样式时,link和@import的区别

  1. 先有link后有@import,link的兼容性比@import好
  2. link是标签,@import不是
  3. 浏览器先加载link,后加载@import

title与h1的区别

定义

  1. title是网站标题,概括了网站信息,告诉搜索引擎或用户网站的内容主题是什么
  2. h1是网站内容,告诉搜索引擎网站的主要内容是什么

区别

  1. title是显示在网页标题上的,h1是显示在网页内容上的
  2. title比h1重要

b与strong的区别

定义

  1. b标签是实体标签,用来给文字加粗的
  2. strong标签是逻辑标签,用来加强字符语气的

区别

  1. b标签只是加粗,没有实际含义
  2. strong是强调标签内字符比较重要
  3. strong更符合CSS3的规范

i与em的区别

定义

  1. i标签是实体标签,用来做文字倾斜的
  2. em标签是逻辑标签,用来强调文字内容的

区别

  1. i标签只是倾斜,没有实际含义
  2. em是强调标签内字符比较重要
  3. i更多的用在字体图标上,em更多的用在术语上(医药、生物)

img标签的title和alt的区别

  1. title是鼠标悬停在图片上显示的提示信息
  2. alt是图片加载失败时显示的信息
  3. 为了让搜索引擎更好的搜索到网站,最好每一张图片都加上alt

解释一下png、jpg、gif、webp图片格式,分别在什么时候使用

  1. png是无损压缩,体积比jpg和jpeg更大,支持透明,适合做小图标
  2. jpg采用压缩算法,有一点失真,体积比png小,不支持透明,适合做大图片(轮播图)
  3. gif一般是做动图,较少使用
  4. 同时支持有损和无损压缩,相同质量的图片,webp具有更小的体积,兼容性较差

CSS

CSS的盒子模型

  1. 有哪些
  2. 标准盒子模型:content-box,由margin、border、padding、content组成
  3. IE盒子模型:border-box,有margin、content(border + padding + content)组成
  4. 如何转换
  5. box-sizing

line-height和height的区别

  1. line-height是每行文字的高,在未设置height时如果文字换行,则整个盒子高度会增大(行数 * line-height)
  2. height是盒子的高

CSS选择器有哪些

选择器
*通配符选择器
#id选择器
.类选择器
div、p...标签选择器
+直接相邻选择器
~相邻选择器
>子代选择器
空格后代选择器
[属性]属性选择器
:hover...伪类选择器
:before...伪元素选择器

哪些属性可以继承

color、font-size、line-height、text-align...

哪些属性不可继承

border、padding、margin...

CSS优先级(权重)算法

!important:无限大 内联样式:1000 id:0100 class:0010 标签:0001 通配符、继承:0 算法:相加不进位,如十个id应为010000而不是1000,内联的权重仍然更大

用CSS画一个三角形

使用border,宽高为0,保留箭头方向对立方向的border的颜色,其余为透明

一个盒子不给宽高如何水平垂直居中

  1. 父盒子设置为弹性盒子,align-items: center;justify-content: center;
  2. 绝对定位 + left: 50%;top: 50%;transform: translate(-50%, -50%);

display有哪些值

  1. none:元素不被显示且不占用位置
  2. block:块级元素,占用一整行
  3. inline:行内元素,无法设置宽高
  4. inline-block:行内块元素,可以设置宽高
  5. flex:弹性盒子
  6. grid:网格布局

对BFC规范的理解

BFC也就是块级格式化上下文,他是页面上的一个隔离的独立容器,容器内的子元素不回影响到外面的元素 比如说div包裹着一个p标签,div下面有一个h1标签,当p标签设置了浮动,就会导致div标签高度塌陷,进而导致h1会跟在p标签后面,在同一行,而BFC就可以解决这一问题

触发方法

  1. float的值非none
  2. overflow的值非visible
  3. display的值为inline-block...
  4. position的值为absolute

清除浮动有哪些方式

  1. 触发BFC
  2. 在最后多创建一个盒子,添加样式:clear: both
  3. 添加伪元素after,添加样式content: '';display: block;clear: both;

在网页中应该使用奇数还是偶数的字体

偶数,让文字在浏览器上表现更好看

position有哪些值

  1. absolute:绝对定位,相对于拥有absolute或releavte的父元素定位,若无,则相对于浏览器进行定位,脱离文档
  2. fixed:固定定位,相对于浏览器进行定位,脱离稳定
  3. relative:相对定位,相对于自身进行定位,不脱离文档,left会覆盖right,top会覆盖bottom
  4. static:默认值,没有定位
  5. sticky:粘性定位,当页面滚动超出目标区域时,相对于fixed,否则相对于relative

什么是CSS reset

reset.css是一个重置CSS样式的文件,但因为性能问题,现在用得比较少,现在主要用normalize.css

CSS sprite(雪碧图)的优缺点

是什么

将多个小图标合并为一张大图片

优点

  1. 减少向服务器发送请求的次数

缺点

  1. 改一个小图标就要改整张图,难维护
  2. 使用麻烦

display: none和visibility: hidden的区别

display: none不占用位置 visibility: hidden占用位置

opacity和rgba的区别

  1. opactiy作用于整个元素,包括文字颜色,子元素等都会被影响,rgba只作用于背景色

JavaScript

延迟加载JS的方法

  1. async:在下载js脚本时不暂停HTML的解析,在执行js时暂停HTML的解析,非顺次执行,谁先加载完谁先执行
  2. defer:在下载js脚本时不暂停HTML的解析,并在HTML解析完毕后再执行,顺次执行js脚本

数据类型有哪些

  • 基本类型:string、number、boolean、undefined、null、symbol(ES6)、bigint(有争议)
  • 引用类型:object

注意

  • undefined 与除字符串外的类型相加,最终都会变成数值类型
  • typeof undefined 还是 undefined
  • null是一个特殊的对象

null和undefined的区别

  1. null是一个表示"无"的特殊对象(空白对象指针),转为数值时是 0,在发生错误时不容易被发
  2. undefined是一个基本类型,转换为数值时是NaN

==和===的区别

  1. ==会隐式转换
  2. ===是全等,除了比较值还会比较类型

在转换中

  1. null == undefined
  2. string == number --> string转number
  3. boolean == number --> boolean转number
  4. object == 基础类型 --> object转基础类型

微任务和宏任务

  1. js是单线程语言,在同步任务执行完后再执行事件循环(请求、定时器、事件...)
  2. 事件循环包含微任务和宏任务
  3. 微任务:promise.then
  4. 宏任务:setTimeout
  5. 总流程:同步 -> 微任务 -> 宏任务 -> 微任务 -> (宏任务 -> 微任务)(循环)...

作用域

  1. 作用域是一个作用范围,有全局作用域和函数作用域,在ES6以前,js 没有块级作用域,只有函数作用域
  2. 在ES6的跨级作用域中,只有let定义的变量和const定义的常量,外部才无法访问,var定义的变量在外部仍可以访问
  3. 外部无法访问内部,但内部跨域访问外部
  4. 若定义变量/常量前无var、let、const,则视为全局变量,如
javascript
(function(){
var a = b = 10; => var a = 10; window.b = 10;
})()
  1. 优先级:变量 > 函数提升 > 参数 > 变量提升

作用域链

从当前作用域逐级向上寻找,子作用域可以访问父作用域的属性,直到寻找到全局作用域,称为作用域链

对象

  1. 对象是通过new操作符构建出来的,所以对象之间不相等
  2. 对象是引用类型
  3. 对象的key都是字符串类型
  4. 对象寻找属性|方法:对象本身 --> 构造函数 --> 构造函数原型 --> 对象上一层原型

原型

  1. 什么是原型
  2. 用于共享属性和方法,函数的内部属性prototype(对象是__proto__)所对应的,就是原型
  3. 解决的问题
  4. 对象共享属性和方法
  5. 谁拥有原型
  6. 函数:prototype
  7. 对象:__proto__

原型链

  1. 什么是原型链 将原型串联起来,最终指向null,形成原型链
  2. 查找顺序 对象本身 > 构造函数 > 对象的原型 > 构造函数的原型 > 当前原型的原型

判断变量是否为数组

  1. Array.isArray
  2. instanceof [Array]
  3. Obejct.prototype.toString.call(arr)
  4. Array.protytype.isPrototypeOf(arr)

slice是干嘛的、splice是否会改变原数组

  1. slice是用来截取的,返回新数组
  2. splice可以用来插入、删除、替换,返回被删除的元素,会改变原来的数组

数组去重

  1. new set
javascript
var arr = [1,2,3,2,4,1];
console.log(Array.from(new Set(arr)));
console.log([...new Set(arr)])
  1. indexOf
javascript
var arr = [1,2,3,2,4,1];
function unique(arr){
var brr = [];
for(let i = 0;i < arr.length;i++){
if(brr.indexOf() == -1) brr.push(arr[i]);
}
return brr;
}
  1. sort
javascript
var arr = [1,2,3,2,4,1];
function unique(arr){
arr = arr.sort();
var brr = [];
for(let i = 0;i < arr.length;i++){
if(arr[i]!==arr[i-1]){
brr.push(arr[i]);
}
}
return brr;
}
  1. filter
javascript
var arr = [1,2,3,2,4,1];
var brr = arr.filter((item,index)=>{
return arr.indexOf(item) == index;
// 原理:找出item在数组中第一次出现的位置,若是第一次出现,indexOf(item)与index是相对应的,若不是第一次出现,则不相对应
})

给字符串新增方法实现功能

String.prototype.xxx = function(){}

统计字符次数

javascript
const str = 'abcffbfffcap';
let obj = {};
for (let i = 0; i < str.length; i++) {
if (!obj[str[i]]) {
obj[str[i]] = 1;
} else {
obj[str[i]] += 1;
}
}
console.log(obj);

出现次数最多的字符

  1. 正则
javascript
let str = 'abcffbfffcap'; // 原始字符串
let index = 0; // 出现的次数
let value = ''; // 出现次数最多的字符
str = str.split('').sort().join('');
str.replace(/(w)1+/g, (val, item) => {
if (index < val.length) {
value = item;
index = val.length;
}
});
console.log(value, index);
  1. 循环
javascript
const str = 'abcffbfffcap';
let obj = {};
for (let i = 0; i < str.length; i++) {
if (!obj[str[i]]) {
obj[str[i]] = 1;
} else {
obj[str[i]] += 1;
}
}
let max = 0;
let val = '';
for(let key in obj){
if(max < obj[key]){
max = obj[key];
val = key;
}
}
console.log(key, max)

new操作符具体做了什么

  1. 创建了一个空的对象
  2. 将空对象的原型指向于构造函数的原型
  3. 将空对象作为构造函数的上下文(改变this指向)
  4. 对构造函数有返回值的处理判断(如果返回值是基本类型,则忽略,如果是引用类型,则返回)

闭包

  1. 闭包是什么
  • 闭包是一个函数加上到创建函数的作用域的连接,闭包"关闭"了函数的自由变量
  • 简单来说就是一个函数内return另一个函数,内部函数称为闭包
  • 函数执行完后,变量不会被销毁
  1. 闭包的优点
  2. 内部函数可以访问外部函数的局部变量
  3. 命名冲突
  4. for循环中,var定义的i的问题
  5. 闭包的缺点
  6. 变量会驻留在内存中,造成内存损耗问题,解决方法:把闭包函数设置为空

JS的继承方式

  1. ES6
javascript
class Parent{
constructor(){
this.age = 18;
}
}
class Child extends Parent{
consturctor(){
super();
this.name = '张三';
}
}
let o1 = new Child();
console.log(o1.age);
  1. 原型链继承,可以共享,但无法向父构造函数传递参数
javascript
function Parent(){
this.age = 18;
}
function Child(){
this.name = '张三';
}
Child.prototype = new Parent(); // 将Parent放到Child的prototype中
let o1 = new Child();
console.log(o1.age);
  1. 借用构造函数,无法共享
javascript
function Parent(){
this.age = 18;
}
function Child(){
Parent.call(this); // 将Parent指向当前
this.name = '张三';
}
let o1 = new Child();
console.log(o1.age);
  1. 组合继承,可以共享
javascript
function Parent(){
this.age = 18;
}
function Child(){
Parent.call(this);
this.name = '张三';
}
Child.prototype = new Parent();
let o1 = new Child();
console.log(o1.age);

call、apply、bind的区别

  1. 功能一致,可以改变函数体内的this的指向
  2. call、apply会立即执行,bind不会,返回改变this指向后的函数
  3. call、bind传参方式是多个参数,apply传参方式是数字
  • call:调用函数并改变this指向,fn.apply(this指向,参数1,参数2...)
  • apply:调用函数并改变this指向,fn.apply(this指向,[参数1,参数2...])
  • bind:改变this指向但不调用函数,返回改变this指向后的函数

sort的原理

默认是根据Unicode的编码进行排序

javascript
arr.sort((a,b)=>{
return a-b; // 从小到大
return b-a; // 从大到小
})

深拷贝和浅拷贝

  1. 浅拷贝:只复制引用,而未复制真正的值
  2. 深拷贝:彻底复制
javascript
// 使用JSON.stringify + JSON.parse
let obj2 = JSON.parse(JSON.stringify(obj1));
// 自定义deepCopy

function isObject(obj) {
return typeof obj === 'object' && obj !== null;
}
function deepCopy(source) {
if (!isObject(source)) return source; //如果不是对象的话直接返回
let target = Array.isArray(source) ? [] : {}; //数组兼容
for (var k in source) {
if (source.hasOwnProperty(k)) {
if (typeof source[k] === 'object') {
target[k] = deepCopy(source[k]);
} else {
target[k] = source[k];
}
}
}
return target;
}

H5C3

什么是语义化标签

如header、section、footer等这些标签就是语义化标签,他的

  1. 易读性和维护性更高
  2. SEO成分会更好

before和after中双冒号和单冒号的区别

实际效果没有区别,但为了更好的区分伪类和伪元素,伪类会用单冒号,为元素用双冒号 before是在元素的最前面添加一个元素、after是在元素的最后面添加一个元素

如何关闭IOS键盘首字母大写

给input添加autocapitalize="off"

如何让Chrome支持小于12px的文字

  1. 缩放:transform: scale()

rem和em的区别

  • em:相对于父元素的 font-size 进行调整
  • rem:相对于 html 标签的 font-size 进行调整

IOS系统中元素被触摸时产生的半透明灰色遮罩如何解决

css
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);

webkit表单输入框placeholder如何修改颜色

css
input::-webkit-input-placeholder{
color: rgba()
}

禁止IOS长按时触发系统菜单

css
-webkit-touch-callout: none;
user-select: none;

布局方案

  1. 响应式布局:一套代码搞定多端,会造成性能变成,数据不多、用户量不大、纯展示类的适用
  2. 自适应布局:移动端使用

ES6

var、let、const

let定义变量,只在当前代码块中生效 var会变量提升,最终全局可用,let不会变量提升 var可以重复声明同一个变量,let不可以 const与let相同,但const为常量,定义之后不可修改,通常大写

箭头函数和普通函数的区别

  1. this指向
  2. 普通函数哪里调用指向哪里,可用call、apply、bind修改
  3. 箭头函数哪里创建指向哪里,且不可用call、apply、bind修改
  4. 箭头函数不能new,即不能当作构造函数
  5. 箭头函数没有prototype、arguments

Promise有几种状态

  1. pending(进行中)
  2. fulfilled(已成功)
  3. rejected(已失败)

find和filter的区别

  1. filter返回的是新数组;find是返回具体的内容,只返回第一个

some和every的区别

  1. some只要有一个满足条件就会返回true,every必须全部满足条件才返回true

变量的解构赋值

let [a, b, c] = [10, 20, 30]; => a=10, b=20, c=30 let {a, b} = {a: 10, b: 20}; => a=10, b=20 let [a, b, c] = 'hello'; => a='h', b='e', c='l'

字符串扩展

  • 模板字符串
  • includes:与indexOf相似,但返回布尔值
  • startsWith:文本是否在头部
  • endsWitdh:文本是否在尾部
  • repeat:将文本重复N次
  • padStart:往前补全N位数
  • padEnd:往后补全N位数
  • trim:去除前后空格
  • trimStart:去除前空格
  • trimEnd:去除后空格

箭头函数

  • 哪里定义指向那里,function,谁调用指向谁
  • 不能作为构造函数,即不可new
  • 箭头函数内部没有arguments对象

函数扩展

  • 函数参数的默认值
  • ...操作符:拆分或合并数组

数组扩展

  • Array.from:将两类对象转换为数组
  • Array.of:将一组数转换为数组
  • find:查找,返回满足条件的元素
  • findIndex:查找,返回满足条件的元素的下标
  • flat:扁平化数组,默认一层

对象扩展

  • for...on:可遍历数组和对象
  • Object.keys:获取对象的键
  • Object.Values:获取对象的值
  • Object.entries:获取对象的键值
  • Object.is:判断是否相等,主要用于解决==和==的问题
  • Object.assign:合并对象,浅拷贝

Class

  • 实际上仍是勾走函数,只是看起来更像面向对象
javascript
class 类名称{
constructor(形参){
// 指向构造函数
this.属性名 = 属性值
},
// 自定义方法
run(){}
}
let obj = new 类名称(实参)
  • 继承
javascript
class 子类 extends 父类{
    constructor(){
        super();
    }
}

Symbol

原始数据类型,防止变量名冲突

new Set()

对象,没有重复的值,可用于去重

Module

  • 引入:import
  1. 完全引入
  2. 按需引入
  3. 自定义名称
  • 抛出:export

Promise

  • 对象,异步编程的一种解决方案,写异步代码,同步方式执行
  • 三种状态:
  1. pending:进行中
  2. fulfilled:已成功
  3. rejected:已失败

async和await

  • 在函数前加async,函数将返回promise对象
  • await,需配合async使用,等待当前异步函数执行完成再执行后面的代码

fetch和mock

  • 不是ES6
  • ajax请求,优点:不需要额外下载依赖;缺点:对低版本浏览器不支持
  • 返回promise对象
javascript
fetch(url,{
method:'get|post',
params:{
// 请求参数
}
}).then(async res=>{
await res.json();// 将res转换为json格式,因是异步函数,因此要等待转换完成后再操作
});
  • fetch-mock:模拟数据,需下载插件

Git

Git常用命令

效果命令
下载git clone gitee/github上的项目链接
下载指定分支git clone -b 分支名称 gitee/github上的项目链接
克隆当前项目git pull
提交代码到中转站git add .(.为所有,也可以指定文件)
提交所有代码到本地仓库git commit -m "注释内容"
提交本地仓库到远程仓库git push
设置用户名git config --global user.name ""
设置邮箱git config --global user.email ""
初始化仓库git init
查看配置git config -l
查看状态git status,红色未被管理,绿色已管理
查看文件git diff 文件名(为空查看全部)
查看修改历史git log 文件名(为空查看全部)
查看修改历史[简单模式]git reflog
回到上一个的版本git reset --hard HEAD^
回到指定版本git reset --hard 版本号
创建/查看/删除分支git branch -d(可选,删除本地分支) 分支名(为空查看分支)-r(可选,查看远程仓库分支)
切换分支git checkout 分支名
本地分支提交到远程仓库git push --set-upstream origin 分支名称
删除远程仓库分支git push origin --delete 分支名
合并分支git merge 分支名(将指定分支与当前分支合并)

SVN和Git的区别

  1. SVN是集中式管理,Git是分布式管理
  2. SVN在断网时无法提交代码,Git在本地有一个服务,可以先提交在本地上,等待有网后再提交到远程仓库
  3. 相对来说Git速度更快

Gitflow

  • master:用于保存上线版本代码
  • develop:用于保存相对稳定版本的代码
  • feature:用于开发功能
  • release:用于代码上线前的准备(测试,bug修复)
  • bugfix:用于修复不紧急bug
  • hotfix:用于修复紧急bug

Vue

生命周期

  1. 有哪些生命周期
  • 默认有8个生命周期,加入keep-alive后有10个
  • beforeCreate:创建之前
  • created:创建之后
  • beforeMount:渲染之前
  • mounted:渲染之后
  • beforeUpdate:更新之前
  • updated:更新之后
  • beforeDestroy:销毁之前
  • destroyed:销毁之后
  • activated:进入
  • deactivated:离开
  1. 进入组件或页面,会执行哪些生命周期
  • beforeCreate
  • created
  • beforeMount
  • mounted
  1. 哪个阶段有$el,哪个阶段有$data
  • $data是组件的数据,$el是组件的根节点
  • 在created阶段有$data
  • 在mounted阶段有$el
  1. 加入keep-alive后,第一次进入页面,会执行哪些生命周期
  • beforeCreate
  • created
  • beforeMount
  • mounted
  • activated
  1. 加入keep-alive后,第2~N次,会执行哪些生命周期
  • activated

keep-alive

  1. 什么是keep-alive
  • vue系统自带的一个组件,用来缓存组件,提升性能
  1. 使用场景
  • 从列表页进入详情页,如果进入的是同一个详情页(数据未发生变化),需要多次向服务器发起请求,一方面会消耗服务器资源,另一方面也会降低应用的速度,此时加入keep-alive可以将页面缓存起来,如果进入的是同一个详情页,就不需要重复发起请求,如果进入的是不同的详情页,再重新发送请求

v-if和v-show的区别

  1. 展示形式不同
  • v-if是创建和删除节点
  • v-show是设置display
  1. 使用场景不同
  • 初次加载v-if性能比v-show好
  • 频繁切换v-show性能比v-if好

v-if和v-for的优先级

v-for优先级比v-if优先级高

ref是什么

用来获取dom的

nextTick是什么

获取更新后的dom内容

scoped原理

  1. 作用:让样式只在本组就中生效,在其他组件中不生效
  2. 原理:添加自定义属性,CSS选择器添加属性选择器

computed、methods、watch的区别

  1. computed是有缓存的,如果计算的属性没有发生变化,则执行缓存数据,methods没有
  2. computed是返回一个数据,当他内部的数据发生变化时触发,watch是数据或路由发生了改变才会执行
  3. computed的函数名就是返回结果,内部的才是监听的数据,watch的函数头是监听的数据

props和data的优先级

props ==> methods ==> data ==> computed ==> watch

Vue设置代理

javascript
// vue.config.js
module.exports {
devServer: {
proxy: '服务端地址'
}
}

打包完成后出现空白页

为什么会出现空白页

js、css等文件引入是/,改为./即可

javascript
// vue.config.js
module.exports {
publicPath: './'
}

路由模式

  1. history
  2. url不带#
  3. 每次跳转会发生一次请求
  4. 项目上线后端要设置重定向
  5. hash
  6. url带#
  7. 跳转不发生请求
  8. 前端测试一般使用hash,使用history可能会出现空白页

模式和环境变量

开发环境

新建文件.env.development

生产环境

新建文件.env.production

SPA

是什么

单页面应用

缺点

  1. SEO优化不好,解决,服务器预渲染等
  2. 性能不是特别好

路径传值

javascript
// 发送方
// 显示
this.$router.push({
path: '',
query: {
xxx:'',
}
})
// 隐式
this.$router.push({
name: '',
params: {
xxx:'',
}
})
javascript
// 接收方
// 显示
this.$route.query.xxx
// 隐式
this.$route.params.xxx

导航守卫有哪些

全局

  1. beforeEach
  2. beforeResolve
  3. afterEach

路由独享

  1. beforeEnter

组件内

  1. beforeRouteEnter
  2. beforeRouteUpdate
  3. beforeRouteLeave

动态路由

路由内的children

双向绑定原理

通过Object.defineProperty劫持数据发生的改变,如果数据发生了改变,触发update方法进行更新节点内容,从而实现了数据双向绑定

diff算法

功能

  1. 提升性能

新老节点替换规则

  1. 如果新老节点不是同一个节点,则直接删除旧的节点,创建插入新的节点
  2. 只能同级比较,不能跨层比较

实现方法

  1. 如果是不同的节点,删除旧节点添加新节点
  2. 如果是相同的节点
  3. 新节点没有children(即新节点是文本节点),直接替换文本
  4. 新节点有children
  5. 旧的有children(diff算法的核心,最难的)
  6. 旧前新前
  7. 旧后新后
  8. 旧前新后
  9. 旧后新前
  10. 以上都不满足
  11. 创建或删除
  12. 旧的没有children,删除旧的,创建元素添加新的

虚拟dom

把dom数据化

什么是MVVM

MVVM分为M(model)、V(view)、VM(ViewModel) model是数据(data里的数据) view是页面(template里的dom) ViewModel是解析器(就是vue的源码)

Vuex

  • state:存放数据
  • getters:相当于计算属性
  • mutations:存放方法,用于直接修改state,是同步的
  • actions:存放方法,无法直接修改state,而是提交mutations,即调用mutations内的方法,可包含任意的异步操作
  • modules:将state, getters, mutations, actions分成多个模块

uni-app

生命周期

应用生命周期

只存在与App.vue

函数名说明
onLaunch当uni-app初始化完成时触发,只触发一次
onShow当uni-app启动或从后台进入前台
onHide当uni-app从前台进入后台
onError当uni-app报错时触发

页面生命周期

pages下的页面都存在

函数名说明
onLoad当页面初始化完成时触发,只触发一次
onShow当页面显示时
onHide当页面隐藏时
onReady当页面完全加载完毕时
onUnload当页面卸载时

组件生命周期

只存在与组件(compoments)中,与vue相同,但没有keep-alive

条件编译

html
<!-- #ifdef 平台 -->
<!-- #endif -->

微信小程序

如何自定义头部

js
// app.json
"window":{
"navigationStyle":"custom",// default为默认,custom为自定义,设置为custom将仅保留两个胶囊按钮
}

如何自定义底部

不配置tabbar即可

不校验URL

工具 --> 详情 --> 本地设置 --> 勾上不校验合法域名(项目上线前需要取消勾选)

性能优化

Vue性能优化

  1. 使用keep-alive缓存组件
  2. 路由懒加载(二级页面可以使用懒加载)
  3. 合理运用v-if和v-show、computed、watch、methods
  4. Object.freeze(冻结对象,纯展示类的接口数据,冻结即可)
  5. 使用UI组件按需引入

加载优化

  1. http请求(尽可能合并)
  2. 小图标 --> 雪碧图
  3. script延迟加载
  4. link引入

图片优化

  1. 雪碧图
  2. 响应式图片(img中的srcset)
  3. 使用webp格式
  4. 懒加载
  5. 小图标可以改用字体图标

渲染优化

  1. 减少重绘回流(触发回流必定触发重绘,触发重绘不一定触发回流)
  2. 用变量缓存dom样式,不要频繁读取
  3. 动画元素使用absolute,脱离文档,不影响其他元素,使用transform,减少使用left等
  4. 动画尽量使用requestAnimationFrame,减少使用定时器

首屏优化

  1. 懒加载
  2. 长列表(先放一部分,触底后再放一部分)
  3. 项目文件的压缩打包

webpack相关

  1. 不生成.map
javascript
// vue.config.js
module.exports = {
productionSourcMap: false, // 不生成.map
}
  1. 路由分包,若不分包则所有页面操作都打包在app.js,home必在app.js中
javascript
// router/index.js
const routes = [
{
path: "",
name: "",
compoent: () => import(/* webpackChunkName: "xxx" */) // 将该页面打包为xxx.js
}
]
  1. vendors.js分包(项目中的依赖包)
  2. UI框架的按需引入,使用插件babel-plugin-component(element-ui)、babel-plugin-import(vant)

兼容

  1. IOS键盘首字母大写
  2. input添加autocapitalize="off"
  3. IOS日期转换为NAN
  4. 日期使用斜杆分割
  5. 移动端click事件300ms延迟
  6. 禁止缩放
  7. fastclick.js
  8. 移动端touch事件穿透
  9. 阻止默认行为
  10. fastclick.js
  11. 移动端键盘遮挡底部
  12. 弹出键盘后将底部抬起
  13. 安卓input的placeholder偏上
  14. 添加样式line-height: normal;
  15. HTML5标签兼容低版本浏览器
  16. 使用html5shiv.js

网络请求

跨域

前端

  1. jsonp
  2. vue项目设置代理

后端

  1. cors

http和https的区别

  1. http是80端口,https是443端口
  2. https比http安全,https需要安全证书

web安全

xss攻击

是什么

执行一些js代码

解决

使用正则,将<>等进行转换

sql注入

是什么

传递sql语法以获取数据库信息

解决

使用正则过滤,禁止输入框中有特殊符号

接口安全

做加密

其他

token

  1. token + cookie:前端判断是否过期
  2. token + localStorage:后端判断是否过期(返回code码,前端判断code码)

SEO

  1. 网站一定要多页面
  2. title、描述、关键字很重要
  3. 图片、视频、音频的标签属性特别关键
  4. 网站不能出现死链接

混入和vuex的区别

如何修改computed中的数据

在computed中设置get和set

腾讯IM的接入步骤

  1. 下载引用依赖,还有demo包,将demo包中的debug包复制到项目中,用于生成userSig
  2. 在GenerateTestUserSig.js中配置key和密钥
  3. 在客服页面的created钩子中获取当前用户ID并生成userSig,添加接收事件
  4. 添加点击发送按钮的发送事件
  5. 将历史记录存储在localStorage中,用于读取

uni-app如何区分IOS和安卓

uni-app自带getSystemInfo