Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article also participated in the “Digitalstar Project” to win a creative gift package and creative incentive money

preface

[A little knowledge a day, a little progress every day] Good friends. Keep-alive principle analysis (a) has been the overall framework of keep-alive source code to do a simple comb, know a general process of keep-alive work, Today I will continue to analyze some of the core source code of Keep-Alive.

cacheVNode

CacheVNode () {cacheVNode ();} cacheVNode () {cacheVNode ();

methods:{
	cacheVNode(){
		const {cache, keys, vnodeToCache, keyToCache} = this.if (vnodeToCache){
			const {tag, componentInstance, componentOptions } = vnodeToCache
			cache[keyToCache] = {
				name: getComponentName(componentOptions),
				tag,
				componentInstance,
			}
			keys.push(keyToCache)
			if(this.max && keys.length > parseInt(this.max)){
				pruneCacheEntry(cache, keys[0], keys, this._vnode)
			}
			this.vnodeToCache = null; }}}Copy the code
  • First get the four attributes cache, keys, vnodeToCache, and keyToCache on the instance
    • The first two properties were explained in the previous article and will not be covered here
    • VnodeToCache The virtual DOM that needs to be cached
    • KeyToCache requires a key corresponding to the cached virtual DOM
  • If vnodeToCache is not empty, it needs to be cached. The detailed information about vnodeToCache is structured and stored in the object cache with keyToCache as the key
  • Also save the key keyToCache in the keys list
  • Check whether the maximum value of the cache is set. If the value is set and the length of the cache list exceeds the maximum value, run pruneCacheEntry to prune the cache list. Note that the earliest cached component is deleted.
  • Finally, the vnodeToCache is emptied

getComponentName

The component’s public function to get the component’s name

function getComponentName(opts: ? VNodeComponentOptions): ?string {
	return opts && (opts.Ctor.options.name || opts.tag);
}
Copy the code

pruneCacheEntry

Component’s public functions

function pruneCacheEntry (
  cache: VNodeCache,
  key: string,
  keys: Array<string>, current? : VNode) {
  const cached = cache[key]
  // Cached has value and is not the component currently being rendered
  if(cached && (! current || cached.tag ! == current.tag)) { cached.componentInstance.$destroy() } cache[key] =null
  remove(keys, key)
}
Copy the code
  • Gets the component instance to be destroyed from the cache object
  • If the group exists and is not currently being rendered, it is destroyed
  • The virtual DOM instance is also removed from the cache object
  • Removes the corresponding key from the keys list

render

  render () {
    const slot = this.$slots.default
    // Get the first child of the kepp-alive component vndoe
    const vnode: VNode = getFirstComponentChild(slot)
    constcomponentOptions: ? VNodeComponentOptions = vnode && vnode.componentOptionsif (componentOptions) {
      // Get the component name
      constname: ? string = getComponentName(componentOptions)const { include, exclude } = this;
      // Check if there is a need to cache, do not need to go directly to this if
      if (
        // Includes and does not get the name value or whether include contains the name value(include && (! name || ! matches(include, name))) ||// Whether to whitelist and filter directly
        (exclude && name && matches(exclude, name))
      ) {
        return vnode
      }
      // Cache logic is required
      const { cache, keys } = this
      // Check whether there is a key. If there is no key, vUE automatically adds a key to it
      constkey: ? string = vnode.key ==null
        ? componentOptions.Ctor.cid + (componentOptions.tag ? ` : :${componentOptions.tag}` : ' ')
        : vnode.key
      // Whether there is component data cached or directly cached
      if (cache[key]) {
          // Assign the cached vNode
        vnode.componentInstance = cache[key].componentInstance
        // make current key freshest
        remove(keys, key)
        keys.push(key)
      } else {
	    // delay setting the cache until update
    	this.vnodeToCache = vnode
       	this.keyToCache = key
      }
      // Add the keepAlive = true flag
      vnode.data.keepAlive = true
    }
    return vnode || (slot && slot[0])}Copy the code
  • Get the default slot in the keep-alive component and get the first keep-alive component based on the slot contents. As mentioned in the previous article, even with multiple child components, only the first is valid by default.
  • Obtain the name of the subcomponent and determine whether the current subcomponent is cached according to the include and exclude of keep-alive. In the following two cases, vNode is directly returned without caching
    • Include: If the include attribute exists and name is not included in the include
    • Exclude: If the include attribute exists and is included in exC
  • If the two conditions are not met, the cache logic needs to be used and the cache object cache and the corresponding key list keys need to be retrieved from the current keep-alive instance
  • Fetch the key of the vNode. If the key does not exist, generate another key
  • Determine whether the child component to be rendered is cached based on the key to the cache object
    • If the componentInstance exists in the cache object, the componentInstance of the cache object is directly extracted and assigned to the componentInstance of vNode. Remove the key from the keys list and add it again (to make sure the current key is up to date)
    • If the child component is not cached, the vNode and key are assigned to the vnodeToCache and keyToCache properties of the Keep-Alive instance, respectively, and will be cached for the next update
  • Finally, set the keepAlive property to true and return the current vNode to rendering.

conclusion

This concludes the analysis of the principle of keep-alive. To summarize briefly: When keep-alive is used, include and exclude are used to determine whether the sub-components inside keep-alive meet the matching conditions. If so, the virtual DOM instances corresponding to the sub-components are cached using the cache and keys attributes. When the next sub-component is re-rendered, it will first judge whether it exists in the cache list. If so, it will be directly pulled from the cache; otherwise, it will be temporarily stored in the object to be cached for the next update. Like small partners welcome to praise the message plus attention oh!