MVC模式
1 控制器Controller 模型 Model 视图 View
2 路由解析(根据URL寻找控制器与行为) à 控制器调用行为,进行数据操作 –> 数据操作后进行 视图与数据的页面渲染 输入到客户端
MVVM模式
将 MVC 中的控制器变成View Model
VIEW代表UI组件 MODEL代表数据模型
VIEW和MODEL之间的桥梁 视图发生改变通知VIEWMODEL层更新,数据发生改变通知VIEWMODEL层更新视图渲染。
VUE2.0数据响应式
Object.defineProperty 给data中所有属性设置setter和getter,收集依赖。数据变化时触发setter通知依赖,Watcher通知外界数据改变(视图更新或者触发回调)。外界读取数据时触发getter将watcher收集到依赖中。
缺点:E6之前无元编程,新增和删除属性无法设置响应式,需要重新遍及设置响应式。数组的一些方法也会无法通知watcher数据发生变化。
VUE2数组如何设置
使用函数劫持,重写函数方法。调用数组API的时候就会通知依赖更新。缺点:修改第一个元素时,无法检测。 清楚数组的操作也无法检测。
VUE3.0数据响应式
使用Proxy 代理直接监听对象和数组的变化,判断Refect.get返回的是否为对象然后通过relative方法做代理,实现深层观测。
观测数组时触发多次如何避免--à用key判断是否代理对象target自身属性。或者判断新旧值是否相等,才执行触发器。
VUE指令原理
模版编译时,将指令解析出来并添加到AST的directives属性里.
VUE常用修饰符
键盘.delete .ctrl .alt .shift .enter .meta
鼠标.left .right 将输入转换成数字v-model.number/.trim
.middle
nestTick原理
再下次DOM更新循环结束后执行延迟回调。
分为宏任务和微任务。
Promise
Mutation Observer
Setimmediate
以上皆不可以使用setTimeout。定义一个异步方法,多次调用nestTick会存入一个队列 。
V-if 和 V-show的区别
实现方式:V-if根据数据真假值判断Dom树删除还是建立元素节点。
v-show只是单纯修改CSS样式,元素一直存在Dom树上。
编译过程中V-if有一个局部编译/卸载的过程。(销毁或者重建内部的事件监听和自组件。)
v-if是惰性 条件为假,什么都不做。
VUE生命周期
创建实例à初始化数据à编译模板à渲染函数à创建虚拟DOMà渲染真实DOMà更新à销毁。组件通过new Vue() 创建后会初始化事件和生命周期。beforeCreate钩子函数,无法访问到数据。Created函数之后实例建立,完成挂载数据,绑定事件,可以获得初始数据。DOM树未建立可以使用vue.$nestTick与dom交互。寻找template模版,编译模板为渲染函数,创建虚拟DOM,然后执行BeforeMounted函数。虚拟dom建立完成。然后渲染真实dom,Mounted 挂载完成后,真实Dom挂载完毕,数据进行双向绑定。可以操作真实dom。响应式数据发生改变,执行Beforeupdate,虚拟dom利用diff算法与真实DOM对比重新渲染。更新完成后,执行Updated 真实DOM更新,此时避免修改数据,防止无线循环更新。调用$destroy方法后,立即执行beforeDestroy,实力销毁前,清除计时器、清除非指令绑定的事件,组件的数据绑定、监听。只剩下dom空壳。然后执行destroyed。
组件通信方式
父->子Props 给子节点指定ref
子->父$on $emit 事件订阅和发布
使用$parent $children 获取实例不推荐会导致代码高度耦合
Ref获取实例 VUEX
COMPUTED 和 WATCH
Computed就是具有缓存的watcher,
依赖属性变化时更新视图。计算比较消耗性能的计算场景。
模板放入过多逻辑无法维护。
Watch没有缓存性,更多是一个观察的作用,可以监听某些数据,执行回调。当我们需要深度监听时 Deep:true
Data为什么是一个函数
一个组件被复用多次的话,会建立多个实例。
本质上,这些实例都是同一个创造函数,如果data是一个对象,对象属于引用类型,会影响到所有实例。
保证了不同实例之间不冲突。
V-model原理
本质是一个语法糖 value + input方法的语法糖。可以通过model实行的prop和event属性进行自定义。
根据不同的标签属性生成不同的事件和属性。
VUE模版翻译
生成AST抽象语法树
深度遍及抽象语法数 查找静态节点(更新dom时直接跳过)。
然后把语法树编译成渲染函数。
VUE2.0和3.0 Diff算法
2.0进行双端比较--------新前旧前,新后旧后,新后旧前,新前旧后 移动节点。借助key找到可以复用的节点。
3.0借鉴了ivi算法和inferno算法
创建VNode时确定类型,以及在patch的过程中采用位运算来判断一个VNode的类型,在这个基础上配合核心diff算法。
虚拟DOM
浏览器渲染真实dom十分耗时。频繁操作dom会造成性能问题。
虚拟dom用js对象描述一个dom节点。对真实dom进行一个抽象形成Vnode 虚拟节点。 经历create-diff-patch
虚拟dom本质上就是在 JS 和 DOM 之间做了一个缓存
Key的作用
为了更高效的复用dom元素。新旧节点中保存映射关系。以便在旧节点中找到可以复用的元素,key就是节点的唯一标识。
新旧节点只有顺序不同时,直接进行移动元素。
Keep-alive
实现组件缓存,当组件切换时不会对当前组件进行卸载。
常用的比如 include / exclude 允许组件有条件的缓存
生命周期有 active / deactivated 通知当前组件是否活跃
还使用的LRU算法
VUE生命周期调用顺序
父 beforecreate 父created 父beforemount
子 beforecreate 子created 子beforemount
子mountd
父mountd
父beforeupdate 子beforeupdate
子updated父Updated
父beforddestroy 子beforddestroy 子destroyed 父destroyed
SSR
服务器渲染,把vue在客户端渲染成HTML的工作放在服务端完成直接把html文件返回给客户端。
首屏加载快。开发受限生命周期只有befordcreate 和 created
服务器更大的耗载。
VUE的性能优化
v-if 和 v-for 不连用。
尽量减少data数据。会增加更多的getter和setter 收集对应的watcher。
SPA页面使用keep-alive
Key保证唯一
防抖和节流
图片懒加载
长列表滚动到可视区域动态加载。
SEO优化
预渲染
服务端渲染SSR
打包优化
压缩代码
CDN加载第三方模块
抽离公共文件
Vuex
1.vuex有哪几种属性?
分别有State、 Getter、Mutation 、Action、 Module。
2.state的理解?
1----Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data
2----state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
3----它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中
3.vuex的Getter特性?
一getters 可以对State进行计算操作,它就是Store的计算属性
二虽然在组件内也可以做计算属性,但是getters 可以在多组件间复用
三如果一个状态只在一个组件内使用,是可以不用getters
4.vuex的Mutation的特性?
Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作
5.vue.js中ajax请求代码放在methods还是actions?
一、如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
二、如果被其他地方复用,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。
Vue-router路由
1.怎么定义vue-router的动态路由?怎么获取传过来的值?
动态路由的创建,主要是使用path属性过程中,使用动态路径参数,以冒号开头,如下:
{
path: '/details/:id'
name: 'Details'
components: Details
}
访问details目录下的所有文件,如果details/a,details/b等,都会映射到Details组件上。
当匹配到/details下的路由时,参数值会被设置到this.$route.params下,所以通过这个属性可以获取动态参数
this.$route.params.id
2.vue-router有哪几种路由守卫?
router.beforeEach 全局守卫(全局前置守卫 )进入路由之前
router.afterEach 全局后置钩子
router.beforeResolve全局解析守卫
router.beforeRouteEnter,router.beforeRouteUpdate,
router.beforeRouteLeave组件内的守卫-----路由独享守卫
3.$route和 $router的区别是什么?
$router为VueRouter的实例,是一个全局路由对象,包含了路由跳转的方法、钩子函数等。
$route 是路由信息对象||跳转的路由对象,每一个路由都会有一个route对象,是一个局部对象,包含path,params,hash,query,fullPath,matched,name等路由信息参数。
4.vue-router响应路由参数的变化
(1)用Watch检测
Watch: {
$route(to, from){
console.log(to.path) 对路由变化进行响应
}}
(2)组件内导航钩子函数
beforeRouteUpdate(to, from, next){
todosomethings}
5. vue-router 传参
(1)使用Params:
只能使用name,不能使用path
参数不会显示在路径上
浏览器强制刷新参数会被清空
Const P = this.$router.params
This.$router.push({
Name:home,
Params:{
Number:1,
Code:’999’
}})
2)使用Query:
参数会显示在路径上,刷新不会被清空
name可以使用path路径
Const P = this.$router.query
This.$router.push({
name:Home,
qurey:{
Number:1,
Code:’999’
}})