Computed 和 Watch

Computed 和 Watch

Computed本质是一个具备缓存的watcher,依赖的属性发生变化就会更新视图。适用于计算比较消耗性能的计算场景。当表达式过于复杂时,在模板中放入过多逻辑会让模板难以维护,可以将复杂的逻辑放入计算属性中处理。

Watch没有缓存性,更多的是观察的作用,可以监听某些数据执行回调。当我们需要深度监听对象中的属性时,可以打开deep:true选项,这样便会对对象中的每一项进行监听。这样会带来性能问题,优化的话可以使用字符串形式监听,如果没有写到组件中,不要忘记使用unWatch手动注销哦。


h7ml
  • vue
大约 4 分钟
diff

Diff 算法

Diff算法的核心就是针对具有相同父节点的同层新旧子节点进行比较,而不是使用逐层搜索递归遍历的方式。时间复杂度为O(n)

如何理解?

说白点,就是当新旧VNode树在同一层具有相同的VNode节点时,才会继续对其子节点进行比较。一旦旧VNode树同层中的节点在新VNode树中不存在或者是多余的,都会在新的真实DOM中进行添加或者删除。


h7ml
  • vue
大约 13 分钟
keep-alive

keep-alive

keep-alive是 Vue 内置的一个组件,可以实现组件缓存,当组件切换时不会对当前组件进行卸载。

activateddeactivated两个生命周期, 将会在<keep-alive>树内的所有嵌套组件中触发, 用来得知当前组件是否处于活跃状态。

  • include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
  • exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。

h7ml
  • vue
大约 3 分钟
vue生命周期

Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载 Dom、渲染 → 更新 → 渲染、销毁等一系列过程,我们称这是 Vue 的生命周期。通俗说就是 Vue 实例从创建到销毁的过程,就是生命周期。

每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如需要设置数据监听、编译模板、挂载实例到 DOM、在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,给予用户机会在一些特定的场景下添加他们自己的代码。


h7ml
  • vue
  • vue
大约 7 分钟
nextTick

nextTick

在做项目的时候,我们经常会用到nextTick,简单的理解就是它就是一个setTimeout函数,将函数放到异步后去处理;将它替换成setTimeout好像也能跑起来,但它仅仅这么简单吗?那为什么我们不直接用setTimeout呢?让我们深入剖析一下。

先看一个例子

<template>
  <div>
    <div ref="message">{{ message }}</div>

h7ml
  • vue
大约 7 分钟
props

props

这一次,通过源码阅读,主要探索的方面包括如何初始化 Props、以及如何进行更新。

初始化

initState(vm);

function initState(vm) {
  vm._watchers = [];
  var opts = vm.$options;
  if (opts.props) {
    initProps(vm, opts.props);

h7ml
  • vue
大约 7 分钟
set

$set() 实时更新

对象添加属性

对于使用 Object.defineProperty 实现响应式的对象,当我们去给这个对象添加一个新的属性的时候,是不能够触发它的 setter 的,比如:

var vm = new Vue({
  data: {
    a: 1,
  },
});
// vm.b 是非响应的
vm.b = 2;

但是添加新属性的场景我们在平时开发中会经常遇到,那么 Vue 为了解决这个问题,定义了一个全局 API Vue.set 方法


h7ml
  • vue
大约 5 分钟
Virtual DOM

Virtual DOM

要知道渲染真实DOM的开销是很大的,比如有时候我们修改了某个数据,如果直接渲染到真实 dom 上会引起整个 dom 树的重绘和重排,有没有可能我们只更新我们修改的那一小块 dom 而不要更新整个 dom 呢?

diff算法能够帮助我们。

我们先根据真实 DOM 生成一颗virtual DOM,当virtual DOM某个节点的数据改变后会生成一个新的Vnode,然后VnodeoldVnode作对比,发现有不一样的地方就直接修改在真实的 DOM 上,然后使oldVnode的值为Vnode


h7ml
  • vue
大约 3 分钟
Object.defineproperty 核心代码 自定义实现
// 触发更新视图
function updateView() {
  console.log('视图更新')
}

// 重新定义数组原型
const oldArrayProperty = Array.prototype
// 创建新对象,原型指向 oldArrayProperty ,再扩展新的方法不会影响原型
const arrProto = Object.create(oldArrayProperty)

h7ml
  • vue
  • vue
大约 1 分钟
Proxy 核心代码 自定义实现
// const data = {
//     name: 'zhangsan',
//     age: 20,
// }
const data = ['a', 'b', 'c']

const proxyData = new Proxy(data, {
  get(target, key, receiver) {
    // 只处理本身(非原型的)属性
    const ownKeys = Reflect.ownKeys(target)

h7ml
  • vue
  • vue
小于 1 分钟
vue

vue 源码分析

核心

Vue 响应式的核心是利用 Object.defineProperty()这个方法进行数据劫持和观察者模式进行数据响应式的。Object.defineProperty()这个方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。具体用法如下:

​ 它有三个参数,第一个是 object,它代表要定义属性的对象。;第二个是 prop,它代表目标对象的属性值;第三个参数是 descriptor,它代表要定义或修改的属性描述符。


h7ml
  • vue
  • vue
大约 6 分钟
proxy-observe 核心代码 自定义实现
// 创建响应式
function reactive(target = {}) {
  if (typeof target !== 'object' || target == null) {
    // 不是对象或数组,则返回
    return target
  }

  // 代理配置
  const proxyConf = {
    get(target, key, receiver) {

h7ml
  • vue
  • vue
小于 1 分钟
vue核心概念

在父组件中监听子组件的生命周期钩子

<template>
  <child @hook:mounted="onChildMounted"></child>
</template>
<script>
  export default {
    methods: {
      onChildMounted() {},
    },
  };
</script>

相关源码


h7ml
  • vue
  • vue
大约 7 分钟