Vue原理

如何理解MVVM

数据驱动视图:

  • 传统组件只是静态渲染,更新还要依赖于操作DOM
  • 数据驱动视图 - Vue - MVVM
  • 数据驱动视图 - React - setState

监听data变化的核心API是什么

Vue2.0:Object.defineProperty
Vue3.0:Proxy(有兼容性问题,且无法用polyfill)

Object.defineProperty 缺点:(不要把缺点故意放大)

  • 深度监听需要递归到底,一次性计算量大
  • 新增或删除属性不能监听到,所以需要Vue.set / Vue.delete
  • 无法原生监听数组,需要特殊处理

虚拟DOM

本质是将计算放到 js 中,以提升计算性能,节约dom开销

  • vdom是实现vue和react的基石
  • diff算法是vdom的核心

HTML是一种XML语言,所有的XML语言都可以用一种JSON的方式表示:
在这里插入图片描述

diff 算法概述

最直接的体现:key

  • 树的diff算法时间复杂度 o ( n ) 3 o(n)^{3} o(n)3,第一遍历tree1,第二遍历tree2,第三排序

优化时间复杂度到 o ( n ) o(n) o(n)

  • 只比较同一层级,不跨级比较
  • tag不同,直接删掉重建,不再深度比较
  • tag 和 key 两者都相同,则认为是相同节点,不再深度比较(因为只比较同层)

diff 算法的时间复杂度

o ( n ) o(n) o(n)

diff 算法的过程

在这里插入图片描述

Vue 模板编译(组件渲染更新过程)

vue-template-compiler 模板编译为render函数,执行render函数返回vnode;基于vnode再执行patch和diff
使用webpack vue-loader 会在开发环境下编译模板;但直接引入vue是在浏览器运行时编译的

  • with语法:
    改变 {} 内自由变量的查找规则,当做obj的属性来查找;如果找不到匹配的属性择报错;(with要慎用,它打破了作用于规则,易读性差)
    在这里插入图片描述
  • vue template compiler 将模板编译为 render 函数
    const template = `<p>{{flag ? message : 'no message found'}}</p>`
    with(this){return _c('p',[_v(_s(flag ? message : 'no message found'))])}
    
  • 执行 render 函数生成 vnode

Vue组件是如何渲染更新的

初次渲染过程:

  • 解析模板为 render 函数(或在开发环境中已完成,vue-loader)
  • 触发响应式,监听data属性getter/setter
  • 执行 render 函数,生成 vnode,patch(ele,vnode)

更新过程:

  • 修改data,触发setter(此前在getter中已被监听)
  • 重新执行 render 函数,生成newVnode
  • patch(vnode,newVnode) ----> patch中的diff算法会算出最小差异然后更新到dom上

在这里插入图片描述

异步渲染

  • $nextTick 在DOM更新完之后触发回调
  • 汇总data修改,一次性更新视图
  • 减少dom操作次数,提高性能

Vue Router 原理

hash的特点:

  • hash变化会触发网页跳转,即浏览器前进后退
  • hash变化不会刷新页面,SPA必须的特点
  • hash永远不会提交到server端

H5 history(需后端配合)

  • 用url规范的路由,跳转时不刷新页面
  • history.pushState()
  • window.onpopstate ---- 浏览器前进后退

总结:

  • hash — window.onhashchange
  • H5 history — history.pushState() & window.onpopstate
  • history需要后端支持

两者选择:

  • 2B 系统推荐用hash,简单易用,对url不敏感
  • 2C 系统可以考虑H5 history,但需要服务端支持

为何v-for中要使用key

diff算法中通过 tag 和 key 来判断是否是 sameNode
作用:减少渲染次数,提升渲染性能

Vue组件的声明周期(父子组件)

组件实例的创建过程是从上而下
组件实例的挂载过程是从下而上

Vue组件如何通讯

  • 父子组件:props 和 this.$emit
  • 自定义事件:event.$on event.$off event.$emit
  • vuex

双向数据绑定v-model的原理

  • v-model 只是一个语法糖,是v-bind和input事件的组合
  • 将value绑定data中的值,通过事件去更新value,从而data更新触发re-render

computed 有何特点

  • 缓存,data不会重新计算,提高性能

组件data必须是一个函数

vue-template编译出来实际上是一个class,在每个地方使用组件的时候相当于实例化class,在实例化class时去执行data,如果data不是函数的话,那么每一个实例的数据都会是一样的

组件化机制

  • 组件化可以让我们方便的把页面拆分成多个可重用的组件
  • 组件是独立的,系统内可重用,组件之间可以嵌套
  • 有了组件可以像搭积木一样开发网页
  • 组件实例的创建过程是从上而下(父组件=>子组件)
  • 组件实例的挂载过程是从下而上(子组件=>父组件)

ajax应该在哪个生命周期

mounted

  • js是单线程的,ajax是异步的,放在mounted之前没什么用,只会让逻辑更加混乱

如何将组件所有的props传递给子组件

  • $props
  • <User v-bind="$props" />

何时使用beforeDestory

  • 解绑自定义事件 event.$off
  • 清除定时器
  • 解绑自定义的DOM事件(用vue定义的事件不用自己解除,vue会自己解除)

什么是作用于插槽

vuex中 action 和 mutation 有何区别

  • action 用于处理异步,mutation 不可以处理异步
  • mutation 做原子操作
  • action 可以整合多个 mutation

vue-router异步加载

箭头函数import

监听data变化的核心API

  • Object.defineProperty(注意深度监听&监听数组)
  • 重新定义原型,重写push,pop等方法
  • proxy可以原生支持监听数组变化

描述响应式原理

  • 监听data变化
  • 组件渲染和更新的流程

Vue常见性能优化

  • 合理使用 v-show 和 v-if
  • 合理使用 computed
  • v-for 加 key
  • v-for 和 v-if 避免同时使用(2.x中v-for优先级更高,每次 v-for 的时候 v-if 都会重新渲染;3.x中 v-if 优先级更高,v-if没有权利访问v-for中的变量)
  • 自定义事件,dom事件及时销毁
  • 合理使用异步组件
  • 合理使用keep-alive
  • data层级不要太深(deep深度监听时需要一次性遍历完成)
  • webpack层面
  • 前端通用–图片懒加载等等
  • ssr
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值