美文网首页
前端面试题【Day02】

前端面试题【Day02】

作者: 小王子__ | 来源:发表于2021-08-23 15:36 被阅读0次

本篇绪论

  • 1,Vue响应式原理
1,Vue响应式原理

在vue实例中声明的数据就是响应式的。响应式:数据发生改变,视图会重新渲染新的值。

vue是怎么知道数据改变的呢;vue在数据改变的时候,怎么知道通知哪些视图更新呢;vue数据改变的时候,视图怎么知道什么时候更新呢?

首先介绍下Object.defineProperty

Object.defineProperty可以为对象中的每一个属性,设置get、set方法,当属性被访问的时候会触发get函数,当属性被赋值/改变时,会触发set函数。

eg

var obj = {
  name: 'xiaowang'
}
Object.defineProperty(obj, "name", {
  get() {
    console.log('get触发')
  },
  set(val) {
    console.log('set触发')
  }
})

当访问obj.name时,会打印get触发

当为obj.name赋值时,obj.name=100会打印set触发

vue是怎么知道数据改变的呢?因为vue在属性的set方法中做了手脚,因此当数据改变的时候,触发属性的set方法,vue就能知道数据有改变。

依赖收集

data中声明的每个属性,都拥有一个数组,保存着谁依赖(使用)了它。
eg:

data() {
  return {
    name: 'xiaowang'
  }
}

页面中引用 {{name}}

此时,name把页面存在它的后宫中(这个页面依赖我),因为它知道谁依赖它之后,他就可以在发生改变的时候,通知依赖它的页面,从而让页面完成更新。

这就是依赖收集,把依赖了我(使用了我)统统保存起来。

为什么要依赖收集?

在使用vue时,我们经常会遇到在data中声明的属性,有的并没有在template里展示,但是我们即将修改这个属性的值,那么就会造成视图更新,这是没有必要的,eg:

<template>
  {{msg1}}
</template>

data () {
  return {
    msg1: 11111,
    msg2: 22222
  }
},
mounted () {
  this.msg2 = 33333
}

我们改变了msg2的值,但是在template里并没有使用这个值,所以并不需要通知视图,进行更新,所以这里我们就需要进行依赖收集,避免不必要的视图更新。

  • data中每个声明的属性,都会有一个专属的依赖收集器subs
  • 当页面使用到某个属性的时候,页面的watcher就会被放在依赖收集器subs中

数据是在什么时候进行收集依赖的呢:在Object.defineProperty的get函数时。当页面读取了name,会触发name的get函数,此时,name就会保存页面的watcher了

依赖更新

就是通知所有的依赖进行更新。

每个属性都会保存一个依赖收集器subs,它是用来在数据发生变化时,通知更新的

Object.defineProperty的set方法,当name放生改变时,name会遍历自己的依赖收集器subs,逐个通知watcher,让watcher完成更新。

数据变化会触发set函数,通知视图,视图开始更新

  • Object.defineProperty的get函数,用于依赖收集
  • Object.defineProperty的set函数,用于依赖更新
  • 每个data声明的属性,都拥有一个专属依赖收集器subs
  • 依赖收集器subs保存的依赖是watcher
  • watcher可用于进行视图更新
Object.defineProperty

是在对象上定义一个新的属性,或者改变一个对象现有的属性,并且返回这个对象。

var str
var obj = {}
Object.defineProperty(obj, "b", {
  get(){
    console.log('get b')
    return str
  },
  set(newVal){
    console.log('set b')
    str = newVal
  },
  enumerable : true,
  configurable : true
})

obj.b = 100
console.log(obj.b)
image

下面例子实现一个极简单的vue双向数据绑定

<body>
  <input type="text" id="txt">
  <span id="content"></span>
</body>
<script>
  var txt = document.querySelector('#txt'),
      content = document.querySelector('#content'),
      obj = {}

  Object.defineProperty(obj, 'msg', {
    set (val) {
      txt.value = val
      content.innerHTML = val
    }
  })

  txt.addEventListener('keyup', function (e) {
    obj.msg = e.target.value
  })
观察者模式

它分为注册环节和发布环节

比如我们去剪头发,但是需要排队,我们不想在店内傻傻等,就会选择出去逛会街隔段时间回来看看排队的人还多吗,这样的话,我可能逛街逛累了不想剪了,这样店家就会流失像我这样的顾客。所以理发店想了个方法,会把客户的电话留下,其实这就是观察者模式中的注册环节。然后排到我的时候,会打电话通知我,这就是观察者的发布模式。

image

相关文章

网友评论

      本文标题:前端面试题【Day02】

      本文链接:https://www.haomeiwen.com/subject/rirliltx.html