[Vue面试] keep-alive 和 $set 的使用

keep-alive 的使用汇总于 半度℃温热圈圈同学

keep-alive

概念

keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 transition 相似,keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。

作用

在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提升用户体验

原理

在 created 函数调用时将需要缓存的 VNode 节点(虚拟DOM,其实就是一个JS对象)保存在 this.cache 中/在 render(页面渲染) 时,如果 VNode 的 name 符合缓存条件(可以用 include 以及 exclude 控制),则会从 this.cache 中取出之前缓存的 VNode 实例进行渲染。

应用场景

用户在某个列表页面选择筛选条件过滤出一份数据列表,由列表页面进入数据详情页面,再返回该列表页面,我们希望:列表页面可以保留用户的筛选(或选中)状态。keep-alive就是用来解决这种场景。当然keep-alive不仅仅是能够保存页面/组件的状态这么简单,它还可以避免组件反复创建和渲染,有效提升系统性能。
总的来说,keep-alive用于保存组件的渲染状态。

用法

  • 在动态组件中的应用
<keep-alive :include="whiteList" :exclude="blackList" :max="amount">
  <component :is="currentComponent"></component>
</keep-alive>
  • 在 App.vue 中的应用
<keep-alive :include="whiteList" :exclude="blackList" :max="amount">
  <router-view></router-view>
</keep-alive>
  • 结合 vue-router,缓存部分页面
import Vue from 'vue'
import Router from 'vue-router'
const Home = resolve => require(['@/components/home/home'], resolve)
const Goods = resolve => require(['@/components/home/goods'], resolve)
const Ratings = resolve => require(['@/components/home/ratings'], resolve)
const Seller = resolve => require(['@/components/home/seller'], resolve)

Vue.use(Router)

export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home,
      redirect: 'goods',
      children: [
        {
          path: 'goods',
          name: 'goods',
          component: Goods,
          meta: {
        	keepAlive: false // 不需要缓存
      	  }
        },
        {
          path: 'ratings',
          name: 'ratings',
          component: Ratings,
          meta: {
        	keepAlive: true  // 需要缓存
      	  }
        },
        {
          path: 'seller',
          name: 'seller',
          component: Seller,
          meta: {
        	keepAlive: true  // 需要缓存
      	  }
        }
      ]
    }
  ]
})

在 App.vue 中

<template>
  <div id="app">
  	<keep-alive>
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>
  • include 定义缓存白名单,可以是一个以英文逗号分隔的字符串、一个正则表达式,或是包含这两种类型的一个数组,keep-alive 会缓存名称匹配的组件;
  • exclude 定义缓存黑名单,可以是一个以英文逗号分隔的字符串、一个正则表达式,或是包含这两种类型的一个数组,名称匹配的组件将不会被缓存;
  • max 数字,定义最多可以缓存多少组件实例,超出上限使用LRU的策略置换缓存数据。

生命周期函数

  • activated
    • 在 keep-alive 组件激活时调用,该钩子函数在服务器端渲染期间不被调用
  • deactivated
    • 在 keep-alive 组件停用时调用,该钩子在服务器端渲染期间不被调用

当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。

使用 keep-alive 会将数据保留在内存中,如果要在每次进入页面的时候获取最新的数据,需要在 activated 阶段获取数据,承担原来 created 钩子函数中获取数据的任务。

只有组件被 keep-alive 包裹时,这两个生命周期函数才会被调用,如果作为正常组件使用,是不会被调用的


vm.$set

这里为什么不是this而是vm?

他们都是指的vue实例

var vm = new Vue({
  data: {
    a: 1
  }
})
vm.$set(vm.userProfile, 'age', 27)

作用

向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = ‘hi’)

应用场景

当我们更改了数据之后,视图没有跟随数据的改动发生变化,即双向数据绑定失效;

根据官方文档,双向数据绑定失效总共有三种情况:

  1. 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength
  3. 对象中的属性增加或删除时

用法

  1. 使用 this.$set(obj, key, value)/vue.set(obj, key, value)
    数组写法:this.$set(原数组, 索引值, 需要赋的值)
    对象写法:
<script>
export default {
 data() {
   return {
     student: {
       name: '张三',
     }
   }
 },
 methods: {
   setMessage() {
     this.$set(this.student, 'age', 15)
     console.log(this.student)
   }
 }
}
</script>
  1. 通过 Object.assign(target, sources) 方法
<script>
export default {
  data() {
    return {
      student: {
        name: '张三',
      }
    }
  },
  methods: {
    setMessage() {
      this.student.age = 15
      this.student = Object.assign({}, this.student)
      console.log(this.student)
    }
  }
}
</script>

这两篇介绍的可能更加详细:文章1文章2

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值