Vue的一些总结-计算属性/双向绑定/生命周期/vue-router

335 阅读5分钟

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

computed和watch的区别

计算属性( computed)

对于任何复杂逻辑,你都应当使用计算属性。计算属性是基于它们响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才重新求值。

官方文档的例子

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>


var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
});

侦听器(watch)

Vue通过watch提供了一个更通用的方法,来响应数据的变化。当需要数据变化时执行异步或者开销更大的操作时,这个方法时最有效的。

官方例子:一下是对fullName进行监听

 <div id="demo">{{ fullName }}</div>

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

总结: computed具有缓存性,computed的值在getter执行后会缓存,只有在他依赖得data属性值改变之后,下一次获取computed得值时重新调用对应的getter来计算。 watch更多的是观察的作用,当数据变化时执行回调进行后续操作,不具有缓存性,页面重新渲染时值不变也会执行。 区别:当我们需要进行数值计算,并且依赖其他数据,那么就是这个数据设计为computed。当需要在某个数据发生变化时做一些事情,使用watch来观察这个数据变化。

双向绑定的原理

创建Vue实例(new Vue({})),Observer会监听劫持data数据,一个data属性就是一个Dep对象,里面存放着watcher,Compile解析el模板,将data里面的属性分别创建对应的watcher,将watcher加入到对应的Dep对象里面,解析el的时候除了创建对象的watcher,还初始化一个View,也就是界面上显示的东西。 如果要修改一个name值,Observer监听到数据的改变,调用对应属性的Dep对象的notify,会遍历所有的watcher,调用watcher的update函数,将界面显示的改变。 一张图详解(图片是一个老师视频里的截图)

在这里插入图片描述

生命周期

这是官方给出的图片,总共八个阶段,上详解~~~ 在这里插入图片描述

  1. beforeCreate(创建前) 对应的钩子是beforeCreate,此阶段为实例初始化之后,此时数据观察和事件机制都未形成,不能获得DOM节点。
  2. Craeted(创建后) 对应的钩子是created,此阶段是vue实例已经创建,仍然不能获取DOM节点
  3. beforeMount(载入前) 对应的钩子是beforeMount,在这一阶段我们虽然得不到具体的DOM元素,但是vue挂载的根节点已经创建,下面vue对DOM的操作将围绕找个根节点进行
  4. Mounted(载入后) 对应的钩子是mounted,我们平时使用最多的一个,在这个阶段数据和DOM元素都被渲染出来了,一般我们把异步请求都写在这里面
  5. beforeUpdata(更新前) 对应的钩子是beforeUpdate,数据更新之后虽然没有立即更新页面数据,但是DOM里的数据会更新,这是Vue双向绑定的作用.
  6. updated(更新后) 对应的钩子是updated,这一阶段DOM会和更改后的数据同步.
  7. beforeDestroy(销毁前) 对应的钩子函数是beforeDestroy, 在上一阶段Vue已经成功的通过数据驱动DOM更新,当我们不再需要vue操控DOM的时候,就需要销毁Vue,也就是清除vue实例与DOM之间的关联,调用destroy方法可以销毁当前组件,在销毁之前,会触发beforeDestroy钩子函数.
  8. destroyed 对应的钩子函数是destroyed,销毁当前组件.

vue-router

这里总结vue-router两种模式的区别 众所周知,vue-router有两种模式可以进行选择使用:hash和history,我们肉眼可见的就是hash模式的url里面带有一个#,而history则没有。它们还有其他区别???答案是:有

hash

原理:在url # 之后对应的是hash值,其原理是通过hashChange()监听hash值得改变,根据路由表对应的hash值来判断加载的对应的路由,加载对应的组件。

window.onhashchange = function(event){
    console.log(event.oldURL, event.newURL);
    let hash = location.hash.slice(1);
    document.body.style.color = hash
}

hash发生变化的url都会被浏览器记录下来,有什么作用呢?你会发现浏览器的前进后退都可以使用了,页面的字体颜色也会发生改变。这样一来,尽管浏览器没有请求服务器,但是页面状态和url相对应关联起来。后来人们给它起了一个霸气的名字叫前端路由,成为了单页应用标配。

history

history api可以分为两大部分:切换和修改

切换历史状态

包括go,forward,back三个方法,分别对应着跳转,前进,后退。

history.go(-2)
history.go(2)
history.forward()
history.back()
修改历史状态

包括了pushState,replaceState两种方法,两种方法接收三个参数:stateObj,title,url

history.pushState({color:'red'}, 'red', 'red'})
 
window.onpopstate = function(event){
    console.log(event.state)
    if(event.state && event.state.color === 'red'){
        document.body.style.color = 'red';
    }
}
 
history.back();
history.forward();

通过pushstate把页面的状态保存在state对象中,当页面的url再变回这个url时,可以通过event.state取到这个state对象,从而可以对页面状态进行还原,这里的页面状态就是页面字体颜色,其实滚动条的位置,阅读进度,组件的开关的这些页面状态都可以存储到state的里面。

对比优缺点

优点缺点
hash1.只需要配置前端路由表,不需要后端的参与
2.兼容性好,浏览器都能支持
3.hash值改变不会向后端发送请求,完全属于前端路由
有#号
history没有#号1.手动输入地址或者刷新你页面都会发起url请求,后端如果没有配置,会发生请求不到静态资源(404)
2.兼容性比较差, 是利用了 HTML5 History对象中新增的 pushState() 和 replaceState() 方法,需要特定浏览器的支持。