关于vue面试官常问的问题1

1、当我们点击按钮的时候动态给 data 增加的成员是否是响应式数据,如果不是的话,如果把新增成员设置成响应式数据,它的内部原理是什么。

let vm = new Vue({
    el: '#el'
    data: {
    o: 'object',
    dog: {}
    },
    method: {
        clickHandler () {
            // 该 name 属性是否是响应式的
            this.dog.name = 'Trump'
        }
    }
})

首先该 name 属性不是响应式数据的。

1、因为vue2.x内部是使用Object.defineProperty()的getter和setter方法来进行数据监听,然而新增的属性name并没有getter 和setter方法,所以数据不是响应式
要想设置成响应式也比较容易

方法1:预留一个坑位类似于以下代码:

let vm = new Vue({
    el: '#el'
    data: {
    o: 'object',
    dog: {
        name:''
    }
    },
    method: {
        clickHandler () {
            // 该 name 属性是否是响应式的
            this.dog.name = 'Trump'
        }
    }
})

原因:初始化的时候已经存在的属性,vue中会使用Object.defineProperty()方法对其进行监听,所以该属性有getter 和setter方法,所以数据就是响应式的

方法2:
vue官网给出一种解决的思路调用Vue.set()就可以实现数据的响应式
调用方法:Vue.set( target, key, value )

  • target:要更改的数据源(可以是对象或者数组)
  • key:要更改的具体数据
  • value :重新赋的值
let vm = new Vue({
        el: '#app',
        data: {
            msg: 'object',
            dog: {}
        },
        method: {
            clickHandler() {
                // 该 name 属性是否是响应式的
                this.$set(this.data.dog, name, 'Trump')
            }
        }
    })

2、请简述 Diff 算法的执行过程

  • diff的过程就是调用名为patch的函数,比较新旧节点,一边比较一边给真实的DOM打补丁。

  • 在采取diff算法比较新旧节点的时候,比较只会在同层级进行, 不会跨层级比较。

  • 数据发生改变时,set方法会让调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁

说明:

patch 函数接收两个参数 oldVnode 和 Vnode,它们分别代表新的节点和之前的旧节点。这个patch函数会比较 oldVnode 和 vnode 是否是相同的, 即函数 sameVnode(oldVnode, vnode), 根据这个函数的返回结果分如下两种情况

  • true:执行 patchVnode
  • false:用 vnode 替换 oldVnode

patchVnode 函数做的工作

1.找到对应的真实 dom,称为 el

2.判断 vnode 和 oldVnode 是否指向同一个对象。
如果是,那么直接 return(结束)。

3.判断他们都有文本节点并且不相等,那么将 el 的文本节点设置为 vnode 的文本节点。

4.判断 oldVnode 有子节点而 vnode 没有,则删除 el 的子节点。

5.判断 oldVnode 没有子节点而 vnode 有,则将 vnode 的子节点真实化之后添加到 el

6.判断两者都有子节点,则执行 updateChildren 函数比较子节点。

vue-router 中常用的 hash 和 history 路由模式实现原理

  1. hash:路由的哈希(锚点)模式其实是利用了window可以监听onhashchange事件,也就是说你的url中的哈希值(#后面的值)如果有变化,前端是可以做到监听并做一些响应(做点事情),这么一来,即使前端并没有发起http请求也能够找到对应页面的代码块进行按需加载
  • hash可以通过window.location.hash读取
  1. history模式:是利用pushState||replaceState(+服务端)以及popState事件的监听到状态变更
  • pushState:浏览器不会向服务端请求数据,直接改变url地址,可以类似的理解为变相版的hash;但不像hash一样,浏览器会记录pushState的历史记录,可以使用浏览器的前进、后退功能作用

  • replaceState:不同于pushState,replaceState仅仅是修改了对应的历史记录

说明:history模式需要服务端做配合将不存在路径重定向到指定页面,不然会出现404(找不到该页面)pushState方法不会触发页面刷新,只是导致history对象发生变化,地址栏会有反应

猜你喜欢

转载自blog.csdn.net/weixin_43956521/article/details/110805963