zoukankan      html  css  js  c++  java
  • vue源码探索之过滤器解析过程

    模板编译

    <body>
        <div id="app">
            <span>{{ 1 | test(8) }}</span>
        </div>
    </body>
    <script src="./vue.js"></script>
    <script>
        new Vue({
      el: "#app",
      filters: {
        test (val, b) {
            console.log(this)
            debugger
          return val + b
        }
      }
    });
    

    模板在编译成render函数时候会经过下面一系列流程:
    image

    parseText

    主要在parseText函数解析文本

    function parseText (
        text,
        delimiters
      ) {
        debugger
        var tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE;
        if (!tagRE.test(text)) {
          return
        }
        var tokens = [];
        var rawTokens = [];
        var lastIndex = tagRE.lastIndex = 0;
        var match, index, tokenValue;
        while ((match = tagRE.exec(text))) {
          index = match.index;
          // push text token
          if (index > lastIndex) {
            rawTokens.push(tokenValue = text.slice(lastIndex, index));
            tokens.push(JSON.stringify(tokenValue));
          }
          // tag token
          var exp = parseFilters(match[1].trim());
          tokens.push(("_s(" + exp + ")"));
          rawTokens.push({ '@binding': exp });
          lastIndex = index + match[0].length;
        }
        if (lastIndex < text.length) {
          rawTokens.push(tokenValue = text.slice(lastIndex));
          tokens.push(JSON.stringify(tokenValue));
        }
        return {
          expression: tokens.join('+'), 
          tokens: rawTokens // 解析成 ["_s(_f("test")(1,8))"]
        }
      }
    

    _f函数就是resolveFilter函数

    function resolveFilter (id) {
        debugger
        return resolveAsset(this.$options, 'filters', id, true) || identity
      }
    
    function resolveAsset (
        options,
        type,
        id,
        warnMissing
      ) {
        /* istanbul ignore if */
        if (typeof id !== 'string') {
          return
        }
        var assets = options[type];
        // check local registration variations first
        if (hasOwn(assets, id)) { return assets[id] }
        var camelizedId = camelize(id);
        if (hasOwn(assets, camelizedId)) { return assets[camelizedId] }
        var PascalCaseId = capitalize(camelizedId);
        if (hasOwn(assets, PascalCaseId)) { return assets[PascalCaseId] }
        // fallback to prototype chain
        var res = assets[id] || assets[camelizedId] || assets[PascalCaseId];
        if (warnMissing && !res) {
          warn(
            'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
            options
          );
        }
        return res
      }
    

    resolveAsset就是取出我们在组件中定义在filters里面的test函数,由此可见当我们在定义filter函数中this是不指向当前组件实例的,指向window。如果要想拿到组件实例,可通过调用过滤器的时候,传入this

    最终生成的render函数

    image
    image

  • 相关阅读:
    DQN(Deep Q-learning)入门教程(结束)之总结
    蕴含式(包含EXISTS语句的分析)
    元组关系演算(从集合的角度深入浅出)
    数据流图 和 数据字典
    第3章_关系数据库标准语言(SQL)_006_由元组关系演算到SQL Command_001_蕴含式 (其中有对EXISTS的分析)
    元组关系演算(从集合的角度深入浅出)- 例题(不严谨,无蕴含式)
    问题_001_数据类型转换
    001_C语言中运算符的优先级
    补充_001_问题_001_Vivian
    Netty学习笔记(三)- Reactor模型
  • 原文地址:https://www.cnblogs.com/raind/p/12706711.html
Copyright © 2011-2022 走看看