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

  • 相关阅读:
    使用Python操作InfluxDB时序数据库
    LogMysqlApeT
    内建函数 iter()
    Python魔法方法总结及注意事项
    Python魔法方法之属性访问 ( __getattr__, __getattribute__, __setattr__, __delattr__ )
    Python描述符 (descriptor) 详解
    在命令行模式下查看Python帮助文档---dir、help、__doc__
    python高并发的解决方案
    map中的erase成员函数用法
    指针的本质
  • 原文地址:https://www.cnblogs.com/raind/p/12706711.html
Copyright © 2011-2022 走看看