目录
html&css
w3c标准
万维网联盟标准是一些列标准的集合,分为结构(html)、表现(css)和行为(js和dom)
w3c提出了规范化的要求
1)标签和属性名字母要小写
2)标签要闭合
3)标签不允许随意嵌套
4)尽量使用外链css样式表和js脚本。让结构、表现和行为分为三块,符合规范。同时提高页面渲染速度,提高用户的体验。
5)样式尽量少用行间样式表,使结构与表现分离
6)标签的id和class等属性命名要做到见文知义,更利于seo,代码便于维护
7)使用注释:正确的应用等号或者空格替换内部的虚线。<!--这里是注释============这里是注释-->
8)所有属性值必须用引号括起来(”” ”)双引号或单引号
9)CSS必须要用<style type=“text/css”>开头来定义,为保证各浏览器的兼容性,在写CSS时请都写上数量单位,例如:错误:.space_10{padding-left:10} 正确:.space_10 {padding-left:10px}
10)需要声明(DOCTYPE)
ECMAScript
是 JavaScript 的核心语言规范,描述了 JavaScript 的语言语法、类型、语句、关键字、保留字、运算符、对象等基本特性
CommonJS
是JS社区在2009年提出的一系列标准的统称,其中包含了模块、文件、IO、控制台等标准。日常工作中所说的CommonJS实际上是指Node.js中实现的版本,不是它的原始定义。CommonJS中规定每个文件是一个模块。模块化开发
主要使用模块化的导入导出功能
导出:export xxxx export{ xxxx,xxxx,xxx}
默认导出:export default xxxx
一个文件只能有一个默认导出
导入:import xxx form url
h5特性
语义化标签、音视频、图形绘画、本地存储
本地存储
localStorage-没有时间限制,sessionStorage-session 关闭浏览器窗口数据删除
flex布局(弹性盒布局)
可以根据父元素的大小自动调整自身的尺寸和位置
在F12内使用,调整多个元素水平或垂直居中、平分父元素空间、排列方向等操作。
js基础
闭包
闭包有三个特性:
1.函数嵌套函数
2.函数内部可以引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
释放闭包:闭包所在变量设置为null
同步异步
同步:
从上往下按顺序依次执行
只有将一个任务完全执行完后, 才执行后面的
会阻塞后面的代码执行
异步
启动任务后, 立即向下继续执行, 等同步代码执行完后才执行回调函数
不会阻塞后面的代码执行
异步回调函数会即使触发了, 也是要先放入队列中待执行, 只有当同步任务或前面的异步任务执
行完才执行
作用域
作用域
一个变量可以合法使用的范围/区域
作用域起到了隔离变量, 避免了变量重名冲突的问题(也就是允许了不同作用域中可以有同名的
变量)
分类:
全局作用域
函数作用域
块作用域 => ES6的let或const变量
作用域链
多个嵌套的作用域形成的由内向外的结构, 用于查找变量
当查找一个变量, 在整个作用域链中都找不到时: 会报引用错误, 错误信息为这个变量没有定义
原型原型链
原型
每个函数都有一个显式原型属性: prototype
每个实例都有一个隐式原型属性: proto
实例的 proto 与对应函数的 prototype 都指向原型对象
函数的默认的原型对象是Object的实例, 也就是一个{}
原型对象上有一个 constructor 属性指向对应的构造函数
显示原型与隐式原型
原型链
从对象的 proto 开始, 连接的所有对象。也可称为“隐式原型链”
原型链的作用:
在查找对象属性或调用对象方法时, 会先在对象自身上查找, 找不到就会沿着原型链查
找
利用原型链可以实现继承
深拷贝
使用第三方库lodash中的cloneDeep()方法
使用递归方式实现
function copy(obj) {
// 创建一个空对象用来拷贝之后的内容
let newObj = {}
//判断数据是否为 复杂数据类型
if (typeof obj === 'object') {
// 是 就将该数据进行 遍历
for (let k in obj) {
// 当 obj[k] 的值依然为 复杂数据类型时 重新调用该函数
// 将obj[k] 当实参 进行调用 直至 obj[k] 的值不在为 复杂数据类型
newObj[k] = copy(obj[k])
}
} else {
newObj = obj
}
return newObj
let newArr = [];
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
newArr.push(copy(arr[i]));
} else if (typeof arr[i] === 'object' && arr[i] !== null) {
newArr.push(copy(arr[i]));
} else {
newArr.push(arr[i]);
}
}
// 将 copy 的对象返回出去
return newArr
}
es6
解构赋值
- 解构对象: let {x, y} = {x: 1, y: 2};
- 解构数组: let [a, b, c] = [1, 2, 3];
- 可以使用别名:let {x: aliasX, y: aliasY} = {x: 1, y: 2};
- 引入模块解构: import { getProductList } from '@/api'
箭头函数
- 没有自己的this, 使用外部作用域中的this, 不能通过bind来绑定this***
- 不能通过new来创建实例对象
- ***内部没有arguments, 可以通过rest参数来代替
promise
Promise有三种状态,pending(等待状态),fulfilled(成功状态),rejected(失败状态)。
Promise还有state属性和result属性,state值是当前状态值,result值是当前结果值。
then
传两个参数 ,成功和失败。可以链式调用,只有返回失败promise和抛出错误会执行链式失败
catch
捕获上层未能捕获到的错误
all
接受promise数组作为参数,所有promise都是成功时才返回成功promise,内容是成功promise结果的数组,否则返回失败的,内容是第一个失败的值
async/await
解决异步的最终方案
async声明这是异步函数,返回promise对象
await会阻止后续代码,等待右侧promise对象结果
缺点:滥用 await 可能会导致性能问题,因为 await 会阻塞代码
async function test2() {
const result = await test();
console.log(result);
}
数组函数
一、改变原数组的方法 1.push() 末尾添加数据 2. pop() 末尾出删除数据 3.unshift() 头部添加数据 4.shift() 头部删除数据 5.reverse() 翻转数组 6.sort() 排序 7.splice() 截取数组 二、不改变原数组的方法 1.concat() 合并数组 2.join() 数组转字符串 3.slice()截取数组的一部分数据 4.indexOf 从左检查数组中有没有这个数值 5.lastIndexOf 从右检查数组中有没有这个数值 三、ES6新增的数组方法
- forEach() 用来循环遍历的 for 2.map 映射数组的 3.filter 过滤数组 4.every 判断数组是不是满足所有条件 5.some() 数组中有没有满足条件的 6.find()用来获取数组中满足条件的第一个数据 7.reduce()叠加后的效果
字符串函数
1.str.charAt()下标查找,根据下标参数查找对应的字符,没取到则是空字符串
2.str.indexOf()根据指定字符串查询对应的索引,返回索引值或-1
3.#### str.slice()字符串截取(开始的位置,结束的位置(不包括))
4.#### str.substr()也是截取字符串,(开始位置,返回字符串的个数)
5.#### str.split()分割字符,碰到参数字符就分割,返回数组
6.#### str.concat()拼接字符,把参数拼接到str后边
7.#### str.replace(旧内容,新内容)字符串替换,识别到旧内容并替换成新内容
vue相关
常用指令
v-show、v-if / v-else、v-for、v-on简写@、v-model简写:
监听和计算属性
计算属性必须同步返回计算结果, 而watch中可以在异步操作后更新数据显示
watch可以深度监视, 计算属性只是监视了使用到的数据
生命周期
初始阶段: mounted: VM挂载完毕会执行一次 beforeCreate:所有生命周期函数中最先执行的 在VM未完成初始化时执行,获取不了VM属性、方法 created: VM初始化完毕时执行,可以获取属性方法 beforeMount: VM挂载之前执行,可以获取VM的属性/方法,但获取不到真实DOM节点 更新阶段: beforUpdate: 响应式数据发生变化时触发一次 updated: 响应式数据发生变化之后触发一次 销毁阶段: 可以看到VM,但VM不工作了 beforeDestroy:VM销毁之前执行 destroyed:VM销毁之后执行,进行收尾工作
防抖节流
节流:
在时间内,不管触发几次,都只执行一次
应用:页面滚动,请求按钮
实现:
函数内设置布尔变量为true,if判断buer,触发事件,改变布尔值为false,设置定时器(多少时间后改变布尔值为true),
防抖:
事件触发后延迟执行,如果延迟期间有新触发,就重新计算
应用:实时搜索,拖拽
实现:
函数内用if判断,如果函数已经有执行的定时器的话,就把它清除掉。
函数添加定时器,内部调用函数,调用后删除定时器标记
响应式数据原理
对象: 通过Object.defineProperty()添加setter方法来监视属性数据的改变 + 订阅-发布
数组: 重写更新数组元素的一系列方法 + 订阅-发布
调用原生的对应对数组元素进行相应的操作
更新界面去
双向数据绑定原理
将动态的data数据通过value属性传给input显示 ==> data到view的绑定
给input标签绑定input监听, 一旦输入改变读取最新的值保存到data对应的属性上 ==> view到data的绑定
组件通信
- 父向子
v-model传递,props接收
¥refs
是一个对象,在组件或dom标签内添加ref使用,子组件中使用 ref属性,会将其添加到父组件的$refs对象中。
父组件通过this.¥refs.属性名.函数
- 子向父
vue自定义事件
¥emit(自定义事件)
this.¥emit(父组件函数,数据)
父组件给子组件传参时添加.sync修饰符,子组件通过this.¥emit(updata:参数名,新值)传回父组件
-
3.兄弟或其它/任意
全局事件总线bus
在入口文件创建vue实例作为bus,把bus挂在到vue原型上
Vue.prototype.$bus= bus; //发送事件 this.$bus.$emit('eventName', data); //接受事件 this.$bus.$on('eventName', (data) => { // 处理事件 } // 组件销毁前取消事件监听,避免内存泄露 this.$bus.$off('eventName'););
Vuex
xuex
const store = new Vuex.Store({ modules: { cart: {//模块 state: {//存放数据的地方 items: [] }, mutations: {/同步修改state数据 pushProductToCart (state, payload) { state.items.push({ id: payload.id, quantity: 1 }) } }, actions: {//异步操作和提交mutations addProductToCart ({ state, commit }, product) { const cartItem = state.items.find(item => item.id === product.id) if (!cartItem) { commit('pushProductToCart', product) } } }, getters: {//对state中的数据进行计算处理,相当于计算属性 cartItems: state => { return state.items } } } } }) 这个代码创建了一个包含cart模块的Vuex store对象,其中cart模块包含state、mutations、actions和getters四个属性,用于管理购物车数据。在addProductToCart action中,使用state.items和commit方法来修改cart模块中的数据。在cartItems getter中,使用state.items来计算购物车中的商品数量和总价。 组件中使用 this.$store.state.属性名 this.$store.setters.计算属性名 this.$store.commit('同步函数名') this.$store.dispatch('异步函数名')
vue路由
¥router是用于做编程式导航的(改变路由的);¥route是获取路由信息的。
路由导航
路由导航,它默认会被渲染成一个带有链接的a标签,通过to属性指定链接地址 <router-link to="/xxx">xxxx</router-link> 编程式导航 this.$router.push({ path:'路由路径', query:{name:'xxx'}//git传参 }) this.$router.push({ name:'路由名字', params:{name:'xxx'}//post传参 }) this.$route.params接收参数
路由配置文件
路由配置文件 [ { path:'/',//路径地址 name:'xxx', component:()=>import("@/App.vue"),//跳转到对应组件 children:[//子路由 // { // path:'topics', // component:()=>import("@/views/topics"), // }, ] }, ]
路由重定向,path地址访问根目录或者无效地址时跳转首页使用
动态路由,根据路由传参,在目的地读取参数并使用
优化
v-for 遍历列表
指定非下标的唯一key, 尽量不用index, 如果只用于展示就没关系
v-if和v-show按需使用
路由组件懒加载 ==> 预加载
第三方插件的按需引入打包
对高频事件进行节流或防抖处理
及时销毁事件监听
网络
跨域
同源策略
vue处理跨域vue.config.js
devServer下proxy里配置,target是代理跨域目标接口、changeOrigin是否改变请求的源地址、pathRewrite重写请求的路径
ajax
浏览器不会对界面进行任何更新操作, 只是调用监视的回调函数并传入响应相关数据
/* xhr + promise 封装一个异步ajax请求的通用函数 简洁版 */ function ajax(url) { return new Promise((resolve, reject) => { // 创建一个XHR对象 const xhr = new XMLHttpRequest() // 初始化一个异步请求(还没发请求) xhr.open('GET', url, true) xhr.onreadystatechange = function () { /* ajax引擎得到响应数据后 将xhr的readyState属性指定为4 将响应数据保存在response / responseText属性上 调用此回调函数 */ // 如果状态值不为4, 直接结束(请求还没有结束) if (xhr.readyState !== 4) { return } // 如果响应码在200~~299之间, 说明请求都是成功的 if (xhr.status>=200 && xhr.status<300) { // 指定promise成功及结果值 resolve(JSON.parse(xhr.responseText)) } else { // 请求失败了 // 指定promise失败及结果值 reject(new Error('request error staus '+ request.status)) } } xhr.send(null) }) }
axios
axios.get(url, {配置}) axios.post(url, data, {配置}) axios.put(url, data, {配置}) axios.delete(url, {配置})
axios二次封装
配置请求响应拦截器,请求拦截器里请求头携带token,相应拦截器里分开处理成功和失败回调,成功返回data,失败返回报错信息,token过期跳转登录
api接口
接口名(参数){ return axios({ url:'xxxxx'+参数 methon:get data:参数 }) }
echarts
title标题 series根据type设置图表类型并配置渲染样式
git指令
Sourcetree可视化提交代码
查看分支:git branch
创建分支:git branch 分支名
切换分支:git checkout 分支名
工作区提交到暂存区:git add
将更改添加到本地存储库的必要命令:git commit -m描述信息
将本地代码推送到远程仓库:git push
从远程仓库拉取最新代码并合并到本地分支:git pull
MVVM和mvc
-
state:存放数据的地方
-
getters对state中的数据进行计算处理,相当于计算属性
-
mutations同步修改state数据
-
actions异步操作和提交mutations,负责api数据接入处理,接受context作为第一个参数,包含了state、getters和commit。不能对satate修改,但可以通过commit通知mutations修改
-
modules将store模块化,每个模块都有自己的仓库
- 同源: 协议, 域名, 端口, 三者都相同
- ajax请求时, 浏览器要求当前网页和服务器必须同源(安全), 否则会抛出跨域的错误
- 加载image/link/script不受同源策略限制
-
配置通用的基础路径和超时
-
显示请求进度条
- 显示进度条: 请求拦截器回调
- 结束进度条: 响应拦截器回调
-
成功返回的数据不再是response, 而直接是响应体数据response.data
-
统一处理请求错误, 具体请求也可以选择处理或不处理
-
每个请求自动携带userTempId的请求头: 在请求拦截器中实现
-
如果当前有token, 自动携带token的请求头
-
对token过期的错误进行处理
-
MVVM
将后端数据转化成页面内容:数据绑定
将页面内容转化成后端数据:dom事件监听、双向绑定
MVC
区别
Webpack
打包用的
Webpack
本身只能处理JavaScript
模块,但通过加载器(Loader)
的使用,可以将其他类型的文件(如CSS、LESS、图片等)转换为有效的模块,使其能够被打包到最终的结果中。
Webpack的核心概念包括entry(入口)、output(输出)、loader(加载器)和plugin(插件)。
- entry指定Webpack的入口文件
- output定义打包输出的文件及路径
- loader用于处理不同类型的文件
- plugin用于扩展Webpack的功能
-
Entry(入口):Webpack将从指定的入口文件开始分析和构建依赖关系树。入口可以是单个文件或多个文件,Webpack会根据入口配置找出所有的依赖模块。
-
Output(输出):指定Webpack打包后的文件输出的路径和文件名。可以通过配置
output
选项来指定输出文件的路径、名称和格式等。 -
Loader(加载器):
Webpack
本身只能处理JavaScript
模块,但通过Loader
的使用,可以处理其他类型的文件(如CSS、LESS、图片等)。Loader的作用是在模块加载时对其进行转换和处理。 -
Plugin(插件):插件用于扩展Webpack的功能。它可以在打包的不同阶段执行特定的任务。例如,可以使用插件来压缩代码、拆分代码、生成HTML文件等。插件通过在Webpack配置中引入并实例化,然后将其添加到plugins数组中。
Webpack的loader是用于处理模块文件的转换工具。
它们可以将不同类型的文件(如CSS、LESS、图片等)转换为可以被Webpack处理的有效模块,以便将其包含在最终的打包结果中。
babel-loader
:将ES6+代码转换为ES5语法,以便在旧版本的浏览器中运行。style-loader
和css-loader
:用于处理CSS文件。css-loader主要负责处理样式文件中的import
和url
语句,而style-loader将转换后的CSS模块直接注入到HTML页面中。sass-loader
和less-loader
:用于处理Sass和Less预处理器。它们将Sass和Less代码转换为普通的CSS代码。html-loader
:用于处理HTML文件,将其中的图片等资源转换为Webpack可以识别的模块。
在Webpack中,插件(plugin)是用来扩展和定制构建过程的工具,可以用于处理和优化资源、自动化任务、注入变量等。
TerserWebpackPlugin
:用于对JS代码进行压缩和混淆,减小文件体积,提高加载速度。
移动端兼容和适配
页面适配
媒体查询:比较麻烦,需要在每个页面上写媒体查询的代码
百分比布局:使用百分比单位设置元素的宽度、高度和边距等。这样可以根据父元素的尺寸自动调整子元素的大小,实现一定程度的自适应效果。因为不同属性的百分比值,相对的可能是不同的参照物,所以百分比往往很难统一,在移动端适配中使用是非常少的。
弹性盒子(flex)布局
使用CSS3弹性盒子布局模型,通过设置弹性容器和弹性项目的属性,实现灵活的布局。弹性盒子布局可以根据容器的尺寸和内容的大小,自动调整项目的 布局和排列。
rem单位 + 动态的font-size
是CSS3新增的一个相对单位,是指相对于根元素的字体大小的单位。flexible 的原理就是这个。
使用rem(根元素字体大小的倍数)作为单位来设置元素的尺寸。通过设置根元素的字体大小,可以控制整个页面的缩放比例,从而实现不同设备的适配。
vw、vh
是css3中提出来的,基于视图窗口的单位。将视觉视口宽度 window.innerWidth和视觉视口高度 window.innerHeight 等分为 100 份。
需要做单位转化,而且px转换成vw不一定能完全整除,因此有一定的像素差。可以使用less或者scss进行换算,也可以在webpack解析css 的时候用postcss-loader 有个postcss-px-to-viewport插件能自动实现px到vw的转化