MST

星途 面试题库

面试题:如何自定义Vue Keep - Alive的缓存淘汰策略

假设你正在开发一个大型的Vue应用,其中使用了Keep - Alive进行组件缓存。由于内存限制,需要自定义一种缓存淘汰策略(比如LRU - 最近最少使用策略)来管理缓存的组件。请描述实现思路,并给出关键代码片段。
40.4万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 数据结构设计:使用一个双向链表和一个哈希表来实现LRU。双向链表用于记录组件的使用顺序,哈希表用于快速定位组件在链表中的位置。
  2. 缓存命中处理:当访问一个缓存中的组件时,将其从当前位置移动到链表头部,表示最近使用。
  3. 缓存未命中处理:如果缓存已满,移除链表尾部的组件(最近最少使用),并将新组件添加到链表头部。

关键代码片段

  1. 双向链表节点类
class DoublyLinkedNode {
    constructor(key, value) {
        this.key = key;
        this.value = value;
        this.prev = null;
        this.next = null;
    }
}
  1. LRU缓存类
class LRUCache {
    constructor(capacity) {
        this.capacity = capacity;
        this.cache = new Map();
        this.head = new DoublyLinkedNode(null, null);
        this.tail = new DoublyLinkedNode(null, null);
        this.head.next = this.tail;
        this.tail.prev = this.head;
    }

    get(key) {
        if (!this.cache.has(key)) {
            return -1;
        }
        const node = this.cache.get(key);
        this._moveToHead(node);
        return node.value;
    }

    put(key, value) {
        if (this.cache.has(key)) {
            const node = this.cache.get(key);
            node.value = value;
            this._moveToHead(node);
        } else {
            const newNode = new DoublyLinkedNode(key, value);
            this.cache.set(key, newNode);
            this._addToHead(newNode);
            if (this.cache.size > this.capacity) {
                const removed = this._removeTail();
                this.cache.delete(removed.key);
            }
        }
    }

    _addToHead(node) {
        node.next = this.head.next;
        node.prev = this.head;
        this.head.next.prev = node;
        this.head.next = node;
    }

    _removeNode(node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    _moveToHead(node) {
        this._removeNode(node);
        this._addToHead(node);
    }

    _removeTail() {
        const removed = this.tail.prev;
        this._removeNode(removed);
        return removed;
    }
}
  1. 在Vue应用中结合Keep - Alive使用 在Vue组件的生命周期钩子中,可以调用上述LRU缓存类的方法。例如,在activated钩子中标记组件被访问(调用get方法),在deactivated钩子中如果组件需要缓存则调用put方法。
export default {
    name: 'MyComponent',
    data() {
        return {
            lruCache: new LRUCache(10) // 假设缓存容量为10
        };
    },
    activated() {
        this.lruCache.get(this.$route.path); // 假设以路由路径作为缓存键
    },
    deactivated() {
        this.lruCache.put(this.$route.path, this); // 缓存当前组件实例
    }
}

在实际应用中,还需要考虑如何与Vue的keep - alive内置机制更好地集成,例如在组件被销毁时正确处理缓存等细节。