国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

vue學習筆記(慎入,內容僅供學習時查詢某些函數具體起到什么作用)

tuniutech / 3459人閱讀

getAndRemoveAttr

從ast模板對象中取出相應的屬性。

檢測屬性是否存在,通過對象attrsMap來檢測,提升效率

如果存在,則從attrsList中中移除

如果第三個傳參為true,刪除attrsMap中對應的屬性

返回取到的結果,或者undefined

// note: this only removes the attr from the Array (attrsList) so that it
// doesn"t get processed by processAttrs.
// By default it does NOT remove it from the map (attrsMap) because the map is
// needed during codegen.
export function getAndRemoveAttr (
  el: ASTElement,
  name: string,
  removeFromMap?: boolean
): ?string {
  let val
  if ((val = el.attrsMap[name]) != null) {
    const list = el.attrsList
    for (let i = 0, l = list.length; i < l; i++) {
      if (list[i].name === name) {
        list.splice(i, 1)
        break
      }
    }
  }
  if (removeFromMap) {
    delete el.attrsMap[name]
  }
  return val
} 
getBindingAttr

獲取動態屬性值

拼接屬性名:|v-bind,調用getAndRemoveAttr讀取相應的屬性值

如果獲取到相應的屬性值,則調用parseFilters解析返回值中可能存在的過濾器,并返回

如果第三個傳參不為false,返回相應的靜態屬性,并將靜態屬性格式化為字符串""demo1"",返回

否則,無返回

/** 第三個參數傳true會在獲取不到動態屬性的時候取靜態屬性 */
export function getBindingAttr (
  el: ASTElement,
  name: string,
  getStatic?: boolean
): ?string {
  const dynamicValue =
    getAndRemoveAttr(el, ":" + name) ||
    getAndRemoveAttr(el, "v-bind:" + name)
  if (dynamicValue != null) {
    // 如果存在過濾器,將匹配到的字符串使用過濾器包裹。
    return parseFilters(dynamicValue)
  } else if (getStatic !== false) {
    const staticValue = getAndRemoveAttr(el, name)
    if (staticValue != null) {
      return JSON.stringify(staticValue)
    }
  }
} 
parseFilters

{{input | filter1 | filter2 }} 解析為:_f("filter2")(_f("filter1")(input))

/* @flow */

/** 匹配任意非空字符,),.,+,-,_,$,] 
* 排除一些其他用法產生的/,諸如a++ / b, a-- / b, a/b, (a + a1) / b, ../path
*/
const validDivisionCharRE = /[w).+-_$]]/

/** 解析出filter的條件是:匹配到|,
 * 并且|不在單引號,雙引號,模板引用符,正則,括號,中括號,大括號中,
 * 并且不是||
 */
export function parseFilters (exp: string): string {
  let inSingle = false
  let inDouble = false
  let inTemplateString = false
  let inRegex = false
  let curly = 0
  let square = 0
  let paren = 0
  let lastFilterIndex = 0
  let c, prev, i, expression, filters

  for (i = 0; i < exp.length; i++) {
    prev = c
    c = exp.charCodeAt(i)
    // 0x5C => 
    if (inSingle) {
      if (c === 0x27 && prev !== 0x5C) inSingle = false
    } else if (inDouble) {
      if (c === 0x22 && prev !== 0x5C) inDouble = false
    } else if (inTemplateString) {
      if (c === 0x60 && prev !== 0x5C) inTemplateString = false
    } else if (inRegex) {
      if (c === 0x2f && prev !== 0x5C) inRegex = false
    } else if (
      c === 0x7C && // |
      exp.charCodeAt(i + 1) !== 0x7C &&
      exp.charCodeAt(i - 1) !== 0x7C &&
      !curly && !square && !paren
    ) {
      if (expression === undefined) {
        // first filter, end of expression
        lastFilterIndex = i + 1
        expression = exp.slice(0, i).trim()
      } else {
        pushFilter()
      }
    } else {
      switch (c) {
        case 0x22: inDouble = true; break         // "
        case 0x27: inSingle = true; break         // "
        case 0x60: inTemplateString = true; break // `
        case 0x28: paren++; break                 // (
        case 0x29: paren--; break                 // )
        case 0x5B: square++; break                // [
        case 0x5D: square--; break                // ]
        case 0x7B: curly++; break                 // {
        case 0x7D: curly--; break                 // }
      }
      if (c === 0x2f) { // /
        let j = i - 1
        let p
        // find first non-whitespace prev char
        for (; j >= 0; j--) {
          p = exp.charAt(j)
          if (p !== " ") break
        }
        if (!p || !validDivisionCharRE.test(p)) {
          inRegex = true
        }
      }
    }
  }

  if (expression === undefined) {
    expression = exp.slice(0, i).trim()
  } else if (lastFilterIndex !== 0) {
    pushFilter()
  }

  function pushFilter () {
    (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim())
    lastFilterIndex = i + 1
  }

  if (filters) {
    for (i = 0; i < filters.length; i++) {
      expression = wrapFilter(expression, filters[i])
    }
  }
  return expression
}

function wrapFilter (exp: string, filter: string): string {
  const i = filter.indexOf("(")
  if (i < 0) {
    // _f: resolveFilter
    return `_f("${filter}")(${exp})`
  } else {
    const name = filter.slice(0, i)
    const args = filter.slice(i + 1)
    return `_f("${name}")(${exp}${args !== ")" ? "," + args : args}`
  }
}
 
preTransformNode
/* @flow */

/**
 * Expand input[v-model] with dyanmic type bindings into v-if-else chains
 * Turn this:
 *   
 * into this:
 *   
 *   
 *   
 */

import {
  addRawAttr,
  getBindingAttr,
  getAndRemoveAttr
} from "compiler/helpers"

import {
  processFor,
  processElement,
  addIfCondition,
  createASTElement
} from "compiler/parser/index"

/** 處理input標簽的v-model */
function preTransformNode (el: ASTElement, options: CompilerOptions) {
  if (el.tag === "input") {
    const map = el.attrsMap
    if (!map["v-model"]) {
      return
    }

    let typeBinding
    if (map[":type"] || map["v-bind:type"]) {
      typeBinding = getBindingAttr(el, "type")
    }
    if (!map.type && !typeBinding && map["v-bind"]) {
      typeBinding = `(${map["v-bind"]}).type`
    }

    if (typeBinding) {
      const ifCondition = getAndRemoveAttr(el, "v-if", true)
      const ifConditionExtra = ifCondition ? `&&(${ifCondition})` : ``
      const hasElse = getAndRemoveAttr(el, "v-else", true) != null
      const elseIfCondition = getAndRemoveAttr(el, "v-else-if", true)
      // 1. checkbox
      const branch0 = cloneASTElement(el)
      // process for on the main node,如果有v-for,將v-for解析為for,alias等屬性,并添加到branch0上
      processFor(branch0)
      // ast直接添加type屬性
      addRawAttr(branch0, "type", "checkbox")
      processElement(branch0, options)
      branch0.processed = true // prevent it from double-processed
      branch0.if = `(${typeBinding})==="checkbox"` + ifConditionExtra
      addIfCondition(branch0, {
        exp: branch0.if,
        block: branch0
      })
      // 2. add radio else-if condition
      const branch1 = cloneASTElement(el)
      getAndRemoveAttr(branch1, "v-for", true)
      addRawAttr(branch1, "type", "radio")
      processElement(branch1, options)
      addIfCondition(branch0, {
        exp: `(${typeBinding})==="radio"` + ifConditionExtra,
        block: branch1
      })
      // 3. other
      const branch2 = cloneASTElement(el)
      getAndRemoveAttr(branch2, "v-for", true)
      addRawAttr(branch2, ":type", typeBinding)
      processElement(branch2, options)
      addIfCondition(branch0, {
        exp: ifCondition,
        block: branch2
      })

      if (hasElse) {
        branch0.else = true
      } else if (elseIfCondition) {
        branch0.elseif = elseIfCondition
      }
      return branch0
    }
  }
}

function cloneASTElement (el) {
  return createASTElement(el.tag, el.attrsList.slice(), el.parent)
}

export default {
  preTransformNode
}
processFor

extend(el, res),el.for, el.alias, el.iterator1, el.iterator2

export function processFor (el: ASTElement) {
  let exp
  if ((exp = getAndRemoveAttr(el, "v-for"))) {
    const res = parseFor(exp)
    if (res) {
      extend(el, res)
    } else if (process.env.NODE_ENV !== "production") {
      warn(
        `Invalid v-for expression: ${exp}`
      )
    }
  }
} 
parseFor

這個函數解析v-for字符串,并返回,比如
item in items返回{ for: items, alias: item };
(item, index) in items返回{ for: items, alias: item, iterator1: index };
(item, key, index) in items返回{ for: items, alias: item, iterator1: key, iterator2: index };

/**
 * item in items *?最小貪婪匹配,如 a in b in c 則匹配
 * a 而不是 a in b, in item 則匹配 ""
 */
export const forAliasRE = /([^]*?)s+(?:in|of)s+([^]*)/ 
/**
 * 匹配多個參數。
 */
export const forIteratorRE = /,([^,}]]*)(?:,([^,}]]*))?$/
const stripParensRE = /^(|)$/g

/** 解析v-for表達式,并返回 */
export function parseFor (exp: string): ?ForParseResult {
  const inMatch = exp.match(forAliasRE)
  if (!inMatch) return
  const res = {}
  res.for = inMatch[2].trim()
  const alias = inMatch[1].trim().replace(stripParensRE, "")
  const iteratorMatch = alias.match(forIteratorRE)
  if (iteratorMatch) {
    res.alias = alias.replace(forIteratorRE, "")
    res.iterator1 = iteratorMatch[1].trim()
    if (iteratorMatch[2]) {
      res.iterator2 = iteratorMatch[2].trim()
    }
  } else {
    res.alias = alias
  }
  return res
} 
processElement
export function processElement (element: ASTElement, options: CompilerOptions) {
  processKey(element)

  // determine whether this is a plain element after
  // removing structural attributes
  element.plain = !element.key && !element.attrsList.length

  processRef(element)
  processSlot(element)
  processComponent(element)
  /**
   * 賦值 el.staticClass, classBinding, staticStyle, styleBinding
   */
  for (let i = 0; i < transforms.length; i++) {
    element = transforms[i](element, options) || element
  }
  /** 處理attrsList 剩余屬性 */
  processAttrs(element)
} 
processSlot

如果el.tag === slot,獲取el的name并賦值給slotname屬性

不是,獲取slot-scope,并給元素賦值slotScope屬性

獲取元素的動態slot,如果不是template且slotScope屬性不存在,則給el的attrs數組屬性增加{name: "slot", value: slotTarget}

function processSlot (el) {
  if (el.tag === "slot") {
    el.slotName = getBindingAttr(el, "name")
    if (process.env.NODE_ENV !== "production" && el.key) {
      warn(
        ``key` does not work on  because slots are abstract outlets ` +
        `and can possibly expand into multiple elements. ` +
        `Use the key on a wrapping element instead.`
      )
    }
  } else {
    let slotScope
    if (el.tag === "template") {
      slotScope = getAndRemoveAttr(el, "scope")
      /* istanbul ignore if */
      if (process.env.NODE_ENV !== "production" && slotScope) {
        warn(
          `the "scope" attribute for scoped slots have been deprecated and ` +
          `replaced by "slot-scope" since 2.5. The new "slot-scope" attribute ` +
          `can also be used on plain elements in addition to