资讯专栏INFORMATION COLUMN

VueJS源码学习——指令解析类

n7then / 1274人阅读

摘要:原文地址项目地址实现了解析器的功能,使用状态机正则表达式等来对表达式文本指令等进行解析在这里引用了,实现了一个双向链表,它会保存最近使用过的对象,在数量超出限制的情况下会抛弃最近没有使用的对象,思想基于,参考自用于解析指令

src/parsers

原文地址
项目地址

parsers 实现了解析器的功能,使用状态机、正则表达式等来对表达式、html、文本、指令等进行解析

src/parsers/directive.js

在这里引用了 cachecache 实现了一个双向链表,它会保存最近使用过的对象,在数量超出限制的情况下会抛弃最近没有使用的对象,思想基于 Least Recently Used, 参考自:https://github.com/rsms/js-lru

directive 用于解析指令:

import { toNumber, stripQuotes } from "../util/index"
import Cache from "../cache"

const cache = new Cache(1000)
const filterTokenRE = /[^s""]+|"[^"]*"|"[^"]*"/g
const reservedArgRE = /^in$|^-?d+/

/**
 * Parser state
 */

var str, dir
var c, i, l, lastFilterIndex
var inSingle, inDouble, curly, square, paren

...

/**
 * Parse a directive value and extract the expression
 * and its filters into a descriptor.
 *
 * Example:
 *
 * "a + 1 | uppercase" will yield:
 * {
 *   expression: "a + 1",
 *   filters: [
 *     { name: "uppercase", args: null }
 *   ]
 * }
 *
 * @param {String} str
 * @return {Object}
 */

export function parseDirective (s) {

  var hit = cache.get(s)
  if (hit) {
    return hit
  }

  // reset parser state
  str = s
  inSingle = inDouble = false
  curly = square = paren = 0
  lastFilterIndex = 0
  dir = {}

  for (i = 0, l = str.length; i < l; i++) {
    c = str.charCodeAt(i)
    if (inSingle) {
      // check single quote
      if (c === 0x27) inSingle = !inSingle
    } else if (inDouble) {
      // check double quote
      if (c === 0x22) inDouble = !inDouble
    } else if (
      c === 0x7C && // pipe
      str.charCodeAt(i + 1) !== 0x7C &&
      str.charCodeAt(i - 1) !== 0x7C
    ) {
      if (dir.expression == null) {
        // first filter, end of expression
        lastFilterIndex = i + 1
        dir.expression = str.slice(0, i).trim()
      } else {
        // already has filter
        pushFilter()
      }
    } else {
      switch (c) {
        case 0x22: inDouble = true; break // "
        case 0x27: inSingle = 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 (dir.expression == null) {
    dir.expression = str.slice(0, i).trim()
  } else if (lastFilterIndex !== 0) {
    pushFilter()
  }

  cache.put(s, dir)
  return dir
}

由于指令可能同时包含表达式和过滤器,如果两者同时存在会以 | 符号分隔开
循环遍历字符找出对应的表达式和过滤器

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88353.html

相关文章

  • VueJS源码学习——项目结构&目录

    摘要:所以整个的核心,就是如何实现这三样东西以上摘自囧克斯博客的一篇文章从版本开始这个时候的项目结构如下源码在里面,为打包编译的代码,为打包后代码放置的位置,为测试代码目录。节点类型摘自资源另一位作者关于源码解析 本项目的源码学习笔记是基于 Vue 1.0.9 版本的也就是最早的 tag 版本,之所以选择这个版本,是因为这个是最原始没有太多功能拓展的版本,有利于更好的看到 Vue 最开始的骨...

    ad6623 评论0 收藏0
  • Vuejs中的那些隐藏属性

    摘要:中的每个对象会一份实际的对象的数据放在外面,改变这些数据并不会反应到实际的对象上,如果我们希望真的改变对象的数据,有一个隐藏属性可以做到就是例子很多情况下你写了一个指令很可能会依赖或者需要解析另外一个指令,比如,然而中的指令并没有这方面的 __vue__ $els中的每个对象会copy一份实际的Vue对象(vm)的数据放在外面,改变这些数据并不会反应到实际的Vue对象上,如果我们希望真...

    antz 评论0 收藏0
  • VueJS源码学习——订阅观察者

    摘要:实现了一个简单的订阅观察者类,这个类被用于在数据修改时通知各个以触发对应的更新,从而实现数据的响应,这个会在后续的数据响应化里提到。 observer 实现了一个简单的订阅观察者类,这个类被用于在数据修改时通知各个 watcher 以触发对应的更新,从而实现数据的响应,这个会在后续的数据响应化里提到。 原文地址项目地址 src/observer src/observer/dep.js ...

    Godtoy 评论0 收藏0
  • Vue 1.0.28 源码解析

    摘要:整体概览源码最终是向外部抛出一个的构造函数,见源码在源码最开始,通过方法见源码向构造函数添加全局方法,如等,主要初始化一些全局使用的方法变量和配置实例化当使用时,最基本使用方式如下此时,会调用构造函数实例化一个对象,而在构造函数中只有这句代 整体概览 Vue源码最终是向外部抛出一个Vue的构造函数,见源码: function Vue (options) { this._init(o...

    URLOS 评论0 收藏0
  • 学习Vue.js-Day1

    摘要:学习内容,基本语法和概念,打包工具,实战操作参考文献官网官方资料库全家桶全家桶文档概念前端框架借助可以实现手机开发前端框架是一套构造用户界面的框架,只关于视图层前端的主要工作室跟用户界面打交道,中的,实现界面效果框架是为了提高开发 学习内容 1,Vue基本语法和概念 2, 打包工具 Webpack , Gulp3,实战操作 参考文献:官网: https://cn.vuejs.org...

    Cheriselalala 评论0 收藏0

发表评论

0条评论

n7then

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<