Vue常见面试题

230 阅读2分钟

1. Vue的双向绑定原理

Vue的双向绑定是建立在MVVM的模型基础上的
    数据层Model:应用的数据以及业务逻辑
    视图层View: 应用的展示效果,各类的UI组件等
    业务逻辑层ViewModel: 负责将数据和视图关联起来
双向绑定就是: 数据变化后更新视图,视图变化后更新数据。主要包含两部分:
    * 监听器Observer: 对所有的数据属性进行监听
    * 解析器Complier:  对每个元素节点的指令进行扫描和解析,根据指令替换数据,绑定对应的更新函数
具体的实现原理:
    1. new Vue()执行初始化,对data通过Object.defineProperty进行响应化处理,这个过程发生在Observer中,每个key都会有一个dep实例来存储watcher实例数组
    2. 对模板进行编译时,v-开头的关键词作为指令解析,找到动态绑定的数据,从data中获取数据并初始化视图,这个过程发生在Compiler里,如果遇到v-model,就监听input事件,更新data对应的值
    3. 在解析指令的过程中,会定义一个更新函数和Watcher,之后对应的数据变化时Watcher会调用更新函数, new Watcher的过程中会去读取data的key,触发getter的依赖收集,将对应的watcher添加到dep里
    4. 将来data中的数据一旦发生变化,会首先找到对应的dep,通知所有的watcher执行更新函数
手动实现一个响应式函数:
const data = {
  a: 55,
  b: {
    cc: 66,
    dd: {
      rr: 66666666,
      gg: {
        hh: 66666,
      },
    },
  },
};

const render = (key, val) => {
  console.log(`set key = ${key}, val = ${val}`);
};
const reactive = (obj) => {
  if (typeof obj !== "object") {
    return;
  }
  for (const key in obj) {
    defineReactive(obj, key, obj[key]);
  }
};
defineReactive = (obj, key, val) => {
  reactive(obj[key]);
  Object.defineProperty(obj, key, {
    get() {
      return val;
    },
    set(newVal) {
      if (val === newVal) {
        return;
      }
      val = newVal;
      render(key, val);
    },
  });
};
reactive(data);
data.a = 555;
// get a = 55, set a =  555
data.b.cc = "cesshi";
// get cc = 66, set cc =  8898989
data.b.dd.rr = 66666666;
// 此处什么也不打印
data.b.dd.gg.hh = "6546456456";
// get hh = 66666, set hh =  6546456456
console.log("data", JSON.stringify(data));
-------------------------------------------
set key = a, val = 555
set key = cc, val = cesshi
set key = hh, val = 6546456456
data {"a":555,"b":{"cc":"cesshi","dd":{"rr":66666666,"gg":{"hh":"6546456456"}}}}