Vue学习笔记

Vue

MVVM

在MVC的基础上实现了view-model,即视图与数据的双向绑定,视图只是数据的映射,所有逻辑都是对数据的修改,不用直接操作DOM。

SPA单页应用

优点:

  • 具有桌面应用的即时反馈,无需刷新页面就可以交互,又有web的跨平台
  • 后续操作无需重新从服务器获取静态资源,服务器压力较小
  • 路由由前端控制,更好的前后端分离

缺点:

  • 首屏加载资源较多,速度较慢(按需加载、懒加载)
  • 需要手动实现导航的前进后退
  • 不利于SEO(需手动优化)

周期

new Vue() –> init –> $mount –> compiler –> render –> vnode –> patch –> DOM

常用题目

单向数据流

父组件使用用prop和子组件进行通信,父级prop更新传递给子组件进行更新,反之则不行。子组件中不能修改prop,只能通过$emit一个事件通知父组件,由父组件更新prop来修改。

computed和watch的区别

  • 计算属性,依赖于参与计算的其他属性值,会对计算结果进行缓存,依赖的值发生变更才会重新计算,主要为了获取到最新的值。
  • watch,当某个属性值发生变化时,触发对应的回调。更多的是在数据变化是执行异步操作/复杂操作, 而不是为了获取最新的值。

对象变更检测

Vue是在初始化实例时对data对象上的property执行getter/setter转换实现检测变更的,直接添加根级别的property将无法触发更新。

可以通过以下方式添加:

  • Vue.set(vm.someObject, b, 2)/vm.$set(vm.someObject, b, 2)
  • this.someObject = Object.assign({}, this.someObject, { b: 2 })

数组变更检测

直接修改数组中一项的值,或者修改数组的length,Vue无法检测到数据的变更。因为Vue是通过数据劫持实现监控数据的,只对数组本身进行了处理,对内容并没有处理。

通过以下方式Vue可以检测到变更:

  • 变异方法,Vue对数组的方法进行了处理,调用时即可检测变更,eg:splice、push、shift、pop、slice等
  • Vue.set()/vm.$set()

生命周期

  • 创建实例
  • 初始化事件/生命周期
  • 初始化注入/校验,data和methods初始化完毕
  • 编译模板,生成模板
  • 挂载实例,创建vm.$e并l替换el
  • 销毁实例

钩子函数

  • beforeCreate,
  • created,最早可以操作data和methods的地方
  • beforeMount
  • mounted,初始化完毕,渲染真是dom
  • beforeUpdate,data变成最新值,但是还没有更新到dom
  • updated
  • beforeDestroy,data、methods、指令、过滤器、计算属性等可用
  • destroyed

父组件监听子组件钩子

方法一:手动在子组件钩子中$emit

方法二:父组件使用@hook:mounted就可以实现

keep-alive

抽象组件,不会渲染任何DOM,动态组件<component :is="currentComponet"></component>切换时每次都会重新渲染组件,无法保存状态,使用keep-alive组件包裹,就可以实现状态的保存。

  • 对应activated和deactivated两个钩子函数
  • 使用include/exclude属性传入正则/字符串,就可以设置哪些组件缓存/不缓存

为什么组件中data是一个函数返回一个对象,而new Vue()中data是一个对象

因为对象是引用类的数据,组件复用时,如果是data 是对象,修改单个组件时就会影响其他组件的值。

v-model

语法糖,例如input元素使用v-model相当于使用value和input事件修改value

用在组件上,默认使用名为value的prop和input的自定义事件

组件通信

  • 父 -> 子,prop/ref/$children
  • 子 -> 父,$emit/$parent
  • 兄弟,EventBus
  • 隔代,$attrs/$listeners,子组件上v-bind=”$attrs”会向下传递props属性中未获取的父组件传下来的props;$listeners包含了作用于当前组件的所有事件
  • 隔代,provide/inject,provide传递数据,inject获取数据
  • Vuex,状态管理模式,state存储状态,getter计算状态,mutation/action可预测的变更状态,响应式

SSR

服务端渲染,Vue在服务端渲染html页面推送到浏览器进行展示

  • 更好的SEO
  • 更快的首屏加载
  • 只支持beforeCreate和created两个钩子
  • 占用更多的服务器资源

Router

  • hash模式,修改url的hash值(location.hash)实现跳转,hashchange更改页面内容
  • history模式,HTML5 History API,pushState和replaceState修改url不会引起页面刷新,需要配置后台避免手动刷新404
  • abstract模式,不依赖于浏览器,通过数组模拟浏览器历史记录和功能

双向绑定实现

  • Observer监听器,对数据对象data进行遍历,使用Object.definePropery()添加getter和setter实现数据劫持,对data 的属性进行修改时就会触发setter
  • Compiler解析器,解析模板指令,将模板中的变量替换为数据,解析指令给对应节点绑定更新函数,添加数据订阅器
  • Watcher订阅者,订阅Observer中的数据变更,找到对应的更新函数并调用
  • Dep订阅器,收集订阅者

数组变化检测

通过重写数组的push、pop、shift、unshift、splice、sort、reverse等方法实现数据劫持,不能修改Array.prototype上的方法,通过一个对象使用Object.create()原型继承的方式继承Array.prototype,将变异方法添加到新对象上,然后将data的数组属性的proto设置为新对象即可。

虚拟DOM的优缺点

优点:

  • 短时间内多次修改操作可以合并成一次,较少渲染成本
  • 框架的虚拟DOM对呀修改DOM进行了性能优化,比手动修改DOM开销更小
  • 对比修改前后的虚拟DOM计算差异,避免渲染整个DOM树
  • 实现双向数据绑定,修改数据即可自动修改视图,减少开发成本
  • 跨平台,纯JS实现,不依赖浏览器,可以实现服务端渲染、weex开发等等

缺点:

  • 多了一次运算,增加开销
  • 虚拟DOM需要适配上层API,无法做到极致的性能优化

虚拟DOM实现原理

  • 解析html,用js对象模拟DOM树,对真是DOM进行抽象
  • dff算法,比较修改前后DOM树的差异
  • patch算法,将差异部分应用到真正的DOM树

Key的作用

vnode的唯一标记,可以更准确、更快的diff操作

  • 解决不需要就地复用的场景
  • 直接通过key取节点比遍历更快

优化

  • v-if和v-show
  • v-for和v-if混用
  • computed和watch
  • 长列表优化,无限滚动/可见区域渲染
  • 销毁事件
  • 懒加载,路由、图片、组件等
  • 三方插件按需引入
  • CDN
  • 压缩,webpack、nginx
  • 组件化
  • sourceMap优化
  • 浏览器缓存机制优化

使用过程中遇到的最大的问题

  • 数组变更检测,变异方法解决
  • 异步回调中this指向问题,箭头函数/变量获取this
  • setInterval销毁

3.0

proxy

创建一个代理替代一个对象,对目标对象的所有操作都可以在代理中进行拦截,对数组同样有效。

  • 可以直接检测对象,而不是对象的属性,可以检测到对象的添加和删除
  • 检测数组的索引和长度的变更
  • 支持Set、Map、WeakMap和WeakSet

改用typescript,对ts更友好

0%