Home / File/ normalize-scoped-slots.ts — vue Source File

normalize-scoped-slots.ts — vue Source File

Architecture documentation for normalize-scoped-slots.ts, a typescript file in the vue codebase. 8 imports, 2 dependents.

File typescript VueCore GlobalAPI 8 imports 2 dependents 3 functions

Entity Profile

Dependency Diagram

graph LR
  091d06a8_6793_746a_7499_d22a1d025196["normalize-scoped-slots.ts"]
  80e29c1b_c807_b450_d82b_2036fd4401e3["is-async-placeholder.ts"]
  091d06a8_6793_746a_7499_d22a1d025196 --> 80e29c1b_c807_b450_d82b_2036fd4401e3
  9e2d427b_d4a2_bb4c_370b_b1726419786d["isAsyncPlaceholder"]
  091d06a8_6793_746a_7499_d22a1d025196 --> 9e2d427b_d4a2_bb4c_370b_b1726419786d
  5164a61d_92b2_9c7f_8acb_b18093afdb59["vnode.ts"]
  091d06a8_6793_746a_7499_d22a1d025196 --> 5164a61d_92b2_9c7f_8acb_b18093afdb59
  bce9f35d_9d67_0066_6c6a_a292b33b6f29["lang"]
  091d06a8_6793_746a_7499_d22a1d025196 --> bce9f35d_9d67_0066_6c6a_a292b33b6f29
  2bf5d0af_391f_8698_e51c_bcaf1f02eb56["normalize-children"]
  091d06a8_6793_746a_7499_d22a1d025196 --> 2bf5d0af_391f_8698_e51c_bcaf1f02eb56
  09aa5370_2caa_6b33_3f44_6ac5211bd11b["util"]
  091d06a8_6793_746a_7499_d22a1d025196 --> 09aa5370_2caa_6b33_3f44_6ac5211bd11b
  64c87498_c46a_6944_ab9d_8e45519852a8["component"]
  091d06a8_6793_746a_7499_d22a1d025196 --> 64c87498_c46a_6944_ab9d_8e45519852a8
  72fd8695_a700_b0bb_c497_9baf5b0b19e0["currentInstance"]
  091d06a8_6793_746a_7499_d22a1d025196 --> 72fd8695_a700_b0bb_c497_9baf5b0b19e0
  2c65c43e_4691_415f_689a_805ec38ae46c["render.ts"]
  2c65c43e_4691_415f_689a_805ec38ae46c --> 091d06a8_6793_746a_7499_d22a1d025196
  414b37af_5f63_dee7_31a2_9a7cad5979ec["create-functional-component.ts"]
  414b37af_5f63_dee7_31a2_9a7cad5979ec --> 091d06a8_6793_746a_7499_d22a1d025196
  style 091d06a8_6793_746a_7499_d22a1d025196 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

import { def } from 'core/util/lang'
import { normalizeChildren } from 'core/vdom/helpers/normalize-children'
import { emptyObject, isArray } from 'shared/util'
import { isAsyncPlaceholder } from './is-async-placeholder'
import type VNode from '../vnode'
import { Component } from 'types/component'
import { currentInstance, setCurrentInstance } from 'v3/currentInstance'

export function normalizeScopedSlots(
  ownerVm: Component,
  scopedSlots: { [key: string]: Function } | undefined,
  normalSlots: { [key: string]: VNode[] },
  prevScopedSlots?: { [key: string]: Function }
): any {
  let res
  const hasNormalSlots = Object.keys(normalSlots).length > 0
  const isStable = scopedSlots ? !!scopedSlots.$stable : !hasNormalSlots
  const key = scopedSlots && scopedSlots.$key
  if (!scopedSlots) {
    res = {}
  } else if (scopedSlots._normalized) {
    // fast path 1: child component re-render only, parent did not change
    return scopedSlots._normalized
  } else if (
    isStable &&
    prevScopedSlots &&
    prevScopedSlots !== emptyObject &&
    key === prevScopedSlots.$key &&
    !hasNormalSlots &&
    !prevScopedSlots.$hasNormal
  ) {
    // fast path 2: stable scoped slots w/ no normal slots to proxy,
    // only need to normalize once
    return prevScopedSlots
  } else {
    res = {}
    for (const key in scopedSlots) {
      if (scopedSlots[key] && key[0] !== '$') {
        res[key] = normalizeScopedSlot(
          ownerVm,
          normalSlots,
          key,
          scopedSlots[key]
        )
      }
    }
  }
  // expose normal slots on scopedSlots
  for (const key in normalSlots) {
    if (!(key in res)) {
      res[key] = proxyNormalSlot(normalSlots, key)
    }
  }
  // avoriaz seems to mock a non-extensible $scopedSlots object
  // and when that is passed down this would cause an error
  if (scopedSlots && Object.isExtensible(scopedSlots)) {
    scopedSlots._normalized = res
  }
  def(res, '$stable', isStable)
  def(res, '$key', key)
  def(res, '$hasNormal', hasNormalSlots)
  return res
}

function normalizeScopedSlot(vm, normalSlots, key, fn) {
  const normalized = function () {
    const cur = currentInstance
    setCurrentInstance(vm)
    let res = arguments.length ? fn.apply(null, arguments) : fn({})
    res =
      res && typeof res === 'object' && !isArray(res)
        ? [res] // single vnode
        : normalizeChildren(res)
    const vnode: VNode | null = res && res[0]
    setCurrentInstance(cur)
    return res &&
      (!vnode ||
        (res.length === 1 && vnode.isComment && !isAsyncPlaceholder(vnode))) // #9658, #10391
      ? undefined
      : res
  }
  // this is a slot using the new v-slot syntax without scope. although it is
  // compiled as a scoped slot, render fn users would expect it to be present
  // on this.$slots because the usage is semantically a normal slot.
  if (fn.proxy) {
    Object.defineProperty(normalSlots, key, {
      get: normalized,
      enumerable: true,
      configurable: true
    })
  }
  return normalized
}

function proxyNormalSlot(slots, key) {
  return () => slots[key]
}

Domain

Subdomains

Dependencies

Frequently Asked Questions

What does normalize-scoped-slots.ts do?
normalize-scoped-slots.ts is a source file in the vue codebase, written in typescript. It belongs to the VueCore domain, GlobalAPI subdomain.
What functions are defined in normalize-scoped-slots.ts?
normalize-scoped-slots.ts defines 3 function(s): normalizeScopedSlot, normalizeScopedSlots, proxyNormalSlot.
What does normalize-scoped-slots.ts depend on?
normalize-scoped-slots.ts imports 8 module(s): component, currentInstance, is-async-placeholder.ts, isAsyncPlaceholder, lang, normalize-children, util, vnode.ts.
What files import normalize-scoped-slots.ts?
normalize-scoped-slots.ts is imported by 2 file(s): create-functional-component.ts, render.ts.
Where is normalize-scoped-slots.ts in the architecture?
normalize-scoped-slots.ts is located at src/core/vdom/helpers/normalize-scoped-slots.ts (domain: VueCore, subdomain: GlobalAPI, directory: src/core/vdom/helpers).

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free