• vue.js 源代码学习笔记 ----- helpers.js


    /* @flow */
    
    import { parseFilters } from './parser/filter-parser'
    
    export function baseWarn (msg: string) {
      console.error(`[Vue parser]: ${msg}`)
    }
    
    export function pluckModuleFunction (
      modules: ?Array<Object>,
      key: string
    ): Array<Function> {
      return modules
        ? modules.map(m => m[key]).filter(_ => _)
        : []
    }
    
    export function addProp (el: ASTElement, name: string, value: string) {
      (el.props || (el.props = [])).push({ name, value })
    }
    
    export function addAttr (el: ASTElement, name: string, value: string) {
      (el.attrs || (el.attrs = [])).push({ name, value })
    }
    
    export function addDirective (
      el: ASTElement,
      name: string,
      rawName: string,
      value: string,
      arg: ?string,
      modifiers: ?ASTModifiers
    ) {
      (el.directives || (el.directives = [])).push({ name, rawName, value, arg, modifiers })
    }
    
    export function addHandler (
      el: ASTElement,
      name: string,
      value: string,
      modifiers: ?ASTModifiers,
      important: ?boolean
    ) {
      // check capture modifier
      if (modifiers && modifiers.capture) {
        delete modifiers.capture
        name = '!' + name // mark the event as captured
      }
      let events
      if (modifiers && modifiers.native) {
        delete modifiers.native
        events = el.nativeEvents || (el.nativeEvents = {})
      } else {
        events = el.events || (el.events = {})
      }
      const newHandler = { value, modifiers }
      const handlers = events[name]
      /* istanbul ignore if */
      if (Array.isArray(handlers)) {
        important ? handlers.unshift(newHandler) : handlers.push(newHandler)
      } else if (handlers) {
        events[name] = important ? [newHandler, handlers] : [handlers, newHandler]
      } else {
        events[name] = newHandler
      }
    }
    
    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)
        }
      }
    }
    
    export function getAndRemoveAttr (el: ASTElement, name: string): ?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
          }
        }
      }
      return val
    }
    
    let len, str, chr, index, expressionPos, expressionEndPos
    
    /**
     * parse directive model to do the array update transform. a[idx] = val => $$a.splice($$idx, 1, val)
     *
     * for loop possible cases:
     *
     * - test
     * - test[idx]
     * - test[test1[idx]]
     * - test["a"][idx]
     * - xxx.test[a[a].test1[idx]]
     * - test.xxx.a["asa"][test1[idx]]
     *
     */
    
    export function parseModel (val: string): Object {
      str = val
      len = str.length
      index = expressionPos = expressionEndPos = 0
    
      if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) {
        return {
          exp: val,
          idx: null
        }
      }
    
      while (!eof()) {
        chr = next()
        /* istanbul ignore if */
        if (isStringStart(chr)) {
          parseString(chr)
        } else if (chr === 0x5B) {
          parseBracket(chr)
        }
      }
    
      return {
        exp: val.substring(0, expressionPos),
        idx: val.substring(expressionPos + 1, expressionEndPos)
      }
    }
    
    function next (): number {
      return str.charCodeAt(++index)
    }
    
    function eof (): boolean {
      return index >= len
    }
    
    function isStringStart (chr: number): boolean {
      return chr === 0x22 || chr === 0x27
    }
    
    function parseBracket (chr: number): void {
      let inBracket = 1
      expressionPos = index
      while (!eof()) {
        chr = next()
        if (isStringStart(chr)) {
          parseString(chr)
          continue
        }
        if (chr === 0x5B) inBracket++
        if (chr === 0x5D) inBracket--
        if (inBracket === 0) {
          expressionEndPos = index
          break
        }
      }
    }
    
    function parseString (chr: number): void {
      const stringQuote = chr
      while (!eof()) {
        chr = next()
        if (chr === stringQuote) {
          break
        }
      }
    }
  • 相关阅读:
    FileWatcher
    virtual table(有180个评论)
    this 指针
    docker -ce(社区免费版)
    vue-cli
    CAP理论、BASE理论
    B+树和LSM存储引擎代表树和B-树
    CPU高速缓存
    Python&基础环境搭建
    二叉树
  • 原文地址:https://www.cnblogs.com/dhsz/p/7245896.html
Copyright © 2020-2023  润新知