目录
- vue原理
- ES6、ESNext
- HTML5
- CSS3
1.vue实现原理
vue是一个数据驱动的渐进性框架,采用数据劫持 结合发布者-订阅者 模式的方式,通过Object.defineProperty()来劫持各个属性的setter和getter。数据变动时,发布消息给订阅者,触发相应的回调函数。
vue是一个MVVM模式的双向数据绑定,实现方式是通过:
1.监听器Observer: 对数据对象的属性进行监听,变动就通过getter方法获取最新值,通知订阅者。
2.解析器Compile:对元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定响应的更新函数
3.观察者Watcher:是数据的监听器和元素节点的解析器的桥梁,能订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数。订阅者本身有update从而更新视图。
在自身实例化时,往订阅器Dep里添加自己;自身必须有一个update方法;属性变动,则订阅器Dep.notify()通知watcher时,调用自己的是update方法,同时触发解析器Compile里绑定的回调函数
4.订阅器Dep:是一个对象,用来维护数组,里面有notify方法,
data进行递归遍历,包括子属性对象的属性,
Object.defineProperty(data,key,{
enumerable:true //可枚举
configurable:false //属性可否改变,false即不可删除
set(){ //派发更新
Dep.notify()
watcher.update()
nextTick()
updateComponent()
}
get(){} //订阅器,收集依赖
})
vue生命周期:创建前后、载入前后、更新前后、销毁前后,有keep-alive的话会多两个:activated,deactived
created和mounted的区别:
created是在模板渲染成HTML之前调用,数据初始化,浏览器解析HTML文件,渲染DOM、CSSOM和解析js文件,还没有进入render阶段,实例被初始化,还未挂载到$el上,所以无法获取对应的节点,对节点操作会报错。
mounted是在模板渲染成HTMl之后调用,实例挂载完成,可以访问DOM节点并可对节点进行操作。
2.ES6、ESNext
ES6
1.类(class)
(1)代替了之前的构造函数function Man(){},更抽象面向对象,减少代码冗余
(2)类必定有一个constructor方法,在第一行,没有定义就默认是空的constructor,方法之间不能逗号
(3)extends关键字实现继承,super调用父类的constructor构造函数
(4)类里有static关键字表示该方法是静态方法,不能被实例继承,只能通过类调用
2.模块化(ES Module),即公共方法export导出,具体vue里import导入
export function sun(){}
import {sun} from './A'
3.箭头函数:没有this const func = (a,b) => a+b;
4.函数参数默认值,查询默认第一页
5.模板字符串,有动态变量的文本,`name is ${x}`
6.解构赋值,排序的左右互换位置,[a,b]=[b,a]
7.扩展操作符 比如,apply方法 Math.max(null,...[1,2,3,4,6,8])
8.对象属性简写:入参data,形参里有id,data = {id} 不用写成键值对的形式,前提是入参data的key是id
9.Promise Promise.resolve().then().catch()
10.let const
ES7:Array.prototype.includes() 数组查询
ES8:async/await 解决两个页面的操作 async function (){ const res = await _api()}
ES9:Promise.finally() 用来解决关闭loading,不管当前请求是resolve还是reject都要强制关闭loading
ES10:flat() 数组扁平化 ElementUI里的联级选择器,每次勾选获得的都是数组,可以扁平化二维数组
ES11:新基本数据类型BigInt 任意精度的整数,解决整数溢出问题± 2`53-1范围,大整数运算 10n 加个n
ES12:Promise.any() 获取最先返回的promise对象
3.HTML5
语义化标签、input的type类型以及属性、audio/vedio、canvas、svg、拖放API(draggable 属性设置为true,drag拖动是触发。drop放置时触发)、地理定位Geolocaltion、webWorker(多线程)、webStorage、webSocket(长连接,长轮询)
4.CSS
1.rem:相对长度单位,基于根元素HTML。基于主流浏览器默认字体font-size是16px
使用方法:
(1)html{font-size:625%} 便于计算,1rem=100px;解决chrome强制最小字体12px
(2)@media screen and (min-width) and (max-width){font-size:703%} 设置媒体查询
(3)引入flexible,cssrem,基于iPhone6做适配
2.垂直水平居中:
(1)CSS2:定位 + margin auto :父级position:relative,子:position:absolute;left,right,top,bottom为0,margin:auto 或者 transform:translate(-50%,-50%)
(2)CSS3:flex 父级设置display:flex;align-items:center;justify-content: center;
3.两栏布局:
(1)CSS2:父级BFC,左float:left,定宽,右边margin-left:左宽
(2)CSS3:flex布局,父级display:flex;左定宽,右flex:1
4.三栏布局:
(1)CSS2:两边float,中间margin,父级BFC,左边左浮动,右边右浮动;两边absolute,且top为0,左left为0,右right为0,中间margin;table布局,父级设display:table,子设table-cell,左右定宽,中width:100%;
(2)CSS3:flex布局,父级设display:flex;左右定宽,中间flex:1
5.原型
原型、构造函数、实例
1.每个对象都有__proto__,通过object.__proto__就可以访问对象的原型。只有浏览器里才有,object.__proto__ === 原型
2.每个对象都有prototype,原来**继承**对象的属性。 prototype.constructor === 构造函数
3.通过new一个构造函数,就创建了一个对象的实例
4.每个构造函数都有一个constructor方法,实例.constructor === 构造函数 ,指向构造函数
原型链
每个对象都有原型,通过__proto__可指向创建该对象的构造函数的原型,连接起来就组成了原型链。
从而可以实现继承和共享属性。
属性查找:沿着原型链向上查找,知道Object.prototype 就可以用Object上面的方法,比如instanceof、hasOwnProperty
属性修改:只会修改实例对象本身的属性,原型上的不会修改
6.权限怎么做的
四个方面:接口权限、按钮权限、菜单权限、路由权限
1.接口权限:项目是基于OA系统的单点登录,所以是采用JWT(JSON Web Token)的方式来验证,oa进来,获取临时token发给后端验证,通过后返给我本系统的接口token,放在vuex和session中,在拦截器request里添加请求头Access-token,设置每个请求都加上token。
JWT方式安全的原因是,JWT分为header、payload、signatur;
JWT的header头部有两部分信息:声明类型和加密算法=>{typ:'JWT',alg:HAS256} base64加密。
JWT的payload载荷存放有效信息,标准注册的声明、公共声明、私有声明
JWT的signature签证有三部分信息:base64后的header、payload和secret。
JWT安全的根本就在于secret存放在服务端的,它是JWT的签发和验证,服务端的私钥。
2.路由权限:初始化挂载不需要权限控制的路由,登录页,404,登录后,获取用户权限信息,然后动态添加路由到全局路由守卫,router.beforeEach((to,from,next)=>{})
3.菜单权限:菜单和路由分离,前端定义路由信息,后端返回菜单信息。
要求后端的菜单信息的name值和前端路由信息的name值一致。获取用户信息后,将用户有权限的菜单信息添加到addRoutes动态挂载。如果有的页面没有权限访问,会跳到404.
4.按钮权限:通过自定义指令进行权限判断,就是配置路由时,在meta里添加对应的用户身份,比如admin,normal、super。然后在自定义指令组件里写一个v-has的指令,遍历meta里的身份信息数组,进行判断。
我们是由于太复杂,后面全部改成前端判断,因为根据身份信息还是不能区分按钮的访问权限,还要结合当前的状态。我们有大的类型和几百个状态。
7.项目目录
components //全局公共组件
config //环境变量配置,axios封装,增加请求拦截器和响应拦截器
utils //工具函数、常用配置
assets //资源目录,会被webpack构建
store //vuex仓库 state.js/ mutation.js / getter.js /actions.js
styles //样式统一配置 包括重置样式文件、全局通用样式、媒体查询样式
router //vue-router 动态路由配置 路由权限控制
views/pages //多页面vue项目的实例
static //纯静态资源,不会被webpack编译构建,比如iconfont.css、图片
app.vue //根组件
main.js //入口js文件
index.html //入口页面
package.json //项目需要的各种模块以及配置信息
package-lock.json //记录当前状态下实际安装的npm package的具体来源和版本号
8.13种vue修饰符
.lazy修饰符 双向数据绑定不起作用,光标离开输入框时值才改变
.trim修饰符 过滤掉输入框前后的空格
.number修饰符 将值转换成数值
.stop修饰符 阻止冒泡
.native修饰符 自定义组件上的@click可执行
.sync修饰符 子组件想要改变父组件的值 this.$emit('update:foo',newValue) :foo.sync="bar"
.prevent修饰符 阻止默认事件,如a标签 <a href="#" @click.prevent="toDo"> 表单的提交
.once修饰符 事件只执行一次 @click.once="xx"
.capture修饰符 改变事件冒泡的方向,变成由外向内 @click.captrue="xx" 冒泡机制:捕获-目标-冒泡
.self修饰符 只有点击绑定的事件才触发
.left/.right/.middle修饰符 鼠标左右中按键事件
.passive修饰符 给移动端onscroll事件加了一个lazy懒加载的功能
.camel修饰符 svg的驼峰识别修饰符 <svg :viewBox.camel="viewBox"> 区分大小写
.keyCode修饰符 键盘事件 普通健:enter、tab、delete、space、up、down、left、right。系统健:ctrl、alt、shift
.exact修饰符 只限制系统修饰健
修饰符可以同时使用多个,从左往右判断,如:@click.prevent.self阻止所有点击。。@click.self.prevent 阻止自身的点击
9.vue指令
v-text 解析文本
v-html 解析html标签
v-on 绑定事件
v-model input数据双向绑定
v-bind :class 三种绑定方式:1.对象型:class="{red:isRed}" 2.三目型:class="isRed : 'red' : 'blue'" 3.数组型:class="[{isRed:'red'},{blue:'isBlue'}]"
v-pre 跳过元素编译,加快编译
v-cloak 解决屏幕闪动问题,实例关联结束时进行编译
v-if 节点的构建与销毁
v-show 切换display的值
v-for 循环
v-once 只渲染一次的事件
10. vue组件通信,8种
1.父子组件传值:3种。
props和$emit:父组件通过props将值传给子组件,子组件通过this.$emit('方法名',newValue)转给父组件
$parents和$children:this.$children[0]获到子组件的值,是个数组。this.$parents获到父组件的值,是个对象。
this.$refs.xxx可以调用子组件上的所有方法。
2.隔代组件传值:provide和inject。祖组件provide提供值,子或孙组件通过inject来获取。
3.eventBus事件总线。 eventBus.$emit('addition',value)发送事件,EventBus.$on('addition',additionValue)接收事件。EventBus.$off('addition')移除事件。
4.vuex: state、getter、mutations、actions、modules
5.sessionStorage/localStorage:使用JSON.parse()和JSON.stringfy()。
6.$attrs和$listeners,通过inheritAttrs的false,可以关闭自动挂载在根元素上没有在props里声明的属性。
11.同源策略
定义:协议、域名、端口号三者相同就是同源。
一个完整的域名:
http: www. abc.com/ 8080/ a.js
协议 子域名 主域名 端口号 请求资源地址
同源策略限制的内容:
1.Cookie、localStorage、IndexedDB等存储性内容。
2.DOM节点。
3.AJAX请求发送后被浏览器拦截的资源。
允许跨域加载资源的三个标签:<img src="xxx"/>、<link href="xxx" />、<script src="xxx" />
跨域是AJAX请求能正常发送,服务器能收到请求并正常返回,只是被浏览器拦截了。所以跨域不能阻止CSRF。
解决跨域:
1.JSONP。利用<script src="xx">标签的可跨域。
JSONP方法的优点:兼容性好
JSONP方法的缺点:仅支持get方法有局限性。不安全有可能遭受XSS攻击。
2.CORS
服务器端设置Access-Control-Allow-Origin 为*。
3.PostMessage:实现多窗口、iframe跨域消息传递。它是HTML5的一个xmlHttpRequest2中的API。
4.Node中间件代理,服务器没有同源策略。
5.Nginx反向代理
6.window.name + iframe
7.location.hash + iframe
8.document.domain + iframe
9.websocket 利用webSocket.io HTML5的一种持久性连接的跨域解决方案
12.红黑树
基于二叉查找树(BST)
二叉查找树的3条基本规则:
1.左子树上所有节点的值都小于等于根节点的值
2.右子树上所有节点的值都大于等于根节点的值
3.左右子树也分别为二叉排序树
为了解决二叉树插入节点导致的不平衡,就有了红黑树
红黑树的五个特征:
1.节点是红色或黑色
2.根节点是黑色
3.每个叶子节点都是黑色的空节点
4.每个红色的两个子节点都是黑色
5.从任一节点到其每个子节点的所有路径都包含相同数目的黑色节点