《整理4》

508 阅读5分钟

一. keep-alive

<keep-alive> 是Vue的一个内置组件。功能:使被它包含的组件的状态维持不变,避免重新渲染。被它包含的组件,即使被切换了,它的状态也会保持在内存中,下一次显示的时候,不会再次渲染。因为有时候某些组件没有必要多次渲染,可以将它们缓存在内存中。

而且,<keep-alive>只是一个抽象组件,不会在DOM树中被渲染。(真实或虚拟都没有)

1. keep-alive的基础使用

最基础的一般是结合动态组件去使用:

<keep-alive>
    <component :is="currentView"></component>
</keep-alive>

new Vue({
    el: '#app',
    data(){
        return {
            currentView: Test //Test为引入的子组件
        }
    }
})

<component :is="currentView"></component> 也是一个内置组件,通过is属性指定不同的组件名,实现组件的切换。也就是动态组件。但是切换后再切回来,原来的组件就会被重新渲染。所以在外边包裹keep-alive ,就可以让里边被切换的组件被缓存。不用再次渲染。

2. 生命周期钩子

被包含在 <keep-alive> 中创建的组件,会多出两个生命周期的钩子: activateddeactivated

activated 在组件被激活时调用,在组件第一次渲染时也会被调用,之后每次keep-alive激活时被调用。

deactivated 在组件被移除时调用。

注意:只有组件被 keep-alive 包裹时,这两个生命周期才会被调用,如果作为正常组件使用,是不会被调用,以及在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,这两个钩子依然不会被调用!另外在服务端渲染时此钩子也不会被调用的。

3. 提供 include 和 exclude 属性

include - 字符串或正则表达式。只有名称匹配的组件会被缓存。

exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。

max - 数字。最多可以缓存多少组件实例。

<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>

<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>

<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
  <component :is="view"></component>
</keep-alive>

匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。当匹配条件同时在 include 与 exclude 存在时,以 exclude 优先级最高

4. 结合路由使用

<router-view> 展示路由匹配到的组件。有些时候可能需要将整个路由页面一切缓存下来,也就是将 <router-view> 进行缓存。这种使用场景还是蛮多的。

<!-- 一个include解决了,不需要多写一个标签,也不需要在路由元中添加keepAlive了 -->
<keep-alive include='a'>
    <router-view></router-view>
</keeo-alive>

二. vue router中 hash模式和history模式的原理,区别

1. hash模式

url中#后边的就是hash值,它可以通过window.location这个API获取到。比如window.location.hash ,通过修改这个值,就能在不刷新页面的情况下,改变url从而得到不同的页面内容。 在单页面应用中要做到的就是不刷新页面也就是不向服务器发http请求,就能改变url。 因为hash值只是客户端保存的状态,它不会被发送到服务器。

前端路由的hash模式就是利用了window可以监听hashchange这个事件,当url中的hash值变化,前端可以监听到并且做一些事情,所以前端即使没有发起http请求,也可以找到对应页面的代码并且加载。

hash 路由模式的实现主要是基于下面几个特性:

URL 中 hash 值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash 部分不会被发送;

hash 值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash 的切换;

可以通过 a 标签,并设置 href 属性,当用户点击这个标签后,URL 的 hash 值会发生改变; 或者使用 JavaScript 来对 loaction.hash 进行赋值,改变 URL 的 hash 值;

我们可以使用 hashchange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)。

window.location这个API上还有哪些方法能做到不刷新页面就改变url的呢?location.href只改变hash也可以做到。但是location.search就会刷新页面。

2. history模式

HTML5 提供了 History API 来实现 URL 的变化。其中做最主要的 API 有以下两个:history.pushState()history.repalceState()。这两个 API 可以在不进行刷新的情况下,改变url,操作浏览器的历史纪录。 唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录,如下所示:

window.history.pushState(null, null, path);
window.history.replaceState(null, null, path);

history 路由模式的实现主要基于存在下面几个特性:

pushState 和 repalceState 两个 API 来操作实现 URL 的变化 ;

我们可以使用 popstate 事件来监听 url 的变化,从而对页面进行跳转(渲染);

history.pushState() 或 history.replaceState() 不会触发 popstate 事件,这时我们需要手动触发页面跳转(渲染)。

因为没有发http请求,所以如果刷新页面,就会404.怎么解决404的问题,就需要后端的配合,需要后端将不存在的路径请求重定向到入口文件(index.html),渲染到同一个路由。

所以不管是hash模式还是history模式,都要先实现不刷新页面就改变url,然后用js监听url的变化。

参考文章1

参考文章2

三. vue 父子组件生命周期的执行顺序

父组件beforeCreated

父组件created

父组件beforeMounted

子组件beforeCreated

子组件created

子组件beforeMounted

子组件mounted

父组件mounted

销毁过程 : 父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed