Vue面试解析

216 阅读4分钟

这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战

Vue.js双向绑定的实现原理

  • 实现数据绑定的做法大致有如下几种:
    • 发布者-订阅者模式(backbone.js
    • 脏值检查(angular.js)
    • 数据劫持(vue.js)
  • vue.js采用数据劫持的方式,结合发布者-订阅者模式,通过Object.defineProperty()来劫持各个属性的settergetter以监听属性的变动,在数据变动时发布消息给订阅者,触发相应的监听回调。
<body>
  <input type="text" name="" value="" id='J_vueInput'>
  <p id="J_span"></span>
</body>
<script type="text/javascript">
var obj = {};
// 为obj定义一个名为 say 的访问器属性
Object.defineProperty(obj,'say',{
  set: function (val) {
    document.getElementById('J_vueInput').value = val;
    document.getElementById('J_span').innerHTML = val;
  }
})
document.addEventListener('keyup',function (e) {
  obj.say = e.target.value;
})
</script>
  • getter使用数据的时候触发,setter是在修改数据的时候触发,修改数据的时候触发setter,同时也触发了底层的watcher监听,通知dom修改刷新。

Vue中使用列表循环key的作用

  • 给每个节点唯一的标识,可以高效渲染虚拟DOM
  • Vue更新使用v-for渲染的元素列表时,默认使用“就地更新”的策略
  • 使用key给每个节点做一个唯一的标识,diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点
    • diff的过程:调用名为“patch”的函数,比较新旧节点

v-showv-if的区别

  • v-if:根据条件控制元素的创建与移除
  • v-show:控制元素的显示与隐藏,通过displaycss样式属性控制,适合频繁的切换使用

区别

  • v-if不同的是:无论v-show的值为true还是falseDOM元素都会存在于HTML代码中;而只有当v-if的值为trueDOM元素才会存在于HTML代码中
  • v-if可以搭配template使用,而v-show不可
  • v-if有配套的v-else-ifv-else,而v-show没有
  • v-show有更高的切换开销,v-show切换开销小

相同点

  • 都可以动态控制DOM元素显示隐藏

vue组件通信

双向绑定和单项数据绑定的优缺点

  • 单向绑定的优点:
    • 带来单向数据流,这样的好处是流动方向可以跟踪、流动单一、没有状态。
    • 单向数据流更利于状态的维护与优化,更利于组件之间的通信,更利于组件的复用
  • 双向数据流的优点:
    • 在一些需要实时反应用户输入的场合会非常方便,用户在视图上的修改会自动同步到数据模型中去,数据模型中值的变化也会立刻同步到视图中去
  • 双向数据绑定的缺点
    • 双向数据流是自动管理状态的,但是在实际应用中有很多需要手动处理状态变化的逻辑,使得程序复杂度上升,无法追踪局部状态的变化。
  • 双绑跟单绑之间的差异只在于,双向绑定把数据变更的操作隐藏在框架内部,调用者并不会直接感知

谈谈你对组件的理解

  • 可组合
  • 可重用:每个组件都是具有独立功能的,它可以被使用多个场景(例如:添加和编辑)
  • 可维护:每个组件仅仅包含自身的逻辑,更容易被理解和维护
  • 可测试:因为每个组件都是独立的,那么对于各个组件分别测试显然要比对整个页面进行测试容易的多

vue中,子组件为何不可以修改父组件传递的prop

  • 为了保证数据的单向流动,便于对数据进行追踪,避免数据混乱。
  • 官网解析

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解

vue的响应式原理中的Object.defineProperty有什么缺陷?

  • 无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应

Vue父组件和子组件生命周期钩子执行顺序?

  • 加载渲染过程
    • 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
  • 子组件更新过程
    • 父beforeUpdate->子beforeUpdate->子updated->父updated
  • 父组件更新过程
    • 父beforeUpdate->父updated
  • 销毁过程
    • 父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

vuecreatemounted这两个生命周期中请求数据有什么区别?

  • created的时候,视图中的html并没有渲染出来,所以此时如果直接去操作html中的dom节点,一定找不到相关的元素
  • 而在mounted中,由于此时html已经渲染出来了,所以可以操作dom节点。

RouteRouter区别

  • routerVueRouter的一个对象
    • 通过Vue.use(VueRouter)VueRouter构造函数得到的一个router的实例对象
    • 这个对象是:全局对象,包含了所有的路由
  • route是:跳转的路由对象
    • 每一个路由都会有一个route对象,是局部对象
    • 可以获取对应的name\path\params\query